Skip to content

Commit

Permalink
Merge pull request mozilla-b2g#19857 from EverythingMe/1016245-collec…
Browse files Browse the repository at this point in the history
…tion-locales

Bug 1016245 - [Collections App] Localized names in Collection suggestions list
  • Loading branch information
amirnissim committed Jun 8, 2014
2 parents 4099f6d + bebcd3f commit 33e464d
Show file tree
Hide file tree
Showing 10 changed files with 319 additions and 152 deletions.
157 changes: 83 additions & 74 deletions apps/collection/js/create_collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,86 +30,95 @@
activity.postResult(false);
});

request = eme.api.Categories.list().then(
function success(response) {
loading.style.display = 'none';

var data = response.response;
var suggest = Suggestions.load(data.categories, data.locale);
suggest.then(
function select(selected) {
eme.log('resolved with', selected);
var dataReady;

if (Array.isArray(selected)) {
// collections from categories
// we have the web app icons in the response
var collections = CategoryCollection.fromResponse(selected, data);
dataReady = Promise.resolve(collections);
} else {
// collection from custom query
// we make another request to get web app icons
dataReady = new Promise(function getIcons(resolve) {
eme.api.Apps.search({query: selected, limit: numAppIcons})
.then(function success(response) {
var webicons =
response.response.apps.slice(0,numAppIcons).map(
function each(app) {
return app.icon;
});

var collection = new QueryCollection({
query: selected,
webicons: webicons
});

resolve([collection]);
}, noIcons)
.catch(noIcons);

function noIcons(e) {
eme.log('noIcons', e);
resolve([new QueryCollection({query: selected})]);
}
});
}
// filter installed categories
CollectionsDatabase.getAllCategories().then(function doRequest(installed) {
// TODO send existingExperienceIds instead of filtering on client side
// (when supported in Partners API)
request = eme.api.Categories.list().then(
function success(response) {
loading.style.display = 'none';

var data = response.response;
var categories = data.categories.filter(function filter(category) {
return installed.indexOf(category.categoryId) === -1;
});

dataReady.then(function success(collections) {
var iconsReady = [];
collections.forEach(function doIcon(collection) {
iconsReady.push(collection.renderIcon());
Suggestions.load(categories).then(
function select(selected) {
eme.log('resolved with', selected);
var dataReady;

if (Array.isArray(selected)) {
// collections from categories
// we have the web app icons in the response
dataReady = Promise.resolve(
CategoryCollection.fromResponse(selected, data));
} else {
// collection from custom query
// we make another request to get web app icons
dataReady = new Promise(function getIcons(resolve) {
eme.api.Apps.search({query: selected, limit: numAppIcons})
.then(function success(response) {
var webicons =
response.response.apps.slice(0,numAppIcons).map(
function each(app) {
return app.icon;
});

var collection = new QueryCollection({
query: selected,
webicons: webicons
});

resolve([collection]);
}, noIcons)
.catch(noIcons);

function noIcons(e) {
eme.log('noIcons', e);
resolve([new QueryCollection({query: selected})]);
}
});
}

dataReady.then(function success(collections) {
var iconsReady = [];
collections.forEach(function doIcon(collection) {
iconsReady.push(collection.renderIcon());
});

Promise.all(iconsReady).then(function then() {
// TODO
// 1. store a batch of collections at once. possible?
// 2. we can store to db *before* icons is ready and once
// the homescreen syncs it will update the icons
var trxs = collections.map(CollectionsDatabase.add);
Promise.all(trxs).then(done, done);
}).catch(function _catch(ex) {
eme.log('caught exception', ex);
activity.postResult(false);
});
});

Promise.all(iconsReady).then(function then() {
// TODO
// 1. store a batch of collections at once. possible?
// 2. we can store to db *before* icons is ready and once
// the homescreen syncs it will update the icons
var trxs = collections.map(CollectionsDatabase.add);
Promise.all(trxs).then(done, done);
}).catch(function _catch(ex) {
eme.log('caught exception', ex);
activity.postResult(false);
});
function done() {
activity.postResult(true);
}
},
function cancel(reason) {
eme.log('rejected with', reason);
activity.postResult(false);
});

function done() {
activity.postResult(true);
}
},
function cancel(reason) {
eme.log('rejected with', reason);
activity.postResult(false);
});
}, function error(reason) {
eme.log('create-collection: error', reason);
activity.postError(_(reason === 'network error' ?
'network-error-message' : undefined));
}).catch(function fail(ex) {
eme.log('create-collection: failed', ex);
activity.postError();
});

}, function error(reason) {
eme.log('create-collection: error', reason);
activity.postError(_(reason === 'network error' ?
'network-error-message' : undefined));
}).catch(function fail(ex) {
eme.log('create-collection: failed', ex);
activity.postError();
});
}, activity.postError);
}

navigator.mozSetMessageHandler('activity', function onActivity(activity) {
Expand Down
86 changes: 50 additions & 36 deletions apps/collection/js/suggestions.js
Original file line number Diff line number Diff line change
@@ -1,69 +1,79 @@
'use strict';
/* global CollectionsDatabase */
/* global Promise */
/* global eme */

(function(exports) {

var _ = navigator.mozL10n.get;
var _map = Array.prototype.map;

var WORLDWIDE_LOCALE = 'en_WW';
const l10nKey = 'categoryId-';

// TODO
// translate collections names when device language changes (requires server
// side changes)
//
var _ = navigator.mozL10n.get;
var map = Array.prototype.map;

function Suggestions(categories) {
function Suggestions() {
this.el = document.getElementById('collections-select');
this.el.addEventListener('blur', this);
this.el.addEventListener('change', this);
this.hide();

this.load = function suggestions_load(categories, locale) {
var self = this;

this.load = function suggestions_load(categories) {
this.clear();

var deviceLocale = this.toLocaleCode(navigator.mozL10n.language.code);

return new Promise(function done(resolve, reject) {
this.resolve = resolve;
this.reject = reject;

var doTranslate = locale !== WORLDWIDE_LOCALE;
var frag = document.createDocumentFragment();
var custom = document.createElement('option');
custom.value = 'custom';

custom.textContent = _('custom');
frag.appendChild(custom);

if (doTranslate) {
// TODO
// see bug 968998
// translate and sort categories
}
// localization. use:
// 1. name provided by Mozilla l10n team
// 2. else - if suggestion has correct locale, use it
// 3. else - ignore the suggestion (do not show in list)
var localeCategories = [];

categories.forEach(function each(category) {
var id = category.categoryId;

var localeName = _(l10nKey + id);
if (!localeName) {
var categoryLocale = this.toLocaleCode(category.locale);
if (categoryLocale === deviceLocale) {
localeName = category.query;
} else {
eme.warn(
'suggestion ignored (wrong locale ' + categoryLocale + ')',
id, category.query);
}
}

// filter installed categories
CollectionsDatabase.getAllCategories()
.then(function filter(installed) {
categories.forEach(function each(category) {
if (installed.indexOf(category.categoryId) > -1) {
return;
}
if (localeName) {
localeCategories.push({id: id, name: localeName});
}

var el = document.createElement('option');
}, this);

el.value = el.textContent = category.query;
el.dataset.query = category.query;
el.dataset.categoryId = category.categoryId;
// sort suggestions by localized names
localeCategories.sort(function sort(a,b) {
return a.name > b.name;
});

frag.appendChild(el);
});
localeCategories.forEach(function each(category) {
var el = document.createElement('option');

self.el.appendChild(frag);
self.show();
el.value = el.textContent = category.name;
el.dataset.categoryId = category.id;

}, reject);
frag.appendChild(el);
});

this.el.appendChild(frag);
this.show();
}.bind(this));
};
}
Expand All @@ -78,7 +88,7 @@
this.hide();

if (!customSelected) {
var selected = _map.call(this.el.querySelectorAll('option:checked'),
var selected = map.call(this.el.querySelectorAll('option:checked'),
function getId(opt) {
return Number(opt.dataset.categoryId);
});
Expand Down Expand Up @@ -114,8 +124,12 @@
},
hide: function suggestions_hide() {
this.el.blur();
},
toLocaleCode: function toLocaleCode(s) {
return s ? s.substr(0, 2) : undefined;
}
};

exports.Suggestions = new Suggestions();

})(window);
78 changes: 78 additions & 0 deletions apps/collection/locales/categories.example.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# THIS IS AN EXAMPLE CONTAINING THE COMPLETE LIST OF SMART COLLECTIONS
# LOCALIZATION KEYS.
#
# Create a .properties file for your locale and include
# ONLY THE KEYS FOR THE CATEGORIES TO CUSTOMIZE.
#
categoryId-22=Books
categoryId-142=Music
categoryId-181=Movies
categoryId-194=Internet
categoryId-207=Games
categoryId-211=Video
categoryId-213=TV
categoryId-220=Restaurants
categoryId-225=Celebs
categoryId-238=Shopping
categoryId-242=Images
categoryId-244=Tech
categoryId-245=News
categoryId-248=Email
categoryId-249=Weather
categoryId-256=Culture
categoryId-260=Sports
categoryId-270=Recipes
categoryId-271=Reference
categoryId-272=Travel Guides
categoryId-274=Jobs
categoryId-275=Medical
categoryId-277=Funny
categoryId-279=Learning & Education
categoryId-282=Fashion
categoryId-286=Electronics
categoryId-288=Autos
categoryId-289=Social
categoryId-291=Video Games
categoryId-292=Daily Deals
categoryId-294=Personal Communication
categoryId-296=Around Me
categoryId-297=Astrology
categoryId-302=Kids
categoryId-303=Financial Services
categoryId-306=Travel
categoryId-316=Hotels
categoryId-320=Dating
categoryId-321=Financial News
categoryId-325=Baseball
categoryId-338=Classifieds
categoryId-347=Baby
categoryId-349=Photography
categoryId-356=Beauty
categoryId-357=Utilities
categoryId-360=Productivity
categoryId-365=Comics
categoryId-366=Lifestyle
categoryId-368=Personalization
categoryId-372=Transportation
categoryId-373=Telecommunication
categoryId-376=Entertainment
categoryId-377=Soccer
categoryId-381=Religion
categoryId-382=Fitness
categoryId-387=Outdoor Activities
categoryId-399=DIY
categoryId-449=I'm So Bored
categoryId-462=Telenovelas
categoryId-463=Politics
categoryId-473=Cricket
categoryId-491=World Cup
categoryId-501=Brazilian Apps
categoryId-504=Bollywood
categoryId-505=Food & Drinks
categoryId-507=Travel & Local
categoryId-510=Tech & Science
categoryId-511=Media & Video
categoryId-512=Health & Fitness
categoryId-513=Business
categoryId-520=Cycling
categoryId-521=Surf
3 changes: 3 additions & 0 deletions apps/collection/locales/categories.fr.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
categoryId-245=custom.fr
categoryId-207=custom.fr
categoryId-296=custom.fr
7 changes: 0 additions & 7 deletions apps/collection/locales/collection.fr.properties

This file was deleted.

Loading

0 comments on commit 33e464d

Please sign in to comment.