diff --git a/src/main/java/com/commafeed/backend/model/UserSettings.java b/src/main/java/com/commafeed/backend/model/UserSettings.java index 084ac7cc..1faf4358 100644 --- a/src/main/java/com/commafeed/backend/model/UserSettings.java +++ b/src/main/java/com/commafeed/backend/model/UserSettings.java @@ -42,6 +42,9 @@ public class UserSettings extends AbstractModel { @Column(nullable = false) private ViewMode viewMode; + @Column(length = 4) + private String language; + private boolean showRead; private boolean scrollMarks; private boolean socialButtons; @@ -113,4 +116,13 @@ public class UserSettings extends AbstractModel { public void setScrollMarks(boolean scrollMarks) { this.scrollMarks = scrollMarks; } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + } diff --git a/src/main/java/com/commafeed/frontend/model/Settings.java b/src/main/java/com/commafeed/frontend/model/Settings.java index f5b5b316..9d009ce5 100644 --- a/src/main/java/com/commafeed/frontend/model/Settings.java +++ b/src/main/java/com/commafeed/frontend/model/Settings.java @@ -15,6 +15,9 @@ import com.wordnik.swagger.annotations.ApiProperty; @ApiClass("User settings") public class Settings implements Serializable { + @ApiProperty(value = "user's preferred language, english if none") + private String language; + @ApiProperty(value = "user reads all entries or unread entries only", allowableValues = "all,unread", required = true) private String readingMode; @@ -92,4 +95,12 @@ public class Settings implements Serializable { this.scrollMarks = scrollMarks; } + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + } diff --git a/src/main/java/com/commafeed/frontend/pages/BasePage.html b/src/main/java/com/commafeed/frontend/pages/BasePage.html index 4a6aa1a9..2ce83f54 100644 --- a/src/main/java/com/commafeed/frontend/pages/BasePage.html +++ b/src/main/java/com/commafeed/frontend/pages/BasePage.html @@ -1,5 +1,5 @@ - + CommaFeed diff --git a/src/main/java/com/commafeed/frontend/pages/BasePage.java b/src/main/java/com/commafeed/frontend/pages/BasePage.java index 33475de7..2588117e 100644 --- a/src/main/java/com/commafeed/frontend/pages/BasePage.java +++ b/src/main/java/com/commafeed/frontend/pages/BasePage.java @@ -5,11 +5,13 @@ import java.util.Map; import javax.inject.Inject; import org.apache.commons.lang.StringUtils; +import org.apache.wicket.AttributeModifier; import org.apache.wicket.RuntimeConfigurationType; import org.apache.wicket.markup.head.CssHeaderItem; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptHeaderItem; import org.apache.wicket.markup.head.filter.HeaderResponseContainer; +import org.apache.wicket.markup.html.TransparentWebMarkupContainer; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.WebPage; @@ -23,7 +25,10 @@ import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.dao.UserRoleDAO; import com.commafeed.backend.dao.UserSettingsDAO; import com.commafeed.backend.model.ApplicationSettings; +import com.commafeed.backend.model.User; +import com.commafeed.backend.model.UserSettings; import com.commafeed.backend.services.ApplicationSettingsService; +import com.commafeed.frontend.CommaFeedSession; import com.commafeed.frontend.utils.WicketUtils; import com.google.api.client.util.Maps; @@ -63,6 +68,18 @@ public abstract class BasePage extends WebPage { private ApplicationSettings settings; public BasePage() { + + String lang = "en"; + User user = CommaFeedSession.get().getUser(); + if (user != null) { + UserSettings settings = userSettingsDAO.findByUser(user); + lang = settings.getLanguage() == null ? "en" : settings + .getLanguage(); + } + + add(new TransparentWebMarkupContainer("html").add(new AttributeModifier("lang", + lang))); + settings = applicationSettingsService.get(); add(new HeaderResponseContainer("footer-container", "footer-container")); add(new WebMarkupContainer("uservoice") { diff --git a/src/main/java/com/commafeed/frontend/rest/resources/UserREST.java b/src/main/java/com/commafeed/frontend/rest/resources/UserREST.java index 8fe51e18..2a18268a 100644 --- a/src/main/java/com/commafeed/frontend/rest/resources/UserREST.java +++ b/src/main/java/com/commafeed/frontend/rest/resources/UserREST.java @@ -45,6 +45,7 @@ public class UserREST extends AbstractResourceREST { s.setSocialButtons(settings.isSocialButtons()); s.setScrollMarks(settings.isScrollMarks()); s.setCustomCss(settings.getCustomCss()); + s.setLanguage(settings.getLanguage()); } else { s.setReadingMode(ReadingMode.unread.name()); s.setReadingOrder(ReadingOrder.desc.name()); @@ -52,6 +53,7 @@ public class UserREST extends AbstractResourceREST { s.setShowRead(true); s.setSocialButtons(true); s.setScrollMarks(true); + s.setLanguage("en"); } return s; } @@ -74,6 +76,7 @@ public class UserREST extends AbstractResourceREST { s.setScrollMarks(settings.isScrollMarks()); s.setCustomCss(settings.getCustomCss()); s.setSocialButtons(settings.isSocialButtons()); + s.setLanguage(settings.getLanguage()); userSettingsDAO.saveOrUpdate(s); return Response.ok(Status.OK).build(); diff --git a/src/main/java/com/commafeed/frontend/utils/InternationalizationDevelopmentFilter.java b/src/main/java/com/commafeed/frontend/utils/InternationalizationDevelopmentFilter.java index 1ebb4794..a4d5f2ab 100644 --- a/src/main/java/com/commafeed/frontend/utils/InternationalizationDevelopmentFilter.java +++ b/src/main/java/com/commafeed/frontend/utils/InternationalizationDevelopmentFilter.java @@ -3,12 +3,12 @@ package com.commafeed.frontend.utils; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.util.Locale; import java.util.Properties; import java.util.ResourceBundle; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.inject.Inject; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -23,6 +23,8 @@ import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.commafeed.backend.dao.UserSettingsDAO; +import com.commafeed.backend.model.UserSettings; import com.commafeed.frontend.CommaFeedSession; /** @@ -35,6 +37,9 @@ public class InternationalizationDevelopmentFilter implements Filter { private static Logger log = LoggerFactory .getLogger(InternationalizationDevelopmentFilter.class); + @Inject + UserSettingsDAO userSettingsDAO; + private boolean production = true; @Override @@ -56,28 +61,25 @@ public class InternationalizationDevelopmentFilter implements Filter { } }; chain.doFilter(request, interceptor); - Locale locale = CommaFeedSession.get().getLocale(); - byte[] bytes = translate(wrapper.toString(), locale).getBytes(); + UserSettings settings = userSettingsDAO.findByUser(CommaFeedSession + .get().getUser()); + String lang = settings.getLanguage() == null ? "en" : settings + .getLanguage(); + + byte[] bytes = translate(wrapper.toString(), lang).getBytes(); response.getOutputStream().write(bytes); response.setContentLength(bytes.length); response.getOutputStream().close(); } - private String translate(String content, Locale locale) { + private String translate(String content, String lang) { Properties props = new Properties(); InputStream is = null; try { - is = getClass().getResourceAsStream( - "/i18n/" + locale.getLanguage() + ".properties"); - if (is == null) { - is = getClass().getResourceAsStream("/i18n/en.properties"); - } - if (is == null) { - throw new Exception("Locale file not found for locale " - + locale.getLanguage()); - } + is = getClass() + .getResourceAsStream("/i18n/" + lang + ".properties"); props.load(is); } catch (Exception e) { log.error(e.getMessage(), e); diff --git a/src/main/script/template-loader.js b/src/main/script/template-loader.js index 3ded2693..01b78d76 100644 --- a/src/main/script/template-loader.js +++ b/src/main/script/template-loader.js @@ -13,7 +13,8 @@ app.factory('$templateCache', ['$cacheFactory', '$http', '$injector', function($ } if (!allTplPromise) { - allTplPromise = $http.get('templates/all-templates.html?${timestamp}').then( + var lang = $('html').attr('lang'); + allTplPromise = $http.get('templates/all-templates.' + lang + '.html?${timestamp}').then( function(response) { $injector.get('$compile')(response.data); return response; diff --git a/src/main/webapp/js/controllers.js b/src/main/webapp/js/controllers.js index b170a106..58b030eb 100644 --- a/src/main/webapp/js/controllers.js +++ b/src/main/webapp/js/controllers.js @@ -798,6 +798,15 @@ function($scope, $location, SettingsService, AnalyticsService) { AnalyticsService.track(); + + $scope.languages = [ { + id : 'en', + label : 'English' + }, { + id : 'fr', + label : 'Français' + } ]; + $scope.settingsService = SettingsService; $scope.$watch('settingsService.settings', function(value) { $scope.settings = angular.copy(value); @@ -811,7 +820,7 @@ function($scope, $location, SettingsService, AnalyticsService) { $scope.save = function() { SettingsService.settings = $scope.settings; SettingsService.save(function() { - $location.path('/'); + window.location.href = window.location.href.substring(0, window.location.href.lastIndexOf('#')); }); }; }]); diff --git a/src/main/webapp/templates/settings.html b/src/main/webapp/templates/settings.html index 8f85ac1b..c62d5193 100644 --- a/src/main/webapp/templates/settings.html +++ b/src/main/webapp/templates/settings.html @@ -19,6 +19,14 @@
+
+ +
+ +
+