store and use preferred language from user (#55)

This commit is contained in:
Athou
2013-05-11 22:49:33 +02:00
parent dab151ce37
commit ca47270db1
9 changed files with 79 additions and 16 deletions

View File

@@ -42,6 +42,9 @@ public class UserSettings extends AbstractModel {
@Column(nullable = false) @Column(nullable = false)
private ViewMode viewMode; private ViewMode viewMode;
@Column(length = 4)
private String language;
private boolean showRead; private boolean showRead;
private boolean scrollMarks; private boolean scrollMarks;
private boolean socialButtons; private boolean socialButtons;
@@ -113,4 +116,13 @@ public class UserSettings extends AbstractModel {
public void setScrollMarks(boolean scrollMarks) { public void setScrollMarks(boolean scrollMarks) {
this.scrollMarks = scrollMarks; this.scrollMarks = scrollMarks;
} }
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
} }

View File

@@ -15,6 +15,9 @@ import com.wordnik.swagger.annotations.ApiProperty;
@ApiClass("User settings") @ApiClass("User settings")
public class Settings implements Serializable { 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) @ApiProperty(value = "user reads all entries or unread entries only", allowableValues = "all,unread", required = true)
private String readingMode; private String readingMode;
@@ -92,4 +95,12 @@ public class Settings implements Serializable {
this.scrollMarks = scrollMarks; this.scrollMarks = scrollMarks;
} }
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
} }

View File

@@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org"> <html xmlns:wicket="http://wicket.apache.org" wicket:id="html">
<head> <head>
<title>CommaFeed</title> <title>CommaFeed</title>
<meta charset="utf-8"> <meta charset="utf-8">

View File

@@ -5,11 +5,13 @@ import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.RuntimeConfigurationType; import org.apache.wicket.RuntimeConfigurationType;
import org.apache.wicket.markup.head.CssHeaderItem; import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem; import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import org.apache.wicket.markup.head.filter.HeaderResponseContainer; 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.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage; 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.UserRoleDAO;
import com.commafeed.backend.dao.UserSettingsDAO; import com.commafeed.backend.dao.UserSettingsDAO;
import com.commafeed.backend.model.ApplicationSettings; 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.backend.services.ApplicationSettingsService;
import com.commafeed.frontend.CommaFeedSession;
import com.commafeed.frontend.utils.WicketUtils; import com.commafeed.frontend.utils.WicketUtils;
import com.google.api.client.util.Maps; import com.google.api.client.util.Maps;
@@ -63,6 +68,18 @@ public abstract class BasePage extends WebPage {
private ApplicationSettings settings; private ApplicationSettings settings;
public BasePage() { 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(); settings = applicationSettingsService.get();
add(new HeaderResponseContainer("footer-container", "footer-container")); add(new HeaderResponseContainer("footer-container", "footer-container"));
add(new WebMarkupContainer("uservoice") { add(new WebMarkupContainer("uservoice") {

View File

@@ -45,6 +45,7 @@ public class UserREST extends AbstractResourceREST {
s.setSocialButtons(settings.isSocialButtons()); s.setSocialButtons(settings.isSocialButtons());
s.setScrollMarks(settings.isScrollMarks()); s.setScrollMarks(settings.isScrollMarks());
s.setCustomCss(settings.getCustomCss()); s.setCustomCss(settings.getCustomCss());
s.setLanguage(settings.getLanguage());
} else { } else {
s.setReadingMode(ReadingMode.unread.name()); s.setReadingMode(ReadingMode.unread.name());
s.setReadingOrder(ReadingOrder.desc.name()); s.setReadingOrder(ReadingOrder.desc.name());
@@ -52,6 +53,7 @@ public class UserREST extends AbstractResourceREST {
s.setShowRead(true); s.setShowRead(true);
s.setSocialButtons(true); s.setSocialButtons(true);
s.setScrollMarks(true); s.setScrollMarks(true);
s.setLanguage("en");
} }
return s; return s;
} }
@@ -74,6 +76,7 @@ public class UserREST extends AbstractResourceREST {
s.setScrollMarks(settings.isScrollMarks()); s.setScrollMarks(settings.isScrollMarks());
s.setCustomCss(settings.getCustomCss()); s.setCustomCss(settings.getCustomCss());
s.setSocialButtons(settings.isSocialButtons()); s.setSocialButtons(settings.isSocialButtons());
s.setLanguage(settings.getLanguage());
userSettingsDAO.saveOrUpdate(s); userSettingsDAO.saveOrUpdate(s);
return Response.ok(Status.OK).build(); return Response.ok(Status.OK).build();

View File

@@ -3,12 +3,12 @@ package com.commafeed.frontend.utils;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Locale;
import java.util.Properties; import java.util.Properties;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.inject.Inject;
import javax.servlet.Filter; import javax.servlet.Filter;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.FilterConfig; import javax.servlet.FilterConfig;
@@ -23,6 +23,8 @@ import org.apache.commons.io.IOUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.commafeed.backend.dao.UserSettingsDAO;
import com.commafeed.backend.model.UserSettings;
import com.commafeed.frontend.CommaFeedSession; import com.commafeed.frontend.CommaFeedSession;
/** /**
@@ -35,6 +37,9 @@ public class InternationalizationDevelopmentFilter implements Filter {
private static Logger log = LoggerFactory private static Logger log = LoggerFactory
.getLogger(InternationalizationDevelopmentFilter.class); .getLogger(InternationalizationDevelopmentFilter.class);
@Inject
UserSettingsDAO userSettingsDAO;
private boolean production = true; private boolean production = true;
@Override @Override
@@ -56,28 +61,25 @@ public class InternationalizationDevelopmentFilter implements Filter {
} }
}; };
chain.doFilter(request, interceptor); 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.getOutputStream().write(bytes);
response.setContentLength(bytes.length); response.setContentLength(bytes.length);
response.getOutputStream().close(); response.getOutputStream().close();
} }
private String translate(String content, Locale locale) { private String translate(String content, String lang) {
Properties props = new Properties(); Properties props = new Properties();
InputStream is = null; InputStream is = null;
try { try {
is = getClass().getResourceAsStream( is = getClass()
"/i18n/" + locale.getLanguage() + ".properties"); .getResourceAsStream("/i18n/" + lang + ".properties");
if (is == null) {
is = getClass().getResourceAsStream("/i18n/en.properties");
}
if (is == null) {
throw new Exception("Locale file not found for locale "
+ locale.getLanguage());
}
props.load(is); props.load(is);
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);

View File

@@ -13,7 +13,8 @@ app.factory('$templateCache', ['$cacheFactory', '$http', '$injector', function($
} }
if (!allTplPromise) { 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) { function(response) {
$injector.get('$compile')(response.data); $injector.get('$compile')(response.data);
return response; return response;

View File

@@ -798,6 +798,15 @@ function($scope, $location, SettingsService, AnalyticsService) {
AnalyticsService.track(); AnalyticsService.track();
$scope.languages = [ {
id : 'en',
label : 'English'
}, {
id : 'fr',
label : 'Français'
} ];
$scope.settingsService = SettingsService; $scope.settingsService = SettingsService;
$scope.$watch('settingsService.settings', function(value) { $scope.$watch('settingsService.settings', function(value) {
$scope.settings = angular.copy(value); $scope.settings = angular.copy(value);
@@ -811,7 +820,7 @@ function($scope, $location, SettingsService, AnalyticsService) {
$scope.save = function() { $scope.save = function() {
SettingsService.settings = $scope.settings; SettingsService.settings = $scope.settings;
SettingsService.save(function() { SettingsService.save(function() {
$location.path('/'); window.location.href = window.location.href.substring(0, window.location.href.lastIndexOf('#'));
}); });
}; };
}]); }]);

View File

@@ -19,6 +19,14 @@
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane active" id="general"> <div class="tab-pane active" id="general">
<div class="form-horizontal"> <div class="form-horizontal">
<div class="control-group">
<label class="control-label">Language</label>
<div class="controls">
<select name="language" ng-model="settings.language" class="input-block-level"
ng-options="lang.id as lang.label for lang in languages" required>
</select>
</div>
</div>
<div class="control-group"> <div class="control-group">
<label class="checkbox"> <label class="checkbox">
<input type="checkbox" name="showRead" <input type="checkbox" name="showRead"