Allow to change language

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2020-06-16 18:00:27 +02:00
parent 45768aa8fd
commit ffc595752a
8 changed files with 110 additions and 9 deletions

View File

@ -106,6 +106,7 @@ export const USER_SETTINGS_FRAGMENT = gql`
export const USER_SETTINGS = gql`
query UserSetting {
loggedUser {
locale
settings {
...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
}
}
`;

View File

@ -644,5 +644,6 @@
"more than 1360 contributors": "more than 1360 contributors",
"{moderator} has unsuspended profile {profile}": "{moderator} has unsuspended profile {profile}",
"{moderator} has deleted user {user}": "{moderator} has deleted user {user}",
"Change timezone": "Change timezone"
"Change timezone": "Change timezone",
"Select a language": "Select a language"
}

View File

@ -667,5 +667,6 @@
"more than 1360 contributors": "plus de 1360 contributeur·ices",
"{moderator} has unsuspended profile {profile}": "{moderator} a annulé la suspension de {profile}",
"{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
View 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": "繁體中文(台灣)"
}

View File

@ -17,12 +17,12 @@ export interface ICurrentUser {
defaultActor: IPerson;
drafts: IEvent[];
settings: IUserSettings;
locale: string;
}
export interface IUser extends ICurrentUser {
confirmedAt: Date;
confirmationSendAt: Date;
locale: String;
actors: IPerson[];
disabled: boolean;
}

View File

@ -1,5 +1,16 @@
<template>
<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-select
:placeholder="$t('Select a timezone')"
@ -17,19 +28,20 @@
</optgroup>
</b-select>
</b-field>
<span>{{
<em>{{
$t("Timezone detected as {timezone}.", {
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
})
}}</span>
}}</em>
</div>
</template>
<script lang="ts">
import { Component, Vue, Watch } from "vue-property-decorator";
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 { ICurrentUser } from "../../types/current-user.model";
import langs from "../../i18n/langs.json";
@Component({
apollo: {
@ -44,6 +56,8 @@ export default class Preferences extends Vue {
selectedTimezone: string | null = null;
locale: string | null = null;
@Watch("loggedUser")
setSavedTimezone(loggedUser: ICurrentUser) {
if (loggedUser && loggedUser.settings.timezone) {
@ -51,6 +65,11 @@ export default class Preferences extends Vue {
} else {
this.selectedTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
}
if (loggedUser && loggedUser.locale) {
this.locale = loggedUser.locale;
} else {
this.locale = this.$i18n.locale;
}
}
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")
async updateTimezone() {
if (this.selectedTimezone !== this.loggedUser.settings.timezone) {
await this.$apollo.mutate<{ setUserSetting: string }>({
mutation: SET_USER_SETTINGS,
variables: {
@ -87,4 +121,15 @@ 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>

View File

@ -477,4 +477,13 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
{:error, "Error while saving user setting"}
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

View File

@ -250,5 +250,10 @@ defmodule Mobilizon.GraphQL.Schema.UserType do
arg(:notification_pending_participation, :notification_pending_participation_enum)
resolve(&User.set_user_setting/3)
end
field :update_locale, :user do
arg(:locale, :string)
resolve(&User.update_locale/3)
end
end
end