stream-chat-react 13.0.5 → 13.1.0
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/dist/components/Channel/Channel.d.ts +1 -1
- package/dist/components/Channel/Channel.js +7 -0
- package/dist/components/ChannelList/hooks/useChannelListShape.js +3 -3
- package/dist/components/Chat/hooks/useChat.js +7 -3
- package/dist/components/Dialog/ButtonWithSubmenu.d.ts +11 -0
- package/dist/components/Dialog/ButtonWithSubmenu.js +88 -0
- package/dist/components/Dialog/index.d.ts +1 -0
- package/dist/components/Dialog/index.js +1 -0
- package/dist/components/Loading/LoadingErrorIndicator.js +1 -1
- package/dist/components/Message/Message.js +3 -2
- package/dist/components/Message/MessageSimple.js +11 -4
- package/dist/components/Message/MessageThreadReplyInChannelButtonIndicator.d.ts +2 -0
- package/dist/components/Message/MessageThreadReplyInChannelButtonIndicator.js +63 -0
- package/dist/components/Message/ReminderNotification.d.ts +6 -0
- package/dist/components/Message/ReminderNotification.js +30 -0
- package/dist/components/Message/hooks/index.d.ts +1 -0
- package/dist/components/Message/hooks/index.js +1 -0
- package/dist/components/Message/hooks/useMessageReminder.d.ts +1 -0
- package/dist/components/Message/hooks/useMessageReminder.js +11 -0
- package/dist/components/Message/index.d.ts +1 -0
- package/dist/components/Message/index.js +1 -0
- package/dist/components/Message/utils.d.ts +4 -2
- package/dist/components/Message/utils.js +11 -1
- package/dist/components/MessageActions/MessageActionsBox.js +12 -6
- package/dist/components/MessageActions/RemindMeSubmenu.d.ts +6 -0
- package/dist/components/MessageActions/RemindMeSubmenu.js +18 -0
- package/dist/components/MessageInput/MessageInputFlat.js +5 -3
- package/dist/components/MessageInput/SendToChannelCheckbox.d.ts +2 -0
- package/dist/components/MessageInput/SendToChannelCheckbox.js +20 -0
- package/dist/components/MessageList/MessageListNotifications.js +8 -3
- package/dist/components/MessageList/VirtualizedMessageListComponents.d.ts +1 -1
- package/dist/components/MessageList/VirtualizedMessageListComponents.js +4 -0
- package/dist/components/Notifications/hooks/index.d.ts +1 -0
- package/dist/components/Notifications/hooks/index.js +1 -0
- package/dist/components/Notifications/hooks/useNotifications.d.ts +2 -0
- package/dist/components/Notifications/hooks/useNotifications.js +10 -0
- package/dist/components/Notifications/index.d.ts +1 -0
- package/dist/components/Notifications/index.js +1 -0
- package/dist/components/TextareaComposer/TextareaComposer.js +4 -0
- package/dist/components/Thread/LegacyThreadContext.d.ts +8 -0
- package/dist/components/Thread/LegacyThreadContext.js +3 -0
- package/dist/components/Thread/Thread.d.ts +0 -4
- package/dist/components/Thread/Thread.js +2 -3
- package/dist/components/Thread/index.d.ts +1 -0
- package/dist/components/Thread/index.js +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/context/ComponentContext.d.ts +6 -1
- package/dist/css/v2/index.css +1 -1
- package/dist/css/v2/index.layout.css +1 -1
- package/dist/experimental/MessageActions/defaults.d.ts +1 -1
- package/dist/experimental/MessageActions/defaults.js +27 -4
- package/dist/experimental/index.browser.cjs +382 -169
- package/dist/experimental/index.browser.cjs.map +4 -4
- package/dist/experimental/index.node.cjs +382 -169
- package/dist/experimental/index.node.cjs.map +4 -4
- package/dist/i18n/Streami18n.d.ts +32 -3
- package/dist/i18n/Streami18n.js +34 -5
- package/dist/i18n/TranslationBuilder/TranslationBuilder.d.ts +31 -0
- package/dist/i18n/TranslationBuilder/TranslationBuilder.js +68 -0
- package/dist/i18n/TranslationBuilder/index.d.ts +2 -0
- package/dist/i18n/TranslationBuilder/index.js +2 -0
- package/dist/i18n/TranslationBuilder/notifications/NotificationTranslationTopic.d.ts +11 -0
- package/dist/i18n/TranslationBuilder/notifications/NotificationTranslationTopic.js +27 -0
- package/dist/i18n/TranslationBuilder/notifications/attachmentUpload.d.ts +4 -0
- package/dist/i18n/TranslationBuilder/notifications/attachmentUpload.js +32 -0
- package/dist/i18n/TranslationBuilder/notifications/index.d.ts +1 -0
- package/dist/i18n/TranslationBuilder/notifications/index.js +1 -0
- package/dist/i18n/TranslationBuilder/notifications/pollComposition.d.ts +3 -0
- package/dist/i18n/TranslationBuilder/notifications/pollComposition.js +9 -0
- package/dist/i18n/TranslationBuilder/notifications/types.d.ts +4 -0
- package/dist/i18n/TranslationBuilder/notifications/types.js +1 -0
- package/dist/i18n/de.json +23 -0
- package/dist/i18n/en.json +23 -0
- package/dist/i18n/es.json +23 -0
- package/dist/i18n/fr.json +23 -0
- package/dist/i18n/hi.json +23 -0
- package/dist/i18n/index.d.ts +1 -0
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/it.json +23 -0
- package/dist/i18n/ja.json +23 -0
- package/dist/i18n/ko.json +23 -0
- package/dist/i18n/nl.json +23 -0
- package/dist/i18n/pt.json +23 -0
- package/dist/i18n/ru.json +23 -0
- package/dist/i18n/tr.json +23 -0
- package/dist/i18n/types.d.ts +54 -0
- package/dist/i18n/utils.d.ts +1 -1
- package/dist/i18n/utils.js +8 -2
- package/dist/index.browser.cjs +3589 -2162
- package/dist/index.browser.cjs.map +4 -4
- package/dist/index.node.cjs +3645 -2156
- package/dist/index.node.cjs.map +4 -4
- package/dist/plugins/Emojis/index.browser.cjs +1 -2
- package/dist/plugins/Emojis/index.browser.cjs.map +3 -3
- package/dist/plugins/Emojis/index.node.cjs +1 -2
- package/dist/plugins/Emojis/index.node.cjs.map +3 -3
- package/dist/scss/v2/Message/Message-layout.scss +11 -1
- package/dist/scss/v2/Message/Message-theme.scss +31 -1
- package/dist/scss/v2/MessageActionsBox/MessageActionsBox-theme.scss +8 -0
- package/dist/scss/v2/MessageInput/MessageInput-layout.scss +19 -0
- package/dist/scss/v2/MessageInput/MessageInput-theme.scss +11 -0
- package/package.json +6 -8
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import Dayjs from 'dayjs';
|
|
2
|
+
import { TranslationBuilder } from './TranslationBuilder';
|
|
2
3
|
import type { TFunction } from 'i18next';
|
|
3
4
|
import type momentTimezone from 'moment-timezone';
|
|
4
5
|
import type { TranslationLanguages } from 'stream-chat';
|
|
6
|
+
import type { TranslationTopicConstructor } from './TranslationBuilder';
|
|
5
7
|
import type { UnknownType } from '../types/types';
|
|
6
8
|
import type { CustomFormatters, PredefinedFormatters, TDateTimeParser } from './types';
|
|
7
9
|
import { enTranslations } from './translations';
|
|
@@ -36,12 +38,15 @@ export type Streami18nOptions = {
|
|
|
36
38
|
formatters?: Partial<PredefinedFormatters> & CustomFormatters;
|
|
37
39
|
language?: TranslationLanguages;
|
|
38
40
|
logger?: (message?: string) => void;
|
|
41
|
+
translationBuilderTopics?: Record<string, TranslationTopicConstructor>;
|
|
39
42
|
parseMissingKeyHandler?: (key: string, defaultValue?: string) => string;
|
|
40
43
|
timezone?: string;
|
|
41
44
|
translationsForLanguage?: Partial<typeof enTranslations>;
|
|
42
45
|
};
|
|
43
46
|
export declare class Streami18n {
|
|
44
47
|
i18nInstance: import("i18next").i18n;
|
|
48
|
+
translationBuilder: TranslationBuilder;
|
|
49
|
+
private translationBuilderTopics;
|
|
45
50
|
Dayjs: null;
|
|
46
51
|
setLanguageCallback: (t: TFunction) => void;
|
|
47
52
|
initialized: boolean;
|
|
@@ -80,6 +85,7 @@ export declare class Streami18n {
|
|
|
80
85
|
lng: string;
|
|
81
86
|
nsSeparator: false;
|
|
82
87
|
parseMissingKeyHandler?: (key: string, defaultValue?: string) => string;
|
|
88
|
+
postProcess?: string[];
|
|
83
89
|
};
|
|
84
90
|
/**
|
|
85
91
|
* A valid TZ identifier string (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
|
|
@@ -116,7 +122,7 @@ export declare class Streami18n {
|
|
|
116
122
|
* Initializes the i18next instance with configuration (which enables natural language as default keys)
|
|
117
123
|
*/
|
|
118
124
|
init(): Promise<{
|
|
119
|
-
t: TFunction
|
|
125
|
+
t: TFunction<"translation", undefined>;
|
|
120
126
|
tDateTimeParser: TDateTimeParser;
|
|
121
127
|
}>;
|
|
122
128
|
localeExists: (language: TranslationLanguages) => boolean;
|
|
@@ -136,6 +142,8 @@ export declare class Streami18n {
|
|
|
136
142
|
"Allow access to microphone": string;
|
|
137
143
|
"Allow comments": string;
|
|
138
144
|
"Allow option suggestion": string;
|
|
145
|
+
"Also send as a direct message": string;
|
|
146
|
+
"Also send in channel": string;
|
|
139
147
|
"An error has occurred during recording": string;
|
|
140
148
|
"An error has occurred during the recording processing": string;
|
|
141
149
|
Anonymous: string;
|
|
@@ -143,6 +151,8 @@ export declare class Streami18n {
|
|
|
143
151
|
Archive: string;
|
|
144
152
|
"Ask a question": string;
|
|
145
153
|
"Attach files": string;
|
|
154
|
+
"Attachment upload blocked due to {{reason}}": string;
|
|
155
|
+
"Attachment upload failed due to {{reason}}": string;
|
|
146
156
|
Cancel: string;
|
|
147
157
|
"Cannot seek in the recording": string;
|
|
148
158
|
"Channel Missing": string;
|
|
@@ -157,6 +167,8 @@ export declare class Streami18n {
|
|
|
157
167
|
"Download attachment {{ name }}": string;
|
|
158
168
|
"Drag your files here": string;
|
|
159
169
|
"Drag your files here to add to your post": string;
|
|
170
|
+
"Due since {{ dueSince }}": string;
|
|
171
|
+
"Due {{ timeLeft }}": string;
|
|
160
172
|
"Edit Message": string;
|
|
161
173
|
"Edit message request failed": string;
|
|
162
174
|
Edited: string;
|
|
@@ -180,6 +192,8 @@ export declare class Streami18n {
|
|
|
180
192
|
"Error uploading image": string;
|
|
181
193
|
"Error \u00B7 Unsent": string;
|
|
182
194
|
"Error: {{ errorMessage }}": string;
|
|
195
|
+
"Failed to create the poll": string;
|
|
196
|
+
"Failed to create the poll due to {{reason}}": string;
|
|
183
197
|
"Failed to jump to the first unread message": string;
|
|
184
198
|
"Failed to mark channel as read": string;
|
|
185
199
|
"Failed to play the recording": string;
|
|
@@ -223,8 +237,12 @@ export declare class Streami18n {
|
|
|
223
237
|
Question: string;
|
|
224
238
|
Quote: string;
|
|
225
239
|
"Recording format is not supported and cannot be reproduced": string;
|
|
240
|
+
"Remind Me": string;
|
|
241
|
+
"Remove reminder": string;
|
|
226
242
|
Reply: string;
|
|
227
243
|
"Reply to Message": string;
|
|
244
|
+
"Save for later": string;
|
|
245
|
+
"Saved for later": string;
|
|
228
246
|
Search: string;
|
|
229
247
|
"Searching...": string;
|
|
230
248
|
"See all options ({{count}})_one": string;
|
|
@@ -248,6 +266,8 @@ export declare class Streami18n {
|
|
|
248
266
|
"This message did not meet our content guidelines": string;
|
|
249
267
|
"This message was deleted...": string;
|
|
250
268
|
Thread: string;
|
|
269
|
+
"Thread has not been found": string;
|
|
270
|
+
"Thread reply": string;
|
|
251
271
|
"To start recording, allow the camera access in your browser": string;
|
|
252
272
|
"To start recording, allow the microphone access in your browser": string;
|
|
253
273
|
"Type a number from 2 to 10": string;
|
|
@@ -288,13 +308,17 @@ export declare class Streami18n {
|
|
|
288
308
|
"aria/Open Reaction Selector": string;
|
|
289
309
|
"aria/Open Thread": string;
|
|
290
310
|
"aria/Reaction list": string;
|
|
311
|
+
"aria/Remind Me Options": string;
|
|
291
312
|
"aria/Remove attachment": string;
|
|
292
313
|
"aria/Retry upload": string;
|
|
293
314
|
"aria/Search results": string;
|
|
294
315
|
"aria/Search results header filter button": string;
|
|
295
316
|
"aria/Send": string;
|
|
296
317
|
"aria/Stop AI Generation": string;
|
|
318
|
+
"duration/Message reminder": string;
|
|
319
|
+
"duration/Remind Me": string;
|
|
297
320
|
live: string;
|
|
321
|
+
"network error": string;
|
|
298
322
|
replyCount_one: string;
|
|
299
323
|
replyCount_other: string;
|
|
300
324
|
"search-results-header-filter-source-button-label--channels": string;
|
|
@@ -302,14 +326,19 @@ export declare class Streami18n {
|
|
|
302
326
|
"search-results-header-filter-source-button-label--users": string;
|
|
303
327
|
searchResultsCount_one: string;
|
|
304
328
|
searchResultsCount_other: string;
|
|
329
|
+
"size limit": string;
|
|
305
330
|
"this content could not be displayed": string;
|
|
306
331
|
"timestamp/DateSeparator": string;
|
|
307
332
|
"timestamp/MessageTimestamp": string;
|
|
308
333
|
"timestamp/PollVote": string;
|
|
309
334
|
"timestamp/PollVoteTooltip": string;
|
|
335
|
+
"timestamp/ReminderNotification": string;
|
|
310
336
|
"timestamp/SystemMessage": string;
|
|
337
|
+
"translationBuilderTopic/notification": string;
|
|
338
|
+
"unknown error": string;
|
|
311
339
|
unreadMessagesSeparatorText_one: string;
|
|
312
340
|
unreadMessagesSeparatorText_other: string;
|
|
341
|
+
"unsupported file type": string;
|
|
313
342
|
"{{ commaSeparatedUsers }} and {{ moreCount }} more": string;
|
|
314
343
|
"{{ commaSeparatedUsers }}, and {{ lastUser }}": string;
|
|
315
344
|
"{{ firstUser }} and {{ secondUser }}": string;
|
|
@@ -335,12 +364,12 @@ export declare class Streami18n {
|
|
|
335
364
|
* Returns current version translator function.
|
|
336
365
|
*/
|
|
337
366
|
getTranslators(): Promise<{
|
|
338
|
-
t: TFunction
|
|
367
|
+
t: TFunction<"translation", undefined>;
|
|
339
368
|
tDateTimeParser: TDateTimeParser;
|
|
340
369
|
}>;
|
|
341
370
|
registerTranslation(language: TranslationLanguages, translation: typeof enTranslations, customDayjsLocale?: Partial<ILocale>): void;
|
|
342
371
|
addOrUpdateLocale(key: TranslationLanguages, config: Partial<ILocale>): void;
|
|
343
|
-
setLanguage(language: TranslationLanguages): Promise<TFunction | undefined>;
|
|
372
|
+
setLanguage(language: TranslationLanguages): Promise<TFunction<"translation", undefined> | undefined>;
|
|
344
373
|
registerSetLanguageCallback(callback: (t: TFunction) => void): void;
|
|
345
374
|
}
|
|
346
375
|
export {};
|
package/dist/i18n/Streami18n.js
CHANGED
|
@@ -5,8 +5,10 @@ import updateLocale from 'dayjs/plugin/updateLocale';
|
|
|
5
5
|
import LocalizedFormat from 'dayjs/plugin/localizedFormat';
|
|
6
6
|
import localeData from 'dayjs/plugin/localeData';
|
|
7
7
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
|
8
|
+
import duration from 'dayjs/plugin/duration';
|
|
8
9
|
import utc from 'dayjs/plugin/utc';
|
|
9
10
|
import timezone from 'dayjs/plugin/timezone';
|
|
11
|
+
import { NotificationTranslationTopic, TranslationBuilder } from './TranslationBuilder';
|
|
10
12
|
import { defaultTranslatorFunction, predefinedFormatters } from './utils';
|
|
11
13
|
import { deTranslations, enTranslations, esTranslations, frTranslations, hiTranslations, itTranslations, jaTranslations, koTranslations, nlTranslations, ptTranslations, ruTranslations, trTranslations, } from './translations';
|
|
12
14
|
import 'dayjs/locale/de';
|
|
@@ -55,7 +57,7 @@ Dayjs.updateLocale('fr', {
|
|
|
55
57
|
lastWeek: 'dddd [dernier à] LT',
|
|
56
58
|
nextDay: '[Demain à] LT',
|
|
57
59
|
nextWeek: 'dddd [à] LT',
|
|
58
|
-
sameDay:
|
|
60
|
+
sameDay: "[Aujourd'hui à] LT",
|
|
59
61
|
sameElse: 'L',
|
|
60
62
|
},
|
|
61
63
|
});
|
|
@@ -205,9 +207,9 @@ const en_locale = {
|
|
|
205
207
|
const isDayJs = (dateTimeParser) => dateTimeParser.extend !== undefined;
|
|
206
208
|
const supportsTz = (dateTimeParser) => dateTimeParser.tz !== undefined;
|
|
207
209
|
/**
|
|
208
|
-
* Wrapper around [i18next](https://www.i18next.com/) class for Stream related
|
|
209
|
-
* Instance of this class should be provided to Chat component to handle
|
|
210
|
-
* Stream provides following list of in-built
|
|
210
|
+
* Wrapper around [i18next](https://www.i18next.com/) class for Stream related i18n.
|
|
211
|
+
* Instance of this class should be provided to Chat component to handle i18n.
|
|
212
|
+
* Stream provides following list of in-built i18n:
|
|
211
213
|
* 1. English (en)
|
|
212
214
|
* 2. Dutch (nl)
|
|
213
215
|
* 3. Russian (ru)
|
|
@@ -271,7 +273,7 @@ const supportsTz = (dateTimeParser) => dateTimeParser.tz !== undefined;
|
|
|
271
273
|
* </Chat>
|
|
272
274
|
* ```
|
|
273
275
|
*
|
|
274
|
-
* ## Datetime
|
|
276
|
+
* ## Datetime i18n
|
|
275
277
|
*
|
|
276
278
|
* Stream react chat components uses [dayjs](https://day.js.org/en/) internally by default to format datetime stamp.
|
|
277
279
|
* e.g., in ChannelPreview, MessageContent components.
|
|
@@ -363,6 +365,18 @@ const defaultStreami18nOptions = {
|
|
|
363
365
|
disableDateTimeTranslations: false,
|
|
364
366
|
language: 'en',
|
|
365
367
|
logger: (message) => console.warn(message),
|
|
368
|
+
/**
|
|
369
|
+
* Key in the translationBuilderTopics has to match postProcessorName in the translation value.
|
|
370
|
+
*
|
|
371
|
+
* {
|
|
372
|
+
* "key": "{{value, postProcessorName}}"
|
|
373
|
+
* }
|
|
374
|
+
*
|
|
375
|
+
* At least the default topics will be supported.
|
|
376
|
+
*/
|
|
377
|
+
translationBuilderTopics: {
|
|
378
|
+
notification: NotificationTranslationTopic,
|
|
379
|
+
},
|
|
366
380
|
};
|
|
367
381
|
export class Streami18n {
|
|
368
382
|
/**
|
|
@@ -393,6 +407,7 @@ export class Streami18n {
|
|
|
393
407
|
*/
|
|
394
408
|
constructor(options = {}) {
|
|
395
409
|
this.i18nInstance = i18n.createInstance();
|
|
410
|
+
this.translationBuilderTopics = {};
|
|
396
411
|
this.Dayjs = null;
|
|
397
412
|
this.setLanguageCallback = () => null;
|
|
398
413
|
this.initialized = false;
|
|
@@ -449,12 +464,18 @@ export class Streami18n {
|
|
|
449
464
|
this.DateTimeParser = finalOptions.DateTimeParser;
|
|
450
465
|
this.timezone = finalOptions.timezone;
|
|
451
466
|
this.formatters = { ...predefinedFormatters, ...options?.formatters };
|
|
467
|
+
this.translationBuilder = new TranslationBuilder(this.i18nInstance);
|
|
468
|
+
this.translationBuilderTopics = {
|
|
469
|
+
...defaultStreami18nOptions.translationBuilderTopics,
|
|
470
|
+
...options.translationBuilderTopics,
|
|
471
|
+
};
|
|
452
472
|
try {
|
|
453
473
|
if (this.DateTimeParser && isDayJs(this.DateTimeParser)) {
|
|
454
474
|
this.DateTimeParser.extend(LocalizedFormat);
|
|
455
475
|
this.DateTimeParser.extend(calendar);
|
|
456
476
|
this.DateTimeParser.extend(localeData);
|
|
457
477
|
this.DateTimeParser.extend(relativeTime);
|
|
478
|
+
this.DateTimeParser.extend(duration);
|
|
458
479
|
}
|
|
459
480
|
}
|
|
460
481
|
catch (error) {
|
|
@@ -487,6 +508,10 @@ export class Streami18n {
|
|
|
487
508
|
lng: this.currentLanguage,
|
|
488
509
|
nsSeparator: false,
|
|
489
510
|
};
|
|
511
|
+
const postProcess = Object.keys(this.translationBuilderTopics);
|
|
512
|
+
if (postProcess.length > 0) {
|
|
513
|
+
this.i18nextConfig.postProcess = postProcess;
|
|
514
|
+
}
|
|
490
515
|
if (finalOptions.parseMissingKeyHandler) {
|
|
491
516
|
this.i18nextConfig.parseMissingKeyHandler = finalOptions.parseMissingKeyHandler;
|
|
492
517
|
}
|
|
@@ -537,6 +562,10 @@ export class Streami18n {
|
|
|
537
562
|
this.i18nInstance.services.formatter?.add(name, formatterFactory(this));
|
|
538
563
|
});
|
|
539
564
|
}
|
|
565
|
+
// Register post-processors after initialization
|
|
566
|
+
Object.entries(this.translationBuilderTopics).forEach(([topic, TranslationTopic]) => {
|
|
567
|
+
this.translationBuilder.registerTopic(topic, TranslationTopic);
|
|
568
|
+
});
|
|
540
569
|
}
|
|
541
570
|
catch (error) {
|
|
542
571
|
this.logger(`Something went wrong with init: ${JSON.stringify(error)}`);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { i18n, TFunction } from 'i18next';
|
|
2
|
+
export type Translator<O extends Record<string, unknown> = Record<string, unknown>> = (params: {
|
|
3
|
+
key: string;
|
|
4
|
+
value: string;
|
|
5
|
+
t: TFunction;
|
|
6
|
+
options: O;
|
|
7
|
+
}) => string | null;
|
|
8
|
+
export type TranslationTopicOptions<O extends Record<string, unknown> = Record<string, unknown>> = {
|
|
9
|
+
i18next: i18n;
|
|
10
|
+
translators?: Record<string, Translator<O>>;
|
|
11
|
+
};
|
|
12
|
+
export declare abstract class TranslationTopic<O extends Record<string, unknown> = Record<string, unknown>> {
|
|
13
|
+
protected options: TranslationTopicOptions<O>;
|
|
14
|
+
protected translators: Map<string, Translator<O>>;
|
|
15
|
+
protected i18next: i18n;
|
|
16
|
+
constructor(options: TranslationTopicOptions<O>);
|
|
17
|
+
abstract translate(value: string, key: string, options: O): string;
|
|
18
|
+
setTranslator: (name: string, translator: Translator<O>) => void;
|
|
19
|
+
removeTranslator: (name: string) => void;
|
|
20
|
+
}
|
|
21
|
+
export type TranslationTopicConstructor = new (options: TranslationTopicOptions) => TranslationTopic;
|
|
22
|
+
export declare class TranslationBuilder {
|
|
23
|
+
private i18next;
|
|
24
|
+
private topics;
|
|
25
|
+
constructor(i18next: i18n);
|
|
26
|
+
registerTopic: (name: string, Topic: TranslationTopicConstructor) => TranslationTopic<Record<string, unknown>>;
|
|
27
|
+
disableTopic: (topicName: string) => void;
|
|
28
|
+
getTopic: (topicName: string) => TranslationTopic<Record<string, unknown>> | undefined;
|
|
29
|
+
registerTranslators(topicName: string, translators: Record<string, Translator>): void;
|
|
30
|
+
removeTranslators(topicName: string, translators: string[]): void;
|
|
31
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export class TranslationTopic {
|
|
2
|
+
constructor(options) {
|
|
3
|
+
this.options = options;
|
|
4
|
+
this.translators = new Map();
|
|
5
|
+
this.setTranslator = (name, translator) => {
|
|
6
|
+
this.translators.set(name, translator);
|
|
7
|
+
};
|
|
8
|
+
this.removeTranslator = (name) => {
|
|
9
|
+
this.translators.delete(name);
|
|
10
|
+
};
|
|
11
|
+
this.i18next = options.i18next;
|
|
12
|
+
if (options.translators) {
|
|
13
|
+
Object.entries(options.translators).forEach(([name, translator]) => {
|
|
14
|
+
this.setTranslator(name, translator);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const forwardTranslation = ({ value }) => value;
|
|
20
|
+
export class TranslationBuilder {
|
|
21
|
+
constructor(i18next) {
|
|
22
|
+
this.i18next = i18next;
|
|
23
|
+
this.topics = new Map();
|
|
24
|
+
this.registerTopic = (name, Topic) => {
|
|
25
|
+
const topic = new Topic({ i18next: this.i18next });
|
|
26
|
+
this.topics.set(name, topic);
|
|
27
|
+
this.i18next.use({
|
|
28
|
+
name,
|
|
29
|
+
process: (value, key, options) => {
|
|
30
|
+
const topic = this.topics.get(name);
|
|
31
|
+
if (!topic)
|
|
32
|
+
return value;
|
|
33
|
+
return topic.translate(value, key, options);
|
|
34
|
+
},
|
|
35
|
+
type: 'postProcessor',
|
|
36
|
+
});
|
|
37
|
+
return topic;
|
|
38
|
+
};
|
|
39
|
+
this.disableTopic = (topicName) => {
|
|
40
|
+
const topic = this.topics.get(topicName);
|
|
41
|
+
if (!topic)
|
|
42
|
+
return;
|
|
43
|
+
this.i18next.use({
|
|
44
|
+
name: topicName,
|
|
45
|
+
process: forwardTranslation,
|
|
46
|
+
type: 'postProcessor',
|
|
47
|
+
});
|
|
48
|
+
this.topics.delete(topicName);
|
|
49
|
+
};
|
|
50
|
+
this.getTopic = (topicName) => this.topics.get(topicName);
|
|
51
|
+
}
|
|
52
|
+
registerTranslators(topicName, translators) {
|
|
53
|
+
const topic = this.getTopic(topicName);
|
|
54
|
+
if (!topic)
|
|
55
|
+
return;
|
|
56
|
+
Object.entries(translators).forEach(([name, translator]) => {
|
|
57
|
+
topic.setTranslator(name, translator);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
removeTranslators(topicName, translators) {
|
|
61
|
+
const topic = this.getTopic(topicName);
|
|
62
|
+
if (!topic)
|
|
63
|
+
return;
|
|
64
|
+
translators.forEach((name) => {
|
|
65
|
+
topic.removeTranslator(name);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { TranslationTopic } from '../../TranslationBuilder';
|
|
2
|
+
import type { Notification } from 'stream-chat';
|
|
3
|
+
import type { NotificationTranslatorOptions } from './types';
|
|
4
|
+
import type { TranslationTopicOptions, Translator } from '../../index';
|
|
5
|
+
export declare const defaultNotificationTranslators: Record<string, Translator<NotificationTranslatorOptions>>;
|
|
6
|
+
export declare class NotificationTranslationTopic extends TranslationTopic<NotificationTranslatorOptions> {
|
|
7
|
+
constructor({ i18next, translators }: TranslationTopicOptions);
|
|
8
|
+
translate: (value: string, key: string, options: {
|
|
9
|
+
notification?: Notification;
|
|
10
|
+
}) => string;
|
|
11
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { attachmentUploadBlockedNotificationTranslator, attachmentUploadFailedNotificationTranslator, } from './attachmentUpload';
|
|
2
|
+
import { TranslationTopic } from '../../TranslationBuilder';
|
|
3
|
+
import { pollCreationFailedNotificationTranslator } from './pollComposition';
|
|
4
|
+
export const defaultNotificationTranslators = {
|
|
5
|
+
'api:attachment:upload:failed': attachmentUploadFailedNotificationTranslator,
|
|
6
|
+
'api:poll:create:failed': pollCreationFailedNotificationTranslator,
|
|
7
|
+
'validation:attachment:upload:blocked': attachmentUploadBlockedNotificationTranslator,
|
|
8
|
+
};
|
|
9
|
+
export class NotificationTranslationTopic extends TranslationTopic {
|
|
10
|
+
constructor({ i18next, translators }) {
|
|
11
|
+
super({ i18next, translators: defaultNotificationTranslators });
|
|
12
|
+
this.translate = (value, key, options) => {
|
|
13
|
+
const { notification } = options;
|
|
14
|
+
if (!notification)
|
|
15
|
+
return value;
|
|
16
|
+
const translator = notification.type && this.translators.get(notification.type);
|
|
17
|
+
if (!translator)
|
|
18
|
+
return value;
|
|
19
|
+
return translator({ key, options, t: this.i18next.t, value }) || value;
|
|
20
|
+
};
|
|
21
|
+
if (translators) {
|
|
22
|
+
Object.entries(translators).forEach(([name, translator]) => {
|
|
23
|
+
this.setTranslator(name, translator);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { NotificationTranslatorOptions } from './types';
|
|
2
|
+
import type { Translator } from '../TranslationBuilder';
|
|
3
|
+
export declare const attachmentUploadBlockedNotificationTranslator: Translator<NotificationTranslatorOptions>;
|
|
4
|
+
export declare const attachmentUploadFailedNotificationTranslator: Translator<NotificationTranslatorOptions>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export const attachmentUploadBlockedNotificationTranslator = ({ options, t }) => {
|
|
2
|
+
const { notification } = options;
|
|
3
|
+
if (!notification)
|
|
4
|
+
return null;
|
|
5
|
+
if (typeof notification.metadata?.reason !== 'string') {
|
|
6
|
+
const reason = t('unknown error');
|
|
7
|
+
return t('Attachment upload blocked due to {{reason}}', { reason });
|
|
8
|
+
}
|
|
9
|
+
if (notification.metadata?.reason === 'size_limit') {
|
|
10
|
+
const reason = t('size limit');
|
|
11
|
+
return t('Attachment upload blocked due to {{reason}}', { reason });
|
|
12
|
+
}
|
|
13
|
+
const reason = t('unsupported file type');
|
|
14
|
+
return t('Attachment upload blocked due to {{reason}}', { reason });
|
|
15
|
+
};
|
|
16
|
+
export const attachmentUploadFailedNotificationTranslator = ({ options, t }) => {
|
|
17
|
+
const { notification } = options;
|
|
18
|
+
if (!notification)
|
|
19
|
+
return null;
|
|
20
|
+
const { reason: originalReason } = notification.metadata ?? {};
|
|
21
|
+
if (typeof originalReason !== 'string') {
|
|
22
|
+
const reason = t('unknown error');
|
|
23
|
+
return t('Attachment upload failed due to {{reason}}', { reason });
|
|
24
|
+
}
|
|
25
|
+
let reason = originalReason.toLowerCase();
|
|
26
|
+
if (reason === 'network error') {
|
|
27
|
+
reason = t('network error');
|
|
28
|
+
return t('Attachment upload failed due to {{reason}}', { reason });
|
|
29
|
+
}
|
|
30
|
+
// custom reason string
|
|
31
|
+
return t('Attachment upload failed due to {{reason}}', { reason });
|
|
32
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { NotificationTranslationTopic } from './NotificationTranslationTopic';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { NotificationTranslationTopic } from './NotificationTranslationTopic';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const pollCreationFailedNotificationTranslator = ({ options: { notification }, t }) => {
|
|
2
|
+
if (typeof notification?.metadata?.reason === 'string' &&
|
|
3
|
+
notification.metadata.reason.length) {
|
|
4
|
+
return t('Failed to create the poll due to {{reason}}', {
|
|
5
|
+
reason: notification.metadata.reason.toLowerCase(),
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
return t('Failed to create the poll');
|
|
9
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/i18n/de.json
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
"Allow access to microphone": "Zugriff auf Mikrofon erlauben",
|
|
7
7
|
"Allow comments": "Kommentare erlauben",
|
|
8
8
|
"Allow option suggestion": "Optionsvorschläge erlauben",
|
|
9
|
+
"Also send as a direct message": "Auch als Direktnachricht senden",
|
|
10
|
+
"Also send in channel": "Auch im Kanal senden",
|
|
9
11
|
"An error has occurred during recording": "Ein Fehler ist während der Aufnahme aufgetreten",
|
|
10
12
|
"An error has occurred during the recording processing": "Ein Fehler ist während der Aufnahmeverarbeitung aufgetreten",
|
|
11
13
|
"Anonymous": "Anonym",
|
|
@@ -13,6 +15,8 @@
|
|
|
13
15
|
"Archive": "Archivieren",
|
|
14
16
|
"Ask a question": "Eine Frage stellen",
|
|
15
17
|
"Attach files": "Dateien anhängen",
|
|
18
|
+
"Attachment upload blocked due to {{reason}}": "Anhang-Upload blockiert wegen {{reason}}",
|
|
19
|
+
"Attachment upload failed due to {{reason}}": "Anhang-Upload fehlgeschlagen wegen {{reason}}",
|
|
16
20
|
"Cancel": "Abbrechen",
|
|
17
21
|
"Cannot seek in the recording": "In der Aufnahme kann nicht gesucht werden",
|
|
18
22
|
"Channel Missing": "Kanal fehlt",
|
|
@@ -27,6 +31,8 @@
|
|
|
27
31
|
"Download attachment {{ name }}": "Anhang {{ name }} herunterladen",
|
|
28
32
|
"Drag your files here": "Ziehen Sie Ihre Dateien hierher",
|
|
29
33
|
"Drag your files here to add to your post": "Ziehen Sie Ihre Dateien hierher, um sie Ihrem Beitrag hinzuzufügen",
|
|
34
|
+
"Due since {{ dueSince }}": "Fällig seit {{ dueSince }}",
|
|
35
|
+
"Due {{ timeLeft }}": "Fällig {{ timeLeft }}",
|
|
30
36
|
"Edit Message": "Nachricht bearbeiten",
|
|
31
37
|
"Edit message request failed": "Anfrage zum Bearbeiten der Nachricht fehlgeschlagen",
|
|
32
38
|
"Edited": "Bearbeitet",
|
|
@@ -50,6 +56,8 @@
|
|
|
50
56
|
"Error uploading image": "Fehler beim Hochladen des Bildes",
|
|
51
57
|
"Error · Unsent": "Fehler · Nicht gesendet",
|
|
52
58
|
"Error: {{ errorMessage }}": "Fehler: {{ errorMessage }}",
|
|
59
|
+
"Failed to create the poll": "Fehler beim Erstellen der Umfrage",
|
|
60
|
+
"Failed to create the poll due to {{reason}}": "Die Umfrage konnte aufgrund von {{reason}} nicht erstellt werden",
|
|
53
61
|
"Failed to jump to the first unread message": "Fehler beim Springen zur ersten ungelesenen Nachricht",
|
|
54
62
|
"Failed to mark channel as read": "Fehler beim Markieren des Kanals als gelesen",
|
|
55
63
|
"Failed to play the recording": "Wiedergabe der Aufnahme fehlgeschlagen",
|
|
@@ -93,8 +101,12 @@
|
|
|
93
101
|
"Question": "Frage",
|
|
94
102
|
"Quote": "Zitieren",
|
|
95
103
|
"Recording format is not supported and cannot be reproduced": "Aufnahmeformat wird nicht unterstützt und kann nicht wiedergegeben werden",
|
|
104
|
+
"Remind Me": "Erinnern",
|
|
105
|
+
"Remove reminder": "Erinnerung entfernen",
|
|
96
106
|
"Reply": "Antworten",
|
|
97
107
|
"Reply to Message": "Auf Nachricht antworten",
|
|
108
|
+
"Save for later": "Für später speichern",
|
|
109
|
+
"Saved for later": "Für später gespeichert",
|
|
98
110
|
"Search": "Suche",
|
|
99
111
|
"Searching...": "Suchen...",
|
|
100
112
|
"See all options ({{count}})_one": "Alle Optionen anzeigen ({{count}})",
|
|
@@ -118,6 +130,8 @@
|
|
|
118
130
|
"This message did not meet our content guidelines": "Diese Nachricht entsprach nicht unseren Inhaltsrichtlinien",
|
|
119
131
|
"This message was deleted...": "Diese Nachricht wurde gelöscht...",
|
|
120
132
|
"Thread": "Thread",
|
|
133
|
+
"Thread has not been found": "Thread wurde nicht gefunden",
|
|
134
|
+
"Thread reply": "Thread-Antwort",
|
|
121
135
|
"To start recording, allow the camera access in your browser": "Um mit der Aufnahme zu beginnen, erlauben Sie den Zugriff auf die Kamera in Ihrem Browser",
|
|
122
136
|
"To start recording, allow the microphone access in your browser": "Um mit der Aufnahme zu beginnen, erlauben Sie den Zugriff auf das Mikrofon in Ihrem Browser",
|
|
123
137
|
"Type a number from 2 to 10": "Geben Sie eine Zahl von 2 bis 10 ein",
|
|
@@ -158,6 +172,7 @@
|
|
|
158
172
|
"aria/Open Reaction Selector": "Reaktionsauswahl öffnen",
|
|
159
173
|
"aria/Open Thread": "Thread öffnen",
|
|
160
174
|
"aria/Reaction list": "Reaktionsliste",
|
|
175
|
+
"aria/Remind Me Options": "Erinnerungsoptionen",
|
|
161
176
|
"aria/Remove attachment": "Anhang entfernen",
|
|
162
177
|
"aria/Retry upload": "Upload erneut versuchen",
|
|
163
178
|
"aria/Search results": "Suchergebnisse",
|
|
@@ -166,11 +181,14 @@
|
|
|
166
181
|
"aria/Stop AI Generation": "KI-Generierung stoppen",
|
|
167
182
|
"ban-command-args": "[@Benutzername] [Text]",
|
|
168
183
|
"ban-command-description": "Einen Benutzer verbannen",
|
|
184
|
+
"duration/Message reminder": "{{ milliseconds | durationFormatter(withSuffix: true) }}",
|
|
185
|
+
"duration/Remind Me": "{{ milliseconds | durationFormatter(withSuffix: true) }}",
|
|
169
186
|
"giphy-command-args": "[Text]",
|
|
170
187
|
"giphy-command-description": "Poste ein zufälliges Gif in den Kanal",
|
|
171
188
|
"live": "live",
|
|
172
189
|
"mute-command-args": "[@Benutzername]",
|
|
173
190
|
"mute-command-description": "Stummschalten eines Benutzers",
|
|
191
|
+
"network error": "Netzwerkfehler",
|
|
174
192
|
"replyCount_one": "1 Antwort",
|
|
175
193
|
"replyCount_other": "{{ count }} Antworten",
|
|
176
194
|
"search-results-header-filter-source-button-label--channels": "Kanäle",
|
|
@@ -178,18 +196,23 @@
|
|
|
178
196
|
"search-results-header-filter-source-button-label--users": "Benutzer",
|
|
179
197
|
"searchResultsCount_one": "1 Ergebnis",
|
|
180
198
|
"searchResultsCount_other": "{{ count }} Ergebnisse",
|
|
199
|
+
"size limit": "Größenbeschränkung",
|
|
181
200
|
"this content could not be displayed": "Dieser Inhalt konnte nicht angezeigt werden",
|
|
182
201
|
"timestamp/DateSeparator": "{{ timestamp | timestampFormatter(calendar: true) }}",
|
|
183
202
|
"timestamp/MessageTimestamp": "{{ timestamp | timestampFormatter(calendar: true) }}",
|
|
184
203
|
"timestamp/PollVote": "{{ timestamp | timestampFormatter(format: MMM D [at] HH:mm) }}",
|
|
185
204
|
"timestamp/PollVoteTooltip": "{{ timestamp | timestampFormatter(calendar: true) }}",
|
|
205
|
+
"timestamp/ReminderNotification": "{{ timestamp | timestampFormatter(calendar: true) }}",
|
|
186
206
|
"timestamp/SystemMessage": "{{ timestamp | timestampFormatter(format: dddd L) }}",
|
|
207
|
+
"translationBuilderTopic/notification": "{{value, notification}}",
|
|
187
208
|
"unban-command-args": "[@Benutzername]",
|
|
188
209
|
"unban-command-description": "Einen Benutzer entbannen",
|
|
210
|
+
"unknown error": "Unbekannter Fehler",
|
|
189
211
|
"unmute-command-args": "[@Benutzername]",
|
|
190
212
|
"unmute-command-description": "Stummschaltung eines Benutzers aufheben",
|
|
191
213
|
"unreadMessagesSeparatorText_one": "1 ungelesene Nachricht",
|
|
192
214
|
"unreadMessagesSeparatorText_other": "{{count}} ungelesene Nachrichten",
|
|
215
|
+
"unsupported file type": "Nicht unterstützter Dateityp",
|
|
193
216
|
"{{ commaSeparatedUsers }} and {{ moreCount }} more": "{{ commaSeparatedUsers }} und {{moreCount}} mehr",
|
|
194
217
|
"{{ commaSeparatedUsers }}, and {{ lastUser }}": "{{ commaSeparatedUsers }} und {{ lastUser }}",
|
|
195
218
|
"{{ firstUser }} and {{ secondUser }}": "{{ firstUser }} und {{ secondUser }}",
|