Allow locale to be selected in footer

This commit is contained in:
Toby Zerner 2015-08-05 09:50:57 +09:30
parent ed823fa43c
commit 69726844d7
11 changed files with 87 additions and 18 deletions

View File

@ -1,4 +1,6 @@
import Component from 'flarum/Component';
import SelectDropdown from 'flarum/components/SelectDropdown';
import Button from 'flarum/components/Button';
import ItemList from 'flarum/utils/ItemList';
import listItems from 'flarum/helpers/listItems';
@ -24,6 +26,31 @@ export default class FooterSecondary extends Component {
items() {
const items = new ItemList();
if (Object.keys(app.locales).length > 1) {
const locales = [];
for (const locale in app.locales) {
locales.push(Button.component({
active: app.locale === locale,
children: app.locales[locale],
icon: app.locale === locale ? 'check' : true,
onclick: () => {
if (app.session.user) {
app.session.user.savePreferences({locale}).then(() => window.location.reload());
} else {
document.cookie = `locale=${locale}; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT`;
window.location.reload();
}
}
}));
}
items.add('locale', SelectDropdown.component({
children: locales,
buttonClassName: 'Button Button--text'
}));
}
items.add('poweredBy', (
<a href="http://flarum.org?r=forum" target="_blank">
{app.trans('core.powered_by_flarum')}

View File

@ -98,13 +98,10 @@ export default class SettingsPage extends UserPage {
*/
preferenceSaver(key) {
return (value, component) => {
const preferences = this.user.preferences();
preferences[key] = value;
if (component) component.loading = true;
m.redraw();
this.user.save({preferences}).then(() => {
this.user.savePreferences({[key]: value}).then(() => {
if (component) component.loading = false;
m.redraw();
});

View File

@ -27,7 +27,7 @@ export default class SelectDropdown extends Dropdown {
if (label instanceof Array) label = label[0];
return [
<span className="Button-label">{label}</span>, ' ',
<span className="Button-label">{label}</span>,
icon(this.props.caretIcon, {className: 'Button-caret'})
];
}

View File

@ -100,4 +100,18 @@ export default class User extends mixin(Model, {
};
image.src = this.avatarUrl();
}
/**
* Update the user's preferences.
*
* @param {Object} newPreferences
* @return {Promise}
*/
savePreferences(newPreferences) {
const preferences = this.preferences();
Object.assign(preferences, newPreferences);
return this.save({preferences});
}
}

View File

@ -354,14 +354,14 @@
.Footer-primary {
display: inline-block;
> li {
.Footer-controls > li {
margin-right: 15px;
}
}
.Footer-secondary {
float: right;
> li {
.Footer-controls > li {
margin-left: 15px;
}
}

View File

@ -227,6 +227,9 @@
.Button-caret {
font-size: 14px;
}
.Button-caret {
margin-left: 3px;
}
.Button-badge {
font-size: 12px;
font-weight: bold;

View File

@ -20,7 +20,6 @@ class CreateUsersTable extends Migration
$table->string('email', 150)->unique();
$table->boolean('is_activated')->default(0);
$table->string('password', 100);
$table->string('locale', 10)->default('en');
$table->text('bio')->nullable();
$table->string('avatar_path', 100)->nullable();
$table->binary('preferences')->nullable();

View File

@ -31,7 +31,6 @@ class ClientAction extends BaseClientAction
$view = parent::render($request, $routeParams);
$view->setVariable('config', $this->settings->all());
$view->setVariable('locales', app('flarum.localeManager')->getLocales());
$view->setVariable('permissions', Permission::map());
$view->setVariable('extensions', app('flarum.extensions')->getInfo());

View File

@ -24,6 +24,7 @@ class UsersServiceProvider extends ServiceProvider
$events->listen(RegisterUserPreferences::class, function (RegisterUserPreferences $event) {
$event->register('discloseOnline', 'boolval', true);
$event->register('indexProfile', 'boolval', true);
$event->register('locale');
});
$events->listen(ModelAllow::class, function (ModelAllow $event) {

View File

@ -20,6 +20,11 @@ class LocaleManager
return $this->locales;
}
public function hasLocale($locale)
{
return isset($this->locales[$locale]);
}
public function addTranslations($locale, $translations)
{
if (! isset($this->translations[$locale])) {

View File

@ -89,31 +89,35 @@ abstract class ClientAction extends HtmlAction
{
$actor = app('flarum.actor');
$assets = $this->getAssets();
$locale = $this->getLocaleCompiler($actor);
$locale = $this->getLocale($actor, $request);
$localeCompiler = $this->getLocaleCompiler($locale);
$view = new ClientView(
$this->apiClient,
$request,
$actor,
$assets,
$locale,
$localeCompiler,
$this->layout
);
$view->setVariable('locales', $this->locales->getLocales());
$view->setVariable('locale', $locale);
// Now that we've set up the ClientView instance, we can fire an event
// to give extensions the opportunity to add their own assets and
// translations. We will pass an array to the event which specifies
// which translations should be included in the locale file. Afterwards,
// we will filter all of the translations for the actor's locale and
// compile only the ones we need.
$translations = $this->locales->getTranslations($actor->locale);
$translations = $this->locales->getTranslations($locale);
$keys = $this->translationKeys;
event(new BuildClientView($this, $view, $keys));
$translations = $this->filterTranslations($translations, $keys);
$locale->setTranslations($translations);
$localeCompiler->setTranslations($translations);
return $view;
}
@ -202,15 +206,13 @@ abstract class ClientAction extends HtmlAction
}
/**
* Set up the locale compiler for the given user's locale.
* Set up the locale compiler for the given locale.
*
* @param User $actor
* @param string $locale
* @return LocaleJsCompiler
*/
protected function getLocaleCompiler(User $actor)
protected function getLocaleCompiler($locale)
{
$locale = $actor->locale;
$compiler = new LocaleJsCompiler($this->getAssetDirectory(), "$this->clientName-$locale.js");
foreach ($this->locales->getJsFiles($locale) as $file) {
@ -220,6 +222,28 @@ abstract class ClientAction extends HtmlAction
return $compiler;
}
/**
* Get the name of the locale to use.
*
* @param User $actor
* @param Request $request
* @return string
*/
protected function getLocale(User $actor, Request $request)
{
if ($actor->exists) {
$locale = $actor->getPreference('locale');
} else {
$locale = array_get($request->getCookieParams(), 'locale');
}
if (! $locale || ! $this->locales->hasLocale($locale)) {
return $this->settings->get('default_locale', 'en');
}
return $locale;
}
/**
* Get the path to the directory where assets should be written.
*