Allow to change language
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
08b4fb9b08
commit
5cb3f478ae
|
@ -106,6 +106,7 @@ export const USER_SETTINGS_FRAGMENT = gql`
|
||||||
export const USER_SETTINGS = gql`
|
export const USER_SETTINGS = gql`
|
||||||
query UserSetting {
|
query UserSetting {
|
||||||
loggedUser {
|
loggedUser {
|
||||||
|
locale
|
||||||
settings {
|
settings {
|
||||||
...UserSettingFragment
|
...UserSettingFragment
|
||||||
}
|
}
|
||||||
|
@ -189,3 +190,12 @@ export const GET_USER = gql`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const UPDATE_USER_LOCALE = gql`
|
||||||
|
mutation UpdateUserLocale($locale: String!) {
|
||||||
|
updateLocale(locale: $locale) {
|
||||||
|
id
|
||||||
|
locale
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
|
@ -644,5 +644,6 @@
|
||||||
"more than 1360 contributors": "more than 1360 contributors",
|
"more than 1360 contributors": "more than 1360 contributors",
|
||||||
"{moderator} has unsuspended profile {profile}": "{moderator} has unsuspended profile {profile}",
|
"{moderator} has unsuspended profile {profile}": "{moderator} has unsuspended profile {profile}",
|
||||||
"{moderator} has deleted user {user}": "{moderator} has deleted user {user}",
|
"{moderator} has deleted user {user}": "{moderator} has deleted user {user}",
|
||||||
"Change timezone": "Change timezone"
|
"Change timezone": "Change timezone",
|
||||||
|
"Select a language": "Select a language"
|
||||||
}
|
}
|
||||||
|
|
|
@ -667,5 +667,6 @@
|
||||||
"more than 1360 contributors": "plus de 1360 contributeur·ices",
|
"more than 1360 contributors": "plus de 1360 contributeur·ices",
|
||||||
"{moderator} has unsuspended profile {profile}": "{moderator} a annulé la suspension de {profile}",
|
"{moderator} has unsuspended profile {profile}": "{moderator} a annulé la suspension de {profile}",
|
||||||
"{moderator} has deleted user {user}": "{moderator} a supprimé l'utilisateur·ice {user}",
|
"{moderator} has deleted user {user}": "{moderator} a supprimé l'utilisateur·ice {user}",
|
||||||
"Change timezone": "Changer de fuseau horaire"
|
"Change timezone": "Changer de fuseau horaire",
|
||||||
|
"Select a language": "Choisissez une langue"
|
||||||
}
|
}
|
||||||
|
|
30
js/src/i18n/langs.json
Normal file
30
js/src/i18n/langs.json
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"ar": "العربية",
|
||||||
|
"bg": "Български",
|
||||||
|
"be": "Беларуская мова",
|
||||||
|
"br": "Brezhoneg",
|
||||||
|
"ca": "Català",
|
||||||
|
"co": "Corsu",
|
||||||
|
"cs": "čeština",
|
||||||
|
"de": "Deutsch",
|
||||||
|
"en": "English",
|
||||||
|
"eo": "Esperanto",
|
||||||
|
"es": "Español",
|
||||||
|
"fi": "suomi",
|
||||||
|
"fr": "Français",
|
||||||
|
"gl": "Galego",
|
||||||
|
"hu": "Magyar",
|
||||||
|
"it": "Italiano",
|
||||||
|
"ja": "日本語",
|
||||||
|
"nl": "Dutch",
|
||||||
|
"oc": "Occitan",
|
||||||
|
"pl": "Polski",
|
||||||
|
"pt": "Português",
|
||||||
|
"pt_PT": "Português (Portugal)",
|
||||||
|
"ru": "Русский",
|
||||||
|
"sq": "Shqip",
|
||||||
|
"sv": "Svenska",
|
||||||
|
"tr": "Türkçe",
|
||||||
|
"vi": "Tiếng Việt",
|
||||||
|
"zh_Hant_TW": "繁體中文(台灣)"
|
||||||
|
}
|
|
@ -17,12 +17,12 @@ export interface ICurrentUser {
|
||||||
defaultActor: IPerson;
|
defaultActor: IPerson;
|
||||||
drafts: IEvent[];
|
drafts: IEvent[];
|
||||||
settings: IUserSettings;
|
settings: IUserSettings;
|
||||||
|
locale: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IUser extends ICurrentUser {
|
export interface IUser extends ICurrentUser {
|
||||||
confirmedAt: Date;
|
confirmedAt: Date;
|
||||||
confirmationSendAt: Date;
|
confirmationSendAt: Date;
|
||||||
locale: String;
|
|
||||||
actors: IPerson[];
|
actors: IPerson[];
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<b-field :label="$t('Language')">
|
||||||
|
<b-select
|
||||||
|
:loading="!config || !loggedUser"
|
||||||
|
v-model="$i18n.locale"
|
||||||
|
:placeholder="$t('Select a language')"
|
||||||
|
>
|
||||||
|
<option v-for="(language, lang) in languages" :value="lang" :key="lang">
|
||||||
|
{{ language }}
|
||||||
|
</option>
|
||||||
|
</b-select>
|
||||||
|
</b-field>
|
||||||
<b-field :label="$t('Timezone')">
|
<b-field :label="$t('Timezone')">
|
||||||
<b-select
|
<b-select
|
||||||
:placeholder="$t('Select a timezone')"
|
:placeholder="$t('Select a timezone')"
|
||||||
|
@ -17,19 +28,20 @@
|
||||||
</optgroup>
|
</optgroup>
|
||||||
</b-select>
|
</b-select>
|
||||||
</b-field>
|
</b-field>
|
||||||
<span>{{
|
<em>{{
|
||||||
$t("Timezone detected as {timezone}.", {
|
$t("Timezone detected as {timezone}.", {
|
||||||
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||||
})
|
})
|
||||||
}}</span>
|
}}</em>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Vue, Watch } from "vue-property-decorator";
|
import { Component, Vue, Watch } from "vue-property-decorator";
|
||||||
import { TIMEZONES } from "../../graphql/config";
|
import { TIMEZONES } from "../../graphql/config";
|
||||||
import { USER_SETTINGS, SET_USER_SETTINGS } from "../../graphql/user";
|
import { USER_SETTINGS, SET_USER_SETTINGS, UPDATE_USER_LOCALE } from "../../graphql/user";
|
||||||
import { IConfig } from "../../types/config.model";
|
import { IConfig } from "../../types/config.model";
|
||||||
import { ICurrentUser } from "../../types/current-user.model";
|
import { ICurrentUser } from "../../types/current-user.model";
|
||||||
|
import langs from "../../i18n/langs.json";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
apollo: {
|
apollo: {
|
||||||
|
@ -44,6 +56,8 @@ export default class Preferences extends Vue {
|
||||||
|
|
||||||
selectedTimezone: string | null = null;
|
selectedTimezone: string | null = null;
|
||||||
|
|
||||||
|
locale: string | null = null;
|
||||||
|
|
||||||
@Watch("loggedUser")
|
@Watch("loggedUser")
|
||||||
setSavedTimezone(loggedUser: ICurrentUser) {
|
setSavedTimezone(loggedUser: ICurrentUser) {
|
||||||
if (loggedUser && loggedUser.settings.timezone) {
|
if (loggedUser && loggedUser.settings.timezone) {
|
||||||
|
@ -51,6 +65,11 @@ export default class Preferences extends Vue {
|
||||||
} else {
|
} else {
|
||||||
this.selectedTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
this.selectedTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||||
}
|
}
|
||||||
|
if (loggedUser && loggedUser.locale) {
|
||||||
|
this.locale = loggedUser.locale;
|
||||||
|
} else {
|
||||||
|
this.locale = this.$i18n.locale;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sanitize(timezone: string): string {
|
sanitize(timezone: string): string {
|
||||||
|
@ -77,8 +96,23 @@ export default class Preferences extends Vue {
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get languages(): object {
|
||||||
|
return this.$i18n.availableLocales.reduce((acc: object, lang: string) => {
|
||||||
|
// @ts-ignore
|
||||||
|
if (langs[lang]) {
|
||||||
|
return {
|
||||||
|
...acc,
|
||||||
|
// @ts-ignore
|
||||||
|
[lang]: langs[lang],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {} as object);
|
||||||
|
}
|
||||||
|
|
||||||
@Watch("selectedTimezone")
|
@Watch("selectedTimezone")
|
||||||
async updateTimezone() {
|
async updateTimezone() {
|
||||||
|
if (this.selectedTimezone !== this.loggedUser.settings.timezone) {
|
||||||
await this.$apollo.mutate<{ setUserSetting: string }>({
|
await this.$apollo.mutate<{ setUserSetting: string }>({
|
||||||
mutation: SET_USER_SETTINGS,
|
mutation: SET_USER_SETTINGS,
|
||||||
variables: {
|
variables: {
|
||||||
|
@ -86,5 +120,16 @@ export default class Preferences extends Vue {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Watch("$i18n.locale")
|
||||||
|
async updateLocale() {
|
||||||
|
await this.$apollo.mutate({
|
||||||
|
mutation: UPDATE_USER_LOCALE,
|
||||||
|
variables: {
|
||||||
|
locale: this.$i18n.locale,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -477,4 +477,13 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||||
{:error, "Error while saving user setting"}
|
{:error, "Error while saving user setting"}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_locale(_parent, %{locale: locale}, %{
|
||||||
|
context: %{current_user: %User{id: logged_user_id, locale: current_locale} = user}
|
||||||
|
}) do
|
||||||
|
with true == current_locale != locale,
|
||||||
|
{:ok, %User{} = updated_user} <- Users.update_user(user, %{locale: locale}) do
|
||||||
|
{:ok, updated_user}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -250,5 +250,10 @@ defmodule Mobilizon.GraphQL.Schema.UserType do
|
||||||
arg(:notification_pending_participation, :notification_pending_participation_enum)
|
arg(:notification_pending_participation, :notification_pending_participation_enum)
|
||||||
resolve(&User.set_user_setting/3)
|
resolve(&User.set_user_setting/3)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
field :update_locale, :user do
|
||||||
|
arg(:locale, :string)
|
||||||
|
resolve(&User.update_locale/3)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue