Skip to content

Commit d997327

Browse files
committed
feat: improve localization interface
1 parent df01e8f commit d997327

File tree

5 files changed

+45
-42
lines changed

5 files changed

+45
-42
lines changed

src/index.ts

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
import deepmerge from 'deepmerge';
21
import type { App } from 'vue';
32
import { reactive } from 'vue';
43

5-
import defaultDictionary from './i18n'
6-
import { createTranslator, createWidget } from './ui';
4+
import { createWidget } from './ui';
75
import type { IPlusAuthContext, IWidgetSettings } from './ui/interfaces';
86
import type { FetchWrapper } from './ui/utils/fetch';
97
import { createFetchWrapper } from './ui/utils/fetch';
10-
import type { Translator } from './ui/utils/translator';
8+
import { Translator } from './ui/utils/translator';
119

1210
export default class PlusAuthWidget {
1311
private _view: App<Element>;
@@ -22,21 +20,18 @@ export default class PlusAuthWidget {
2220

2321
this.http = createFetchWrapper(settings.apiUrl)
2422

25-
const { locale: localeSettings, ...otherSettings } = settings
23+
const reactiveSettings = reactive(settings)
2624

27-
const reactiveSettings = reactive(
28-
deepmerge({
29-
locale: {
30-
defaultLocale: localeSettings?.defaultLocale || 'en',
31-
selectedLocale: localeSettings?.selectedLocale || context.params?.ui_locale,
32-
dictionary: deepmerge(defaultDictionary, localeSettings?.dictionary || {})
25+
this.i18n = new Translator(reactiveSettings.locale)
26+
if(context.params?.ui_locales){
27+
const userPreferredLocales = context.params?.ui_locales?.split(' ') || []
28+
for (let contextLocale of userPreferredLocales) {
29+
if(this.i18n.locales[contextLocale]){
30+
this.i18n.locale = contextLocale
31+
break;
3332
}
34-
},
35-
otherSettings,
36-
{ clone: true })
37-
)
38-
39-
this.i18n = createTranslator(reactiveSettings.locale)
33+
}
34+
}
4035
this._view = createWidget(container || document.body, reactiveSettings as any, context, {
4136
i18n: this.i18n,
4237
http: this.http,

src/ui/components/Footer.vue

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<template>
22
<footer>
3-
<template v-if="languages && languages.length">
3+
<template v-if="languages && languages.length > 1">
44
<PSelect
55
v-model="translator.locale"
66
flat
77
label="Language"
88
style="width: auto; margin: 0"
99
dense
1010
hide-messages
11+
item-text="label"
1112
:items="languages"
1213
/>
1314
</template>
@@ -38,9 +39,10 @@
3839
</template>
3940

4041
<script lang="ts">
41-
import { defineComponent, inject, reactive } from 'vue';
42+
import { defineComponent, inject } from 'vue';
4243
4344
import type { IPlusAuthContext } from '../interfaces';
45+
import type { Translator } from '../utils/translator';
4446
import { translatorKey } from '../utils/translator';
4547
4648
export default defineComponent({
@@ -57,12 +59,11 @@ export default defineComponent({
5759
},
5860
setup(){
5961
const context = inject('context') as IPlusAuthContext
60-
const translator = inject(translatorKey) as any
62+
const translator = inject(translatorKey) as Translator
6163
const client = context.client
62-
const languages = reactive(context.ui_locales || [])
6364
return {
6465
translator,
65-
languages,
66+
languages: Object.values(translator.locales || []),
6667
tosUri: client.tosUri,
6768
policyUri: client.policyUri,
6869
}

src/ui/index.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,12 @@ import { Theme } from './utils/theme';
77
import { Translator, translatorKey } from './utils/translator';
88
import { App } from './widget';
99

10-
export function createTranslator(settings: IWidgetSettings['locale']) {
11-
return new Translator(
12-
settings.dictionary,
13-
settings.defaultLocale,
14-
settings.selectedLocale
15-
)
16-
}
17-
1810
export function createWidget(container: Element | string,
1911
settings: IWidgetSettings,
2012
context: Partial<IPlusAuthContext>,
2113
inject) {
2214
const theme = new Theme(settings.theme);
23-
const translator = inject.i18n || createTranslator(settings.locale)
15+
const translator = inject.i18n || new Translator(settings.locale)
2416
const widget = createApp(App(theme, settings));
2517

2618
widget.directive('t', i18n)

src/ui/interfaces/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export interface IClient {
2323

2424
type DictionaryItem = string | Record<string, any>
2525
export interface ILocaleSettings {
26+
locales?: Record<string, { label: string, codes: string[] }>
2627
dictionary: Record<string, typeof defaultDictionary | DictionaryItem>;
2728
defaultLocale: string;
2829
selectedLocale?: string;
@@ -189,8 +190,7 @@ export interface IPlusAuthContext {
189190
prompt?: {
190191
name: string,
191192
mode?: string
192-
},
193-
ui_locales: string[]
193+
}
194194
}
195195

196196
export type ITranslatePath = string | {

src/ui/utils/translator.ts

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,44 @@
1+
import deepmerge from 'deepmerge';
12
import type { Ref } from 'vue';
23
import { getCurrentInstance } from 'vue';
34
import { ref } from 'vue';
45

6+
import defaultDictionary from '../../i18n'
7+
8+
import type { ILocaleSettings } from '../interfaces';
9+
510
import { escapeRegExp, isObject, keysToDotNotation, propertyAccessor } from '.';
611

712
export const translatorKey = Symbol('t')
813

914

1015
export class Translator {
11-
private fallBackLocale: string;
16+
private defaultLocale: string;
1217
private dictionary: any;
1318
private selectedLocale: Ref
19+
locales: Record<string, { label: string, codes: string[], value: string }>
1420

15-
constructor(dictionary: any, fallbackLocale?: string, selectedLocale?: string) {
16-
this.dictionary = dictionary;
17-
this.fallBackLocale = fallbackLocale || 'en'
18-
this.selectedLocale = ref<string | undefined>(selectedLocale || this.fallBackLocale)
21+
constructor(options: Partial<ILocaleSettings> = {}) {
22+
this.dictionary = deepmerge(defaultDictionary, options.dictionary || {});
23+
this.defaultLocale = options.defaultLocale = options.defaultLocale || 'en'
24+
this.selectedLocale = ref<string | undefined>(options.selectedLocale || this.defaultLocale)
25+
this.locales = Object.keys(this.dictionary).reduce((finalLocales, dictKey) => {
26+
finalLocales[dictKey] = options.locales?.[dictKey] || { label: dictKey, codes: [dictKey] }
27+
finalLocales[dictKey].value = dictKey
28+
return finalLocales
29+
}, {})
1930
}
2031

2132
get localeRef() {
2233
return this.selectedLocale
2334
}
2435

2536
set locale(locale: string) {
26-
this.selectedLocale.value = locale
37+
if (this.locales[locale]) {
38+
this.selectedLocale.value = locale
39+
} else {
40+
this.selectedLocale.value = this.defaultLocale
41+
}
2742
}
2843

2944
get locale(): string {
@@ -51,7 +66,7 @@ export class Translator {
5166
}
5267
const locale = opts.locale || this.locale
5368
const value = propertyAccessor(vm.dictionary[locale], key)
54-
|| propertyAccessor(vm.dictionary[vm.fallBackLocale], key);
69+
|| propertyAccessor(vm.dictionary[vm.defaultLocale], key);
5570
if (value) {
5671
return vm._interpolate(
5772
value,
@@ -61,7 +76,7 @@ export class Translator {
6176
} else if (opts.fallback) {
6277
return vm._interpolate(
6378
propertyAccessor(vm.dictionary[locale], opts.fallback)
64-
|| propertyAccessor(vm.dictionary[vm.fallBackLocale], opts.fallback)
79+
|| propertyAccessor(vm.dictionary[vm.defaultLocale], opts.fallback)
6580
|| opts.fallback,
6681
params,
6782
locale
@@ -83,7 +98,7 @@ export class Translator {
8398
str = str.replace(searchRegexp,
8499
v === null ||
85100
v === undefined ? '' : propertyAccessor(this.dictionary[locale], v)
86-
|| propertyAccessor(this.dictionary[this.fallBackLocale], v)
101+
|| propertyAccessor(this.dictionary[this.defaultLocale], v)
87102
|| v
88103
)
89104
})

0 commit comments

Comments
 (0)