@ethora/chat-component-rn 26.8.7 → 26.8.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +27 -4
- package/lib/commonjs/components/Header/HeaderRoomList.js +34 -6
- package/lib/commonjs/components/Header/HeaderRoomList.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatHeader.js +15 -1
- package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatWrapper.js +5 -3
- package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ReduxWrapper.js +8 -0
- package/lib/commonjs/components/MainComponents/ReduxWrapper.js.map +1 -1
- package/lib/commonjs/components/MainComponents/RoomList.js +63 -11
- package/lib/commonjs/components/MainComponents/RoomList.js.map +1 -1
- package/lib/commonjs/components/Menu/HeaderRoomListMenu.js +26 -13
- package/lib/commonjs/components/Menu/HeaderRoomListMenu.js.map +1 -1
- package/lib/commonjs/components/MenuRoom/MenuRoom.js +5 -3
- package/lib/commonjs/components/MenuRoom/MenuRoom.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/Message.js +3 -3
- package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/MessageInteractions.js +5 -3
- package/lib/commonjs/components/MessageBubble/MessageInteractions.js.map +1 -1
- package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js +1 -1
- package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
- package/lib/commonjs/components/Modals/ChatProfileModal/ReportChatModal.js +5 -4
- package/lib/commonjs/components/Modals/ChatProfileModal/ReportChatModal.js.map +1 -1
- package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js +7 -5
- package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
- package/lib/commonjs/components/Modals/Modal/Modal.js +33 -11
- package/lib/commonjs/components/Modals/Modal/Modal.js.map +1 -1
- package/lib/commonjs/components/Modals/NewChatModal/NewChatModal.js +8 -8
- package/lib/commonjs/components/Modals/NewChatModal/NewChatModal.js.map +1 -1
- package/lib/commonjs/components/Modals/SettingsModals/ChangePassword/ChangePasswordModal.js +279 -0
- package/lib/commonjs/components/Modals/SettingsModals/ChangePassword/ChangePasswordModal.js.map +1 -0
- package/lib/commonjs/components/Modals/SettingsModals/ManageDataModal/ManageDataModal.js +10 -8
- package/lib/commonjs/components/Modals/SettingsModals/ManageDataModal/ManageDataModal.js.map +1 -1
- package/lib/commonjs/components/Modals/SettingsModals/Visibility/VisibilityModal.js +13 -11
- package/lib/commonjs/components/Modals/SettingsModals/Visibility/VisibilityModal.js.map +1 -1
- package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js +22 -38
- package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
- package/lib/commonjs/components/Modals/UserSettingsModal/LanguageCard.js +121 -0
- package/lib/commonjs/components/Modals/UserSettingsModal/LanguageCard.js.map +1 -0
- package/lib/commonjs/components/Modals/UserSettingsModal/UserSettingsModal.js +11 -6
- package/lib/commonjs/components/Modals/UserSettingsModal/UserSettingsModal.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/SwipeableRoomRow.js +133 -0
- package/lib/commonjs/components/RoomComponents/SwipeableRoomRow.js.map +1 -0
- package/lib/commonjs/components/Thread/ThreadWrapper.js +4 -2
- package/lib/commonjs/components/Thread/ThreadWrapper.js.map +1 -1
- package/lib/commonjs/context/xmppProvider.js +15 -3
- package/lib/commonjs/context/xmppProvider.js.map +1 -1
- package/lib/commonjs/e2ee/stanza.js +1 -1
- package/lib/commonjs/e2ee/stanza.js.map +1 -1
- package/lib/commonjs/helpers/constants/MODAL_COMPONENTS.js +2 -0
- package/lib/commonjs/helpers/constants/MODAL_COMPONENTS.js.map +1 -1
- package/lib/commonjs/helpers/constants/MODAL_TYPES.js +1 -0
- package/lib/commonjs/helpers/constants/MODAL_TYPES.js.map +1 -1
- package/lib/commonjs/helpers/preferencesStorage.js.map +1 -1
- package/lib/commonjs/hooks/useChatSettingState.js +4 -0
- package/lib/commonjs/hooks/useChatSettingState.js.map +1 -1
- package/lib/commonjs/hooks/useChatWrapperInit.js +4 -0
- package/lib/commonjs/hooks/useChatWrapperInit.js.map +1 -1
- package/lib/commonjs/hooks/useConnectionLabel.js +29 -0
- package/lib/commonjs/hooks/useConnectionLabel.js.map +1 -0
- package/lib/commonjs/i18n/strings.js +199 -1
- package/lib/commonjs/i18n/strings.js.map +1 -1
- package/lib/commonjs/i18n/useT.js +8 -4
- package/lib/commonjs/i18n/useT.js.map +1 -1
- package/lib/commonjs/networking/api-requests/user.api.js +13 -0
- package/lib/commonjs/networking/api-requests/user.api.js.map +1 -1
- package/lib/commonjs/networking/stanzaHandlers.js +1 -1
- package/lib/commonjs/networking/stanzaHandlers.js.map +1 -1
- package/lib/commonjs/networking/xmppClient.js +29 -1
- package/lib/commonjs/networking/xmppClient.js.map +1 -1
- package/lib/commonjs/roomStore/chatSettingsSlice.js +12 -2
- package/lib/commonjs/roomStore/chatSettingsSlice.js.map +1 -1
- package/lib/commonjs/services/languageSettings.js +177 -0
- package/lib/commonjs/services/languageSettings.js.map +1 -0
- package/lib/commonjs/version.js +1 -1
- package/lib/module/components/Header/HeaderRoomList.js +34 -6
- package/lib/module/components/Header/HeaderRoomList.js.map +1 -1
- package/lib/module/components/MainComponents/ChatHeader.js +15 -1
- package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/module/components/MainComponents/ChatWrapper.js +5 -3
- package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/module/components/MainComponents/ReduxWrapper.js +9 -1
- package/lib/module/components/MainComponents/ReduxWrapper.js.map +1 -1
- package/lib/module/components/MainComponents/RoomList.js +64 -12
- package/lib/module/components/MainComponents/RoomList.js.map +1 -1
- package/lib/module/components/Menu/HeaderRoomListMenu.js +26 -13
- package/lib/module/components/Menu/HeaderRoomListMenu.js.map +1 -1
- package/lib/module/components/MenuRoom/MenuRoom.js +5 -3
- package/lib/module/components/MenuRoom/MenuRoom.js.map +1 -1
- package/lib/module/components/MessageBubble/Message.js +3 -3
- package/lib/module/components/MessageBubble/Message.js.map +1 -1
- package/lib/module/components/MessageBubble/MessageInteractions.js +5 -3
- package/lib/module/components/MessageBubble/MessageInteractions.js.map +1 -1
- package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js +1 -1
- package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
- package/lib/module/components/Modals/ChatProfileModal/ReportChatModal.js +5 -4
- package/lib/module/components/Modals/ChatProfileModal/ReportChatModal.js.map +1 -1
- package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js +7 -5
- package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
- package/lib/module/components/Modals/Modal/Modal.js +33 -11
- package/lib/module/components/Modals/Modal/Modal.js.map +1 -1
- package/lib/module/components/Modals/NewChatModal/NewChatModal.js +8 -8
- package/lib/module/components/Modals/NewChatModal/NewChatModal.js.map +1 -1
- package/lib/module/components/Modals/SettingsModals/ChangePassword/ChangePasswordModal.js +274 -0
- package/lib/module/components/Modals/SettingsModals/ChangePassword/ChangePasswordModal.js.map +1 -0
- package/lib/module/components/Modals/SettingsModals/ManageDataModal/ManageDataModal.js +10 -8
- package/lib/module/components/Modals/SettingsModals/ManageDataModal/ManageDataModal.js.map +1 -1
- package/lib/module/components/Modals/SettingsModals/Visibility/VisibilityModal.js +13 -11
- package/lib/module/components/Modals/SettingsModals/Visibility/VisibilityModal.js.map +1 -1
- package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js +24 -40
- package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
- package/lib/module/components/Modals/UserSettingsModal/LanguageCard.js +116 -0
- package/lib/module/components/Modals/UserSettingsModal/LanguageCard.js.map +1 -0
- package/lib/module/components/Modals/UserSettingsModal/UserSettingsModal.js +10 -5
- package/lib/module/components/Modals/UserSettingsModal/UserSettingsModal.js.map +1 -1
- package/lib/module/components/RoomComponents/SwipeableRoomRow.js +126 -0
- package/lib/module/components/RoomComponents/SwipeableRoomRow.js.map +1 -0
- package/lib/module/components/Thread/ThreadWrapper.js +4 -2
- package/lib/module/components/Thread/ThreadWrapper.js.map +1 -1
- package/lib/module/context/xmppProvider.js +16 -4
- package/lib/module/context/xmppProvider.js.map +1 -1
- package/lib/module/e2ee/stanza.js +1 -1
- package/lib/module/e2ee/stanza.js.map +1 -1
- package/lib/module/helpers/constants/MODAL_COMPONENTS.js +2 -0
- package/lib/module/helpers/constants/MODAL_COMPONENTS.js.map +1 -1
- package/lib/module/helpers/constants/MODAL_TYPES.js +1 -0
- package/lib/module/helpers/constants/MODAL_TYPES.js.map +1 -1
- package/lib/module/helpers/preferencesStorage.js.map +1 -1
- package/lib/module/hooks/useChatSettingState.js +4 -0
- package/lib/module/hooks/useChatSettingState.js.map +1 -1
- package/lib/module/hooks/useChatWrapperInit.js +4 -0
- package/lib/module/hooks/useChatWrapperInit.js.map +1 -1
- package/lib/module/hooks/useConnectionLabel.js +25 -0
- package/lib/module/hooks/useConnectionLabel.js.map +1 -0
- package/lib/module/i18n/strings.js +199 -1
- package/lib/module/i18n/strings.js.map +1 -1
- package/lib/module/i18n/useT.js +8 -4
- package/lib/module/i18n/useT.js.map +1 -1
- package/lib/module/networking/api-requests/user.api.js +12 -0
- package/lib/module/networking/api-requests/user.api.js.map +1 -1
- package/lib/module/networking/stanzaHandlers.js +1 -1
- package/lib/module/networking/stanzaHandlers.js.map +1 -1
- package/lib/module/networking/xmppClient.js +29 -1
- package/lib/module/networking/xmppClient.js.map +1 -1
- package/lib/module/roomStore/chatSettingsSlice.js +9 -1
- package/lib/module/roomStore/chatSettingsSlice.js.map +1 -1
- package/lib/module/services/languageSettings.js +164 -0
- package/lib/module/services/languageSettings.js.map +1 -0
- package/lib/module/version.js +1 -1
- package/lib/typescript/components/Header/HeaderRoomList.d.ts +1 -0
- package/lib/typescript/components/Header/HeaderRoomList.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ReduxWrapper.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/RoomList.d.ts.map +1 -1
- package/lib/typescript/components/Menu/HeaderRoomListMenu.d.ts +7 -1
- package/lib/typescript/components/Menu/HeaderRoomListMenu.d.ts.map +1 -1
- package/lib/typescript/components/MenuRoom/MenuRoom.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts.map +1 -1
- package/lib/typescript/components/Modals/ChatProfileModal/ReportChatModal.d.ts +2 -0
- package/lib/typescript/components/Modals/ChatProfileModal/ReportChatModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/FilePreviewModal/FilePreviewModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/Modal/Modal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/SettingsModals/ChangePassword/ChangePasswordModal.d.ts +15 -0
- package/lib/typescript/components/Modals/SettingsModals/ChangePassword/ChangePasswordModal.d.ts.map +1 -0
- package/lib/typescript/components/Modals/SettingsModals/ManageDataModal/ManageDataModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/SettingsModals/Visibility/VisibilityModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/UserProfileModal/UserProfileModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/UserSettingsModal/LanguageCard.d.ts +14 -0
- package/lib/typescript/components/Modals/UserSettingsModal/LanguageCard.d.ts.map +1 -0
- package/lib/typescript/components/Modals/UserSettingsModal/UserSettingsModal.d.ts.map +1 -1
- package/lib/typescript/components/RoomComponents/SwipeableRoomRow.d.ts +19 -0
- package/lib/typescript/components/RoomComponents/SwipeableRoomRow.d.ts.map +1 -0
- package/lib/typescript/components/Thread/ThreadWrapper.d.ts.map +1 -1
- package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
- package/lib/typescript/helpers/constants/MODAL_COMPONENTS.d.ts.map +1 -1
- package/lib/typescript/helpers/constants/MODAL_TYPES.d.ts +1 -0
- package/lib/typescript/helpers/constants/MODAL_TYPES.d.ts.map +1 -1
- package/lib/typescript/helpers/preferencesStorage.d.ts +4 -0
- package/lib/typescript/helpers/preferencesStorage.d.ts.map +1 -1
- package/lib/typescript/hooks/useChatSettingState.d.ts +2 -0
- package/lib/typescript/hooks/useChatSettingState.d.ts.map +1 -1
- package/lib/typescript/hooks/useChatWrapperInit.d.ts.map +1 -1
- package/lib/typescript/hooks/useConnectionLabel.d.ts +8 -0
- package/lib/typescript/hooks/useConnectionLabel.d.ts.map +1 -0
- package/lib/typescript/i18n/strings.d.ts.map +1 -1
- package/lib/typescript/i18n/useT.d.ts.map +1 -1
- package/lib/typescript/networking/api-requests/user.api.d.ts +6 -0
- package/lib/typescript/networking/api-requests/user.api.d.ts.map +1 -1
- package/lib/typescript/networking/stanzaHandlers.d.ts.map +1 -1
- package/lib/typescript/networking/xmppClient.d.ts +11 -1
- package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
- package/lib/typescript/roomStore/chatSettingsSlice.d.ts +18 -1
- package/lib/typescript/roomStore/chatSettingsSlice.d.ts.map +1 -1
- package/lib/typescript/services/languageSettings.d.ts +29 -0
- package/lib/typescript/services/languageSettings.d.ts.map +1 -0
- package/lib/typescript/types/models/user.model.d.ts +4 -0
- package/lib/typescript/types/models/user.model.d.ts.map +1 -1
- package/lib/typescript/types/types.d.ts +23 -0
- package/lib/typescript/types/types.d.ts.map +1 -1
- package/lib/typescript/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/Header/HeaderRoomList.tsx +31 -6
- package/src/components/MainComponents/ChatHeader.tsx +16 -1
- package/src/components/MainComponents/ChatWrapper.tsx +5 -3
- package/src/components/MainComponents/ReduxWrapper.tsx +6 -0
- package/src/components/MainComponents/RoomList.tsx +78 -12
- package/src/components/Menu/HeaderRoomListMenu.tsx +40 -13
- package/src/components/MenuRoom/MenuRoom.tsx +5 -3
- package/src/components/MessageBubble/Message.tsx +3 -3
- package/src/components/MessageBubble/MessageInteractions.tsx +5 -3
- package/src/components/Modals/ChatProfileModal/ChatProfileModal.tsx +1 -1
- package/src/components/Modals/ChatProfileModal/ReportChatModal.tsx +6 -3
- package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +7 -5
- package/src/components/Modals/Modal/Modal.tsx +44 -16
- package/src/components/Modals/NewChatModal/NewChatModal.tsx +8 -8
- package/src/components/Modals/SettingsModals/ChangePassword/ChangePasswordModal.tsx +316 -0
- package/src/components/Modals/SettingsModals/ManageDataModal/ManageDataModal.tsx +10 -15
- package/src/components/Modals/SettingsModals/Visibility/VisibilityModal.tsx +13 -14
- package/src/components/Modals/UserProfileModal/UserProfileModal.tsx +19 -40
- package/src/components/Modals/UserSettingsModal/LanguageCard.tsx +144 -0
- package/src/components/Modals/UserSettingsModal/UserSettingsModal.tsx +11 -4
- package/src/components/RoomComponents/SwipeableRoomRow.tsx +133 -0
- package/src/components/Thread/ThreadWrapper.tsx +4 -2
- package/src/context/xmppProvider.tsx +21 -4
- package/src/e2ee/stanza.ts +1 -1
- package/src/helpers/constants/MODAL_COMPONENTS.tsx +2 -0
- package/src/helpers/constants/MODAL_TYPES.ts +1 -0
- package/src/helpers/preferencesStorage.ts +4 -0
- package/src/hooks/useChatSettingState.tsx +8 -0
- package/src/hooks/useChatWrapperInit.ts +4 -0
- package/src/hooks/useConnectionLabel.ts +16 -0
- package/src/i18n/strings.ts +199 -1
- package/src/i18n/useT.ts +6 -4
- package/src/networking/api-requests/user.api.ts +9 -0
- package/src/networking/stanzaHandlers.ts +1 -0
- package/src/networking/xmppClient.ts +33 -1
- package/src/roomStore/chatSettingsSlice.ts +30 -0
- package/src/services/languageSettings.ts +143 -0
- package/src/types/models/user.model.ts +4 -0
- package/src/types/types.ts +23 -0
- package/src/version.ts +1 -1
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// The user's two languages, as the backend keeps them on the profile:
|
|
2
|
+
//
|
|
3
|
+
// appLanguage - the interface: the chat's captions (`uiLocale`).
|
|
4
|
+
// chatLanguage - what incoming messages are translated into, and the
|
|
5
|
+
// language declared on the user's own messages (`langSource`).
|
|
6
|
+
//
|
|
7
|
+
// Both are per account, not per device: a choice made here is written to the
|
|
8
|
+
// profile with `PUT /v1/users` - one field per request, as the web app does,
|
|
9
|
+
// so writing one never rewrites the other - and the profile's values are
|
|
10
|
+
// applied when a session starts. The last choice is also kept on the device,
|
|
11
|
+
// so the interface comes up in the right language before the profile loads.
|
|
12
|
+
//
|
|
13
|
+
// Translation itself happens on the server, per the reader's chatLanguage:
|
|
14
|
+
// that is why the choice has to reach the profile for a translation to ever
|
|
15
|
+
// arrive on a message.
|
|
16
|
+
|
|
17
|
+
import { store } from '../roomStore';
|
|
18
|
+
import { setLangSource, setUiLocale, updateUser } from '../roomStore/chatSettingsSlice';
|
|
19
|
+
import { savePreferences } from '../helpers/preferencesStorage';
|
|
20
|
+
import { updateMe } from '../networking/api-requests/user.api';
|
|
21
|
+
import { LANGUAGE_OPTIONS } from '../helpers/constants/LANGUAGE_OPTIONS';
|
|
22
|
+
import type { IConfig } from '../types/types';
|
|
23
|
+
|
|
24
|
+
export interface LanguageChoice {
|
|
25
|
+
/** BCP-47 tag, e.g. "fr-CA". */
|
|
26
|
+
id: string;
|
|
27
|
+
/** The language's own name for itself. */
|
|
28
|
+
name: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const AUTONYMS: Record<string, string> = {
|
|
32
|
+
en: 'English',
|
|
33
|
+
es: 'Español',
|
|
34
|
+
fr: 'Français',
|
|
35
|
+
pt: 'Português',
|
|
36
|
+
ht: 'Kreyòl ayisyen',
|
|
37
|
+
zh: '中文',
|
|
38
|
+
de: 'Deutsch',
|
|
39
|
+
it: 'Italiano',
|
|
40
|
+
uk: 'Українська',
|
|
41
|
+
ru: 'Русский',
|
|
42
|
+
pl: 'Polski',
|
|
43
|
+
tr: 'Türkçe',
|
|
44
|
+
ar: 'العربية',
|
|
45
|
+
hi: 'हिन्दी',
|
|
46
|
+
ja: '日本語',
|
|
47
|
+
ko: '한국어',
|
|
48
|
+
nl: 'Nederlands',
|
|
49
|
+
sv: 'Svenska',
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/** "en-ca" -> "en-CA"; anything that is not a language tag -> undefined. */
|
|
53
|
+
export const canonicalLocale = (value: unknown): string | undefined => {
|
|
54
|
+
const raw = String(value ?? '').trim();
|
|
55
|
+
const match = /^([A-Za-z]{2,3})(?:[-_]([A-Za-z0-9]{2,8}))?$/.exec(raw);
|
|
56
|
+
if (!match) {return undefined;}
|
|
57
|
+
const [, language, region] = match;
|
|
58
|
+
const base = language!.toLowerCase();
|
|
59
|
+
if (!region) {return base;}
|
|
60
|
+
return `${base}-${region.length === 2 ? region.toUpperCase() : region}`;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const languageLabel = (id: string): string => {
|
|
64
|
+
const exact = LANGUAGE_OPTIONS.find((o) => o.id.toLowerCase() === id.toLowerCase());
|
|
65
|
+
if (exact) {return exact.name;}
|
|
66
|
+
return AUTONYMS[id.split('-')[0]!.toLowerCase()] || id;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const toChoices = (ids: string[] | undefined): LanguageChoice[] | undefined => {
|
|
70
|
+
const list = (ids || []).map(canonicalLocale).filter((id): id is string => !!id);
|
|
71
|
+
return list.length ? list.map((id) => ({ id, name: languageLabel(id) })) : undefined;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const languagesEnabled = (config?: IConfig | null): boolean =>
|
|
75
|
+
config?.settings?.languages?.enabled === true;
|
|
76
|
+
|
|
77
|
+
/** What the interface can be shown in. */
|
|
78
|
+
export const appLanguageChoices = (config?: IConfig | null): LanguageChoice[] =>
|
|
79
|
+
toChoices(config?.settings?.languages?.appLanguages) ??
|
|
80
|
+
LANGUAGE_OPTIONS.map((o) => ({ id: o.id, name: o.name }));
|
|
81
|
+
|
|
82
|
+
/** What messages can be translated into. */
|
|
83
|
+
export const chatLanguageChoices = (config?: IConfig | null): LanguageChoice[] =>
|
|
84
|
+
toChoices(config?.settings?.languages?.chatLanguages) ??
|
|
85
|
+
LANGUAGE_OPTIONS.map((o) => ({ id: o.id, name: o.name }));
|
|
86
|
+
|
|
87
|
+
async function writeToProfile(field: 'appLanguage' | 'chatLanguage', value: string) {
|
|
88
|
+
try {
|
|
89
|
+
await updateMe({ [field]: value });
|
|
90
|
+
// The field alone: replacing the whole user with the backend's profile
|
|
91
|
+
// would drop what only this side holds (tokens, the XMPP password).
|
|
92
|
+
store.dispatch(updateUser({ updates: { [field]: value } }));
|
|
93
|
+
return true;
|
|
94
|
+
} catch (error) {
|
|
95
|
+
// The local choice stands: a flaky network degrades to a device-only
|
|
96
|
+
// setting rather than silently reverting what the user just picked.
|
|
97
|
+
console.warn(`[languages] could not save ${field}`, error);
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** The interface language. Applied at once; written to the profile behind. */
|
|
103
|
+
export async function setAppLanguage(id: string): Promise<boolean> {
|
|
104
|
+
const locale = canonicalLocale(id);
|
|
105
|
+
if (!locale) {return false;}
|
|
106
|
+
store.dispatch(setUiLocale(locale));
|
|
107
|
+
void savePreferences({ uiLocale: locale });
|
|
108
|
+
if (!languagesEnabled(store.getState().chatSettingStore.config)) {return true;}
|
|
109
|
+
return writeToProfile('appLanguage', locale);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** The language messages are translated into. */
|
|
113
|
+
export async function setChatLanguage(id: string): Promise<boolean> {
|
|
114
|
+
const locale = canonicalLocale(id);
|
|
115
|
+
if (!locale) {return false;}
|
|
116
|
+
store.dispatch(setLangSource(locale as any));
|
|
117
|
+
void savePreferences({ chatLanguage: locale });
|
|
118
|
+
if (!languagesEnabled(store.getState().chatSettingStore.config)) {return true;}
|
|
119
|
+
return writeToProfile('chatLanguage', locale);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* The profile's languages, applied when a session starts. The profile is the
|
|
124
|
+
* account's truth; what the device remembered only bridged the gap until
|
|
125
|
+
* now. A profile that has never chosen leaves the device's value alone.
|
|
126
|
+
*/
|
|
127
|
+
export function applyProfileLanguages(
|
|
128
|
+
user: { appLanguage?: string | null; chatLanguage?: string | null } | null | undefined,
|
|
129
|
+
config?: IConfig | null
|
|
130
|
+
): void {
|
|
131
|
+
if (!user || !languagesEnabled(config)) {return;}
|
|
132
|
+
const app = canonicalLocale(user.appLanguage);
|
|
133
|
+
if (app && app !== store.getState().chatSettingStore.uiLocale) {
|
|
134
|
+
store.dispatch(setUiLocale(app));
|
|
135
|
+
void savePreferences({ uiLocale: app });
|
|
136
|
+
}
|
|
137
|
+
// Unset means "follow the app language" - the backend's own rule.
|
|
138
|
+
const chat = canonicalLocale(user.chatLanguage) || app;
|
|
139
|
+
if (chat && chat !== store.getState().chatSettingStore.langSource) {
|
|
140
|
+
store.dispatch(setLangSource(chat as any));
|
|
141
|
+
void savePreferences({ chatLanguage: chat });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -54,6 +54,10 @@ export interface User {
|
|
|
54
54
|
isAssetsOpen?: boolean;
|
|
55
55
|
isAgreeWithTerms?: boolean;
|
|
56
56
|
isSuperAdmin?: boolean;
|
|
57
|
+
/** Interface language on the profile (BCP-47). */
|
|
58
|
+
appLanguage?: string | null;
|
|
59
|
+
/** Language messages are translated into (BCP-47); unset = follow appLanguage. */
|
|
60
|
+
chatLanguage?: string | null;
|
|
57
61
|
}
|
|
58
62
|
|
|
59
63
|
export interface ConfigUser {
|
package/src/types/types.ts
CHANGED
|
@@ -652,6 +652,8 @@ export interface IConfig {
|
|
|
652
652
|
};
|
|
653
653
|
disableProfilesInteractions?: boolean;
|
|
654
654
|
disableUserCount?: boolean;
|
|
655
|
+
/** No Report / Leave behind a room-list row swiped to the left. */
|
|
656
|
+
disableRoomSwipeActions?: boolean;
|
|
655
657
|
disableSentLogic?: boolean;
|
|
656
658
|
disableTypingIndicator?: boolean;
|
|
657
659
|
// Hide the full-screen "Connection error" overlay (the dark modal with
|
|
@@ -811,6 +813,27 @@ export interface IConfig {
|
|
|
811
813
|
hideAppearance?: boolean;
|
|
812
814
|
/** Hide the push-notifications toggle. */
|
|
813
815
|
hidePushToggle?: boolean;
|
|
816
|
+
/**
|
|
817
|
+
* A "Language" card with two pickers, off by default: the interface
|
|
818
|
+
* language (the backend's `user.appLanguage`) and the language messages
|
|
819
|
+
* are translated into (`user.chatLanguage`). A choice is applied at
|
|
820
|
+
* once, kept on the device, and written to the profile with
|
|
821
|
+
* `PUT /v1/users`, one field per request; the profile's values are
|
|
822
|
+
* applied when a session starts. Translation itself is the server's,
|
|
823
|
+
* per the reader's chat language - so `translates.enabled` is what
|
|
824
|
+
* shows the result. Options default to the built-in list (en-CA, es-US,
|
|
825
|
+
* fr-CA); pass BCP-47 tags to offer others.
|
|
826
|
+
*/
|
|
827
|
+
languages?: {
|
|
828
|
+
enabled: boolean;
|
|
829
|
+
appLanguages?: string[];
|
|
830
|
+
chatLanguages?: string[];
|
|
831
|
+
};
|
|
832
|
+
/**
|
|
833
|
+
* A "Change password" screen, off by default: the current password and
|
|
834
|
+
* the new one, sent to `PUT /v2/users/me/password`.
|
|
835
|
+
*/
|
|
836
|
+
changePassword?: boolean;
|
|
814
837
|
};
|
|
815
838
|
|
|
816
839
|
// ----- event hooks -----
|
package/src/version.ts
CHANGED