@appsupportkit/support-sdk 0.2.0 → 0.4.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/lib/commonjs/api.js +61 -12
- package/lib/commonjs/api.js.map +1 -1
- package/lib/commonjs/components/BottomSheet.js +1 -1
- package/lib/commonjs/components/BottomSheet.js.map +1 -1
- package/lib/commonjs/components/LauncherButton.js +4 -4
- package/lib/commonjs/components/LauncherButton.js.map +1 -1
- package/lib/commonjs/components/SupportButton.js +192 -66
- package/lib/commonjs/components/SupportButton.js.map +1 -1
- package/lib/commonjs/components/icons.js +117 -110
- package/lib/commonjs/components/icons.js.map +1 -1
- package/lib/commonjs/components/primitives.js +3 -154
- package/lib/commonjs/components/primitives.js.map +1 -1
- package/lib/commonjs/components/screens/ChatScreen.js +487 -0
- package/lib/commonjs/components/screens/ChatScreen.js.map +1 -0
- package/lib/commonjs/components/screens/LanguageScreen.js +150 -0
- package/lib/commonjs/components/screens/LanguageScreen.js.map +1 -0
- package/lib/commonjs/i18n/index.js +101 -0
- package/lib/commonjs/i18n/index.js.map +1 -0
- package/lib/commonjs/i18n/languages.js +95 -0
- package/lib/commonjs/i18n/languages.js.map +1 -0
- package/lib/commonjs/i18n/strings/de.js +75 -0
- package/lib/commonjs/i18n/strings/de.js.map +1 -0
- package/lib/commonjs/i18n/strings/en.js +91 -0
- package/lib/commonjs/i18n/strings/en.js.map +1 -0
- package/lib/commonjs/i18n/strings/es.js +75 -0
- package/lib/commonjs/i18n/strings/es.js.map +1 -0
- package/lib/commonjs/i18n/strings/fr.js +75 -0
- package/lib/commonjs/i18n/strings/fr.js.map +1 -0
- package/lib/commonjs/i18n/strings/hi.js +75 -0
- package/lib/commonjs/i18n/strings/hi.js.map +1 -0
- package/lib/commonjs/i18n/strings/it.js +75 -0
- package/lib/commonjs/i18n/strings/it.js.map +1 -0
- package/lib/commonjs/i18n/strings/ja.js +75 -0
- package/lib/commonjs/i18n/strings/ja.js.map +1 -0
- package/lib/commonjs/i18n/strings/ko.js +75 -0
- package/lib/commonjs/i18n/strings/ko.js.map +1 -0
- package/lib/commonjs/i18n/strings/nl.js +75 -0
- package/lib/commonjs/i18n/strings/nl.js.map +1 -0
- package/lib/commonjs/i18n/strings/pl.js +75 -0
- package/lib/commonjs/i18n/strings/pl.js.map +1 -0
- package/lib/commonjs/i18n/strings/pt.js +75 -0
- package/lib/commonjs/i18n/strings/pt.js.map +1 -0
- package/lib/commonjs/i18n/strings/ru.js +75 -0
- package/lib/commonjs/i18n/strings/ru.js.map +1 -0
- package/lib/commonjs/i18n/strings/tr.js +75 -0
- package/lib/commonjs/i18n/strings/tr.js.map +1 -0
- package/lib/commonjs/i18n/strings/zh.js +75 -0
- package/lib/commonjs/i18n/strings/zh.js.map +1 -0
- package/lib/commonjs/index.js +38 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/push.js +78 -3
- package/lib/commonjs/push.js.map +1 -1
- package/lib/commonjs/review.js +54 -0
- package/lib/commonjs/review.js.map +1 -0
- package/lib/commonjs/theme.js +142 -23
- package/lib/commonjs/theme.js.map +1 -1
- package/lib/commonjs/types.js +32 -3
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/useSupportThreads.js +41 -24
- package/lib/commonjs/useSupportThreads.js.map +1 -1
- package/lib/commonjs/utils.js +25 -30
- package/lib/commonjs/utils.js.map +1 -1
- package/lib/commonjs/version.js +13 -0
- package/lib/commonjs/version.js.map +1 -0
- package/lib/module/api.js +57 -10
- package/lib/module/api.js.map +1 -1
- package/lib/module/components/BottomSheet.js +1 -1
- package/lib/module/components/BottomSheet.js.map +1 -1
- package/lib/module/components/LauncherButton.js +5 -5
- package/lib/module/components/LauncherButton.js.map +1 -1
- package/lib/module/components/SupportButton.js +199 -73
- package/lib/module/components/SupportButton.js.map +1 -1
- package/lib/module/components/icons.js +115 -107
- package/lib/module/components/icons.js.map +1 -1
- package/lib/module/components/primitives.js +5 -147
- package/lib/module/components/primitives.js.map +1 -1
- package/lib/module/components/screens/ChatScreen.js +485 -0
- package/lib/module/components/screens/ChatScreen.js.map +1 -0
- package/lib/module/components/screens/LanguageScreen.js +147 -0
- package/lib/module/components/screens/LanguageScreen.js.map +1 -0
- package/lib/module/i18n/index.js +56 -0
- package/lib/module/i18n/index.js.map +1 -0
- package/lib/module/i18n/languages.js +88 -0
- package/lib/module/i18n/languages.js.map +1 -0
- package/lib/module/i18n/strings/de.js +71 -0
- package/lib/module/i18n/strings/de.js.map +1 -0
- package/lib/module/i18n/strings/en.js +87 -0
- package/lib/module/i18n/strings/en.js.map +1 -0
- package/lib/module/i18n/strings/es.js +71 -0
- package/lib/module/i18n/strings/es.js.map +1 -0
- package/lib/module/i18n/strings/fr.js +71 -0
- package/lib/module/i18n/strings/fr.js.map +1 -0
- package/lib/module/i18n/strings/hi.js +71 -0
- package/lib/module/i18n/strings/hi.js.map +1 -0
- package/lib/module/i18n/strings/it.js +71 -0
- package/lib/module/i18n/strings/it.js.map +1 -0
- package/lib/module/i18n/strings/ja.js +71 -0
- package/lib/module/i18n/strings/ja.js.map +1 -0
- package/lib/module/i18n/strings/ko.js +71 -0
- package/lib/module/i18n/strings/ko.js.map +1 -0
- package/lib/module/i18n/strings/nl.js +71 -0
- package/lib/module/i18n/strings/nl.js.map +1 -0
- package/lib/module/i18n/strings/pl.js +71 -0
- package/lib/module/i18n/strings/pl.js.map +1 -0
- package/lib/module/i18n/strings/pt.js +71 -0
- package/lib/module/i18n/strings/pt.js.map +1 -0
- package/lib/module/i18n/strings/ru.js +71 -0
- package/lib/module/i18n/strings/ru.js.map +1 -0
- package/lib/module/i18n/strings/tr.js +71 -0
- package/lib/module/i18n/strings/tr.js.map +1 -0
- package/lib/module/i18n/strings/zh.js +71 -0
- package/lib/module/i18n/strings/zh.js.map +1 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/push.js +77 -3
- package/lib/module/push.js.map +1 -1
- package/lib/module/review.js +48 -0
- package/lib/module/review.js.map +1 -0
- package/lib/module/theme.js +141 -23
- package/lib/module/theme.js.map +1 -1
- package/lib/module/types.js +32 -3
- package/lib/module/types.js.map +1 -1
- package/lib/module/useSupportThreads.js +41 -24
- package/lib/module/useSupportThreads.js.map +1 -1
- package/lib/module/utils.js +24 -29
- package/lib/module/utils.js.map +1 -1
- package/lib/module/version.js +9 -0
- package/lib/module/version.js.map +1 -0
- package/lib/typescript/api.d.ts +40 -10
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/components/SupportButton.d.ts +2 -2
- package/lib/typescript/components/SupportButton.d.ts.map +1 -1
- package/lib/typescript/components/icons.d.ts +10 -14
- package/lib/typescript/components/icons.d.ts.map +1 -1
- package/lib/typescript/components/primitives.d.ts +3 -30
- package/lib/typescript/components/primitives.d.ts.map +1 -1
- package/lib/typescript/components/screens/ChatScreen.d.ts +21 -0
- package/lib/typescript/components/screens/ChatScreen.d.ts.map +1 -0
- package/lib/typescript/components/screens/LanguageScreen.d.ts +30 -0
- package/lib/typescript/components/screens/LanguageScreen.d.ts.map +1 -0
- package/lib/typescript/i18n/index.d.ts +15 -0
- package/lib/typescript/i18n/index.d.ts.map +1 -0
- package/lib/typescript/i18n/languages.d.ts +36 -0
- package/lib/typescript/i18n/languages.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/de.d.ts +3 -0
- package/lib/typescript/i18n/strings/de.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/en.d.ts +86 -0
- package/lib/typescript/i18n/strings/en.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/es.d.ts +3 -0
- package/lib/typescript/i18n/strings/es.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/fr.d.ts +3 -0
- package/lib/typescript/i18n/strings/fr.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/hi.d.ts +3 -0
- package/lib/typescript/i18n/strings/hi.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/it.d.ts +3 -0
- package/lib/typescript/i18n/strings/it.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/ja.d.ts +3 -0
- package/lib/typescript/i18n/strings/ja.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/ko.d.ts +3 -0
- package/lib/typescript/i18n/strings/ko.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/nl.d.ts +3 -0
- package/lib/typescript/i18n/strings/nl.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/pl.d.ts +3 -0
- package/lib/typescript/i18n/strings/pl.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/pt.d.ts +3 -0
- package/lib/typescript/i18n/strings/pt.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/ru.d.ts +3 -0
- package/lib/typescript/i18n/strings/ru.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/tr.d.ts +3 -0
- package/lib/typescript/i18n/strings/tr.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/zh.d.ts +3 -0
- package/lib/typescript/i18n/strings/zh.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +4 -2
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/push.d.ts +14 -2
- package/lib/typescript/push.d.ts.map +1 -1
- package/lib/typescript/review.d.ts +15 -0
- package/lib/typescript/review.d.ts.map +1 -0
- package/lib/typescript/theme.d.ts +23 -5
- package/lib/typescript/theme.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +86 -13
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/useSupportThreads.d.ts +20 -4
- package/lib/typescript/useSupportThreads.d.ts.map +1 -1
- package/lib/typescript/utils.d.ts +8 -6
- package/lib/typescript/utils.d.ts.map +1 -1
- package/lib/typescript/version.d.ts +7 -0
- package/lib/typescript/version.d.ts.map +1 -0
- package/package.json +2 -2
- package/src/api.ts +75 -23
- package/src/components/BottomSheet.tsx +1 -1
- package/src/components/LauncherButton.tsx +4 -4
- package/src/components/SupportButton.tsx +244 -86
- package/src/components/icons.tsx +96 -101
- package/src/components/primitives.tsx +9 -161
- package/src/components/screens/ChatScreen.tsx +541 -0
- package/src/components/screens/LanguageScreen.tsx +172 -0
- package/src/i18n/index.ts +81 -0
- package/src/i18n/languages.ts +106 -0
- package/src/i18n/strings/de.ts +81 -0
- package/src/i18n/strings/en.ts +97 -0
- package/src/i18n/strings/es.ts +80 -0
- package/src/i18n/strings/fr.ts +81 -0
- package/src/i18n/strings/hi.ts +80 -0
- package/src/i18n/strings/it.ts +80 -0
- package/src/i18n/strings/ja.ts +80 -0
- package/src/i18n/strings/ko.ts +79 -0
- package/src/i18n/strings/nl.ts +80 -0
- package/src/i18n/strings/pl.ts +80 -0
- package/src/i18n/strings/pt.ts +80 -0
- package/src/i18n/strings/ru.ts +80 -0
- package/src/i18n/strings/tr.ts +80 -0
- package/src/i18n/strings/zh.ts +78 -0
- package/src/index.tsx +13 -0
- package/src/push.ts +100 -2
- package/src/review.ts +54 -0
- package/src/theme.ts +182 -28
- package/src/types.ts +85 -13
- package/src/useSupportThreads.ts +61 -28
- package/src/utils.ts +27 -29
- package/src/version.ts +6 -0
- package/lib/commonjs/components/screens/ComposeScreen.js +0 -228
- package/lib/commonjs/components/screens/ComposeScreen.js.map +0 -1
- package/lib/commonjs/components/screens/HomeScreen.js +0 -286
- package/lib/commonjs/components/screens/HomeScreen.js.map +0 -1
- package/lib/commonjs/components/screens/ThreadScreen.js +0 -327
- package/lib/commonjs/components/screens/ThreadScreen.js.map +0 -1
- package/lib/module/components/screens/ComposeScreen.js +0 -224
- package/lib/module/components/screens/ComposeScreen.js.map +0 -1
- package/lib/module/components/screens/HomeScreen.js +0 -282
- package/lib/module/components/screens/HomeScreen.js.map +0 -1
- package/lib/module/components/screens/ThreadScreen.js +0 -325
- package/lib/module/components/screens/ThreadScreen.js.map +0 -1
- package/lib/typescript/components/screens/ComposeScreen.d.ts +0 -10
- package/lib/typescript/components/screens/ComposeScreen.d.ts.map +0 -1
- package/lib/typescript/components/screens/HomeScreen.d.ts +0 -14
- package/lib/typescript/components/screens/HomeScreen.d.ts.map +0 -1
- package/lib/typescript/components/screens/ThreadScreen.d.ts +0 -10
- package/lib/typescript/components/screens/ThreadScreen.d.ts.map +0 -1
- package/src/components/screens/ComposeScreen.tsx +0 -233
- package/src/components/screens/HomeScreen.tsx +0 -287
- package/src/components/screens/ThreadScreen.tsx +0 -397
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// UI copy, in the user's language.
|
|
2
|
+
//
|
|
3
|
+
// Message bodies are translated by the backend at write time; the sheet's own
|
|
4
|
+
// chrome is not — it is a fixed set of strings that never changes, so it ships
|
|
5
|
+
// as a bundled table. A model call to render the word "Send" would be absurd,
|
|
6
|
+
// and it would also mean the SDK couldn't draw its own UI offline.
|
|
7
|
+
|
|
8
|
+
import { DEFAULT_LANGUAGE, type Language } from './languages';
|
|
9
|
+
import { en, type StringKey, type StringTable } from './strings/en';
|
|
10
|
+
import { de } from './strings/de';
|
|
11
|
+
import { es } from './strings/es';
|
|
12
|
+
import { fr } from './strings/fr';
|
|
13
|
+
import { hi } from './strings/hi';
|
|
14
|
+
import { it } from './strings/it';
|
|
15
|
+
import { ja } from './strings/ja';
|
|
16
|
+
import { ko } from './strings/ko';
|
|
17
|
+
import { nl } from './strings/nl';
|
|
18
|
+
import { pl } from './strings/pl';
|
|
19
|
+
import { pt } from './strings/pt';
|
|
20
|
+
import { ru } from './strings/ru';
|
|
21
|
+
import { tr } from './strings/tr';
|
|
22
|
+
import { zh } from './strings/zh';
|
|
23
|
+
|
|
24
|
+
const TABLES: Record<Language, StringTable> = {
|
|
25
|
+
en,
|
|
26
|
+
es,
|
|
27
|
+
fr,
|
|
28
|
+
de,
|
|
29
|
+
nl,
|
|
30
|
+
pt,
|
|
31
|
+
it,
|
|
32
|
+
pl,
|
|
33
|
+
tr,
|
|
34
|
+
ru,
|
|
35
|
+
ja,
|
|
36
|
+
ko,
|
|
37
|
+
zh,
|
|
38
|
+
hi,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/** Fills `{name}` placeholders. Unknown tokens are left alone, not blanked. */
|
|
42
|
+
function format(
|
|
43
|
+
template: string,
|
|
44
|
+
vars?: Record<string, string | number>,
|
|
45
|
+
): string {
|
|
46
|
+
if (!vars) return template;
|
|
47
|
+
return template.replace(/\{(\w+)\}/g, (match, key: string) =>
|
|
48
|
+
key in vars ? String(vars[key]) : match,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface Translator {
|
|
53
|
+
language: Language;
|
|
54
|
+
/**
|
|
55
|
+
* BCP-47 tag for Intl — dates and times stay in the user's chosen language
|
|
56
|
+
* rather than the device's, so a sheet never mixes the two.
|
|
57
|
+
*/
|
|
58
|
+
locale: string;
|
|
59
|
+
t: (key: StringKey, vars?: Record<string, string | number>) => string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function createTranslator(language: Language): Translator {
|
|
63
|
+
const table = TABLES[language] ?? TABLES[DEFAULT_LANGUAGE];
|
|
64
|
+
return {
|
|
65
|
+
language,
|
|
66
|
+
locale: language,
|
|
67
|
+
t: (key, vars) => format(table[key] ?? en[key], vars),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export type { StringKey, StringTable };
|
|
72
|
+
export {
|
|
73
|
+
asLanguage,
|
|
74
|
+
baseLanguage,
|
|
75
|
+
DEFAULT_LANGUAGE,
|
|
76
|
+
deviceLanguage,
|
|
77
|
+
isSupportedLanguage,
|
|
78
|
+
LANGUAGE_LABELS,
|
|
79
|
+
SUPPORTED_LANGUAGES,
|
|
80
|
+
type Language,
|
|
81
|
+
} from './languages';
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { NativeModules, Platform } from 'react-native';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The languages the picker offers.
|
|
5
|
+
*
|
|
6
|
+
* Kept in sync by hand with supabase/functions/_shared/languages.ts — the two
|
|
7
|
+
* run in different runtimes and share no build step. Adding one means adding a
|
|
8
|
+
* string table here too, which the compiler enforces.
|
|
9
|
+
*
|
|
10
|
+
* Right-to-left languages are deliberately absent for now: React Native only
|
|
11
|
+
* flips layout direction through I18nManager, which needs an app restart the
|
|
12
|
+
* SDK has no business triggering inside a host app.
|
|
13
|
+
*/
|
|
14
|
+
export const SUPPORTED_LANGUAGES = [
|
|
15
|
+
'en',
|
|
16
|
+
'es',
|
|
17
|
+
'fr',
|
|
18
|
+
'de',
|
|
19
|
+
'nl',
|
|
20
|
+
'pt',
|
|
21
|
+
'it',
|
|
22
|
+
'pl',
|
|
23
|
+
'tr',
|
|
24
|
+
'ru',
|
|
25
|
+
'ja',
|
|
26
|
+
'ko',
|
|
27
|
+
'zh',
|
|
28
|
+
'hi',
|
|
29
|
+
] as const;
|
|
30
|
+
|
|
31
|
+
export type Language = (typeof SUPPORTED_LANGUAGES)[number];
|
|
32
|
+
|
|
33
|
+
/** The language the support team reads and writes. */
|
|
34
|
+
export const DEFAULT_LANGUAGE: Language = 'en';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Endonyms — a language is listed the way its own speakers write it, so the
|
|
38
|
+
* picker is readable to someone who can't read the current UI language.
|
|
39
|
+
*/
|
|
40
|
+
export const LANGUAGE_LABELS: Record<Language, string> = {
|
|
41
|
+
en: 'English',
|
|
42
|
+
es: 'Español',
|
|
43
|
+
fr: 'Français',
|
|
44
|
+
de: 'Deutsch',
|
|
45
|
+
nl: 'Nederlands',
|
|
46
|
+
pt: 'Português',
|
|
47
|
+
it: 'Italiano',
|
|
48
|
+
pl: 'Polski',
|
|
49
|
+
tr: 'Türkçe',
|
|
50
|
+
ru: 'Русский',
|
|
51
|
+
ja: '日本語',
|
|
52
|
+
ko: '한국어',
|
|
53
|
+
zh: '简体中文',
|
|
54
|
+
hi: 'हिन्दी',
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/** Strips a region qualifier: "pt-BR" → "pt". */
|
|
58
|
+
export function baseLanguage(code: string): string {
|
|
59
|
+
return code.trim().toLowerCase().split(/[-_]/)[0] ?? '';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function isSupportedLanguage(code: string): code is Language {
|
|
63
|
+
return (SUPPORTED_LANGUAGES as readonly string[]).includes(baseLanguage(code));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Narrows any string to a supported language, or null. */
|
|
67
|
+
export function asLanguage(code: string | null | undefined): Language | null {
|
|
68
|
+
if (!code) return null;
|
|
69
|
+
const base = baseLanguage(code);
|
|
70
|
+
return isSupportedLanguage(base) ? base : null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function rawDeviceLocale(): string | null {
|
|
74
|
+
try {
|
|
75
|
+
if (Platform.OS === 'ios') {
|
|
76
|
+
const settings = NativeModules.SettingsManager?.settings;
|
|
77
|
+
const locale = settings?.AppleLocale ?? settings?.AppleLanguages?.[0];
|
|
78
|
+
if (typeof locale === 'string') return locale;
|
|
79
|
+
} else {
|
|
80
|
+
const locale = NativeModules.I18nManager?.localeIdentifier;
|
|
81
|
+
if (typeof locale === 'string') return locale;
|
|
82
|
+
}
|
|
83
|
+
} catch {
|
|
84
|
+
// Fall through to Intl.
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
return Intl.DateTimeFormat().resolvedOptions().locale;
|
|
89
|
+
} catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The device's language, if the SDK supports it.
|
|
96
|
+
*
|
|
97
|
+
* Used to pre-select a row in the picker and to render the picker itself, so
|
|
98
|
+
* the one screen shown before we know the user's choice is already in a
|
|
99
|
+
* language they probably read. Deliberately not used to *skip* the picker: a
|
|
100
|
+
* device set to French says nothing about which language its owner wants to
|
|
101
|
+
* write support messages in.
|
|
102
|
+
*/
|
|
103
|
+
export function deviceLanguage(): Language | null {
|
|
104
|
+
const locale = rawDeviceLocale();
|
|
105
|
+
return locale === null ? null : asLanguage(locale);
|
|
106
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { StringTable } from './en';
|
|
2
|
+
|
|
3
|
+
export const de: StringTable = {
|
|
4
|
+
'home.title': 'Support',
|
|
5
|
+
'home.subtitle': 'Starte ein Gespräch — wir antworten direkt hier.',
|
|
6
|
+
'home.close': 'Support schließen',
|
|
7
|
+
'home.open': 'Offen',
|
|
8
|
+
'home.resolved': 'Erledigt',
|
|
9
|
+
'home.empty': 'Noch keine Gespräche',
|
|
10
|
+
'home.emptyHint':
|
|
11
|
+
'Alles, was du sendest, landet beim Team, und die Antworten kommen in dieses Fenster zurück.',
|
|
12
|
+
'home.noMessages': 'Noch keine Nachrichten',
|
|
13
|
+
'home.you': 'Du',
|
|
14
|
+
'home.threadA11y': 'Gespräch: {type}',
|
|
15
|
+
'home.threadUnreadA11y': 'Gespräch: {type}, {count} ungelesen',
|
|
16
|
+
'home.newA11y': 'Neu: {type}',
|
|
17
|
+
'home.language': 'Sprache',
|
|
18
|
+
|
|
19
|
+
'type.feedback': 'Feedback',
|
|
20
|
+
'type.feature_request': 'Funktionswunsch',
|
|
21
|
+
'type.bug_report': 'Fehlerbericht',
|
|
22
|
+
'hint.feedback': 'Sag uns, was du denkst',
|
|
23
|
+
'hint.feature_request': 'Schlage eine Verbesserung vor',
|
|
24
|
+
'hint.bug_report': 'Etwas funktioniert nicht',
|
|
25
|
+
'prompt.feedback': 'Was sollten wir wissen?',
|
|
26
|
+
'prompt.feature_request': 'Was würdest du dir wünschen?',
|
|
27
|
+
'prompt.bug_report': 'Was ist passiert, und was hattest du erwartet?',
|
|
28
|
+
'sub.feedback': 'Gut oder schlecht — es geht direkt ans Team.',
|
|
29
|
+
'sub.feature_request': 'Sag uns, was du erreichen möchtest.',
|
|
30
|
+
'sub.bug_report':
|
|
31
|
+
'Schritte, Bildschirm und deine Erwartung helfen uns weiter.',
|
|
32
|
+
|
|
33
|
+
'compose.back': 'Zurück zu den Gesprächen',
|
|
34
|
+
'compose.sent': 'Gesendet',
|
|
35
|
+
'compose.sentHint':
|
|
36
|
+
'Wir antworten direkt hier. Du findest das Gespräch unter Offen, und der Button zeigt ein Abzeichen, sobald wir geantwortet haben.',
|
|
37
|
+
'compose.done': 'Fertig',
|
|
38
|
+
'compose.send': 'Senden',
|
|
39
|
+
'compose.sending': 'Wird gesendet…',
|
|
40
|
+
'compose.minChars': 'Mindestens {count} Zeichen',
|
|
41
|
+
|
|
42
|
+
'thread.support': 'Support',
|
|
43
|
+
'thread.new': 'Neu',
|
|
44
|
+
'thread.resolvedAt': 'Erledigt · {date}',
|
|
45
|
+
'thread.readOnly': 'Dieses Gespräch ist erledigt und schreibgeschützt',
|
|
46
|
+
'thread.placeholder': 'Antwort schreiben…',
|
|
47
|
+
'chat.placeholder': 'Nachricht schreiben…',
|
|
48
|
+
'review.appStore': 'Im App Store bewerten',
|
|
49
|
+
'review.playStore': 'Bei Google Play bewerten',
|
|
50
|
+
'thread.sendA11y': 'Antwort senden',
|
|
51
|
+
'thread.sendingA11y': 'Wird gesendet',
|
|
52
|
+
'thread.translating': 'Wird übersetzt…',
|
|
53
|
+
|
|
54
|
+
'status.open': 'Offen',
|
|
55
|
+
'status.resolved': 'Erledigt',
|
|
56
|
+
|
|
57
|
+
'error.tryAgain': 'Erneut versuchen',
|
|
58
|
+
'error.rateLimited': 'Zu viele Anfragen — versuche es später noch einmal',
|
|
59
|
+
'error.offline': 'Du bist offline — prüfe deine Verbindung',
|
|
60
|
+
'error.sendFailed': 'Senden fehlgeschlagen — versuche es noch einmal',
|
|
61
|
+
'error.loadFailed': 'Deine Gespräche konnten nicht geladen werden',
|
|
62
|
+
'error.unavailable': 'Der Support ist gerade nicht verfügbar',
|
|
63
|
+
'error.loadRateLimited': 'Zu viele Anfragen — versuche es gleich noch einmal',
|
|
64
|
+
|
|
65
|
+
'lang.title': 'Wähle deine Sprache',
|
|
66
|
+
'lang.subtitle':
|
|
67
|
+
'Schreib in der Sprache, die dir liegt — wir übersetzen zwischen dir und dem Support-Team.',
|
|
68
|
+
'lang.continue': 'Weiter',
|
|
69
|
+
'lang.change': 'Sprache ändern',
|
|
70
|
+
'lang.saveFailed': 'Speichern fehlgeschlagen — versuche es noch einmal',
|
|
71
|
+
|
|
72
|
+
'time.justNow': 'gerade eben',
|
|
73
|
+
'time.minutes': 'vor {count} Min.',
|
|
74
|
+
'time.hours': 'vor {count} Std.',
|
|
75
|
+
'time.days': 'vor {count} T.',
|
|
76
|
+
'time.weeks': 'vor {count} Wo.',
|
|
77
|
+
'time.months': 'vor {count} Mon.',
|
|
78
|
+
'time.years': 'vor {count} J.',
|
|
79
|
+
'time.today': 'Heute',
|
|
80
|
+
'time.yesterday': 'Gestern',
|
|
81
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* English is the source table: every other language is typed against it, so a
|
|
3
|
+
* missing or misspelled key fails the build rather than falling back silently
|
|
4
|
+
* at runtime.
|
|
5
|
+
*
|
|
6
|
+
* Placeholders are `{name}` tokens filled in by `format()` — the table stays
|
|
7
|
+
* pure data so it can be handed to a translator (or lifted to JSON) without
|
|
8
|
+
* touching code.
|
|
9
|
+
*
|
|
10
|
+
* Keys that read identically in English are still separate when their context
|
|
11
|
+
* differs: `home.open` labels a section of several threads, `status.open`
|
|
12
|
+
* labels one thread's state, and plenty of languages inflect those
|
|
13
|
+
* differently.
|
|
14
|
+
*/
|
|
15
|
+
export const en = {
|
|
16
|
+
'home.title': 'Support',
|
|
17
|
+
'home.subtitle': 'Start a conversation — we reply right here.',
|
|
18
|
+
'home.close': 'Close support',
|
|
19
|
+
'home.open': 'Open',
|
|
20
|
+
'home.resolved': 'Resolved',
|
|
21
|
+
'home.empty': 'No conversations yet',
|
|
22
|
+
'home.emptyHint':
|
|
23
|
+
'Anything you send lands with the team, and their replies come back to this sheet.',
|
|
24
|
+
'home.noMessages': 'No messages yet',
|
|
25
|
+
'home.you': 'You',
|
|
26
|
+
'home.threadA11y': '{type} thread',
|
|
27
|
+
'home.threadUnreadA11y': '{type} thread, {count} unread',
|
|
28
|
+
'home.newA11y': 'New {type}',
|
|
29
|
+
'home.language': 'Language',
|
|
30
|
+
|
|
31
|
+
'type.feedback': 'Feedback',
|
|
32
|
+
'type.feature_request': 'Feature request',
|
|
33
|
+
'type.bug_report': 'Bug report',
|
|
34
|
+
'hint.feedback': 'Tell us what you think',
|
|
35
|
+
'hint.feature_request': 'Suggest an improvement',
|
|
36
|
+
'hint.bug_report': "Something isn't working",
|
|
37
|
+
'prompt.feedback': 'What should we know?',
|
|
38
|
+
'prompt.feature_request': 'What would you like to see?',
|
|
39
|
+
'prompt.bug_report': 'What happened, and what did you expect?',
|
|
40
|
+
'sub.feedback': 'Good or bad — it goes straight to the team.',
|
|
41
|
+
'sub.feature_request': 'Tell us what you are trying to do.',
|
|
42
|
+
'sub.bug_report': 'Steps, screen, and what you expected all help.',
|
|
43
|
+
|
|
44
|
+
'compose.back': 'Back to conversations',
|
|
45
|
+
'compose.sent': 'Sent',
|
|
46
|
+
'compose.sentHint':
|
|
47
|
+
"We'll reply right here. You'll find the conversation under Open, and the button shows a badge when we answer.",
|
|
48
|
+
'compose.done': 'Done',
|
|
49
|
+
'compose.send': 'Send',
|
|
50
|
+
'compose.sending': 'Sending…',
|
|
51
|
+
'compose.minChars': 'At least {count} characters',
|
|
52
|
+
|
|
53
|
+
'thread.support': 'Support',
|
|
54
|
+
'thread.new': 'New',
|
|
55
|
+
'thread.resolvedAt': 'Resolved · {date}',
|
|
56
|
+
'thread.readOnly': 'This conversation is resolved and read-only',
|
|
57
|
+
'thread.placeholder': 'Write a reply…',
|
|
58
|
+
'chat.placeholder': 'Write a message…',
|
|
59
|
+
'review.appStore': 'Rate on the App Store',
|
|
60
|
+
'review.playStore': 'Rate on Google Play',
|
|
61
|
+
'thread.sendA11y': 'Send reply',
|
|
62
|
+
'thread.sendingA11y': 'Sending',
|
|
63
|
+
'thread.translating': 'Translating…',
|
|
64
|
+
|
|
65
|
+
'status.open': 'Open',
|
|
66
|
+
'status.resolved': 'Resolved',
|
|
67
|
+
|
|
68
|
+
'error.tryAgain': 'Try again',
|
|
69
|
+
'error.rateLimited': 'Too many requests — try again later',
|
|
70
|
+
'error.offline': "You're offline — check your connection",
|
|
71
|
+
'error.sendFailed': "Couldn't send — try again",
|
|
72
|
+
'error.loadFailed': "Couldn't load your conversations",
|
|
73
|
+
'error.unavailable': 'Support is unavailable right now',
|
|
74
|
+
'error.loadRateLimited': 'Too many requests — try again in a bit',
|
|
75
|
+
|
|
76
|
+
'lang.title': 'Choose your language',
|
|
77
|
+
'lang.subtitle':
|
|
78
|
+
'Write in whichever language you prefer — we translate between you and the support team.',
|
|
79
|
+
'lang.continue': 'Continue',
|
|
80
|
+
'lang.change': 'Change language',
|
|
81
|
+
'lang.saveFailed': "Couldn't save — try again",
|
|
82
|
+
|
|
83
|
+
'time.justNow': 'just now',
|
|
84
|
+
'time.minutes': '{count}m ago',
|
|
85
|
+
'time.hours': '{count}h ago',
|
|
86
|
+
'time.days': '{count}d ago',
|
|
87
|
+
'time.weeks': '{count}w ago',
|
|
88
|
+
'time.months': '{count}mo ago',
|
|
89
|
+
'time.years': '{count}y ago',
|
|
90
|
+
'time.today': 'Today',
|
|
91
|
+
'time.yesterday': 'Yesterday',
|
|
92
|
+
} as const;
|
|
93
|
+
|
|
94
|
+
export type StringKey = keyof typeof en;
|
|
95
|
+
|
|
96
|
+
/** Every language provides every key — enforced at compile time. */
|
|
97
|
+
export type StringTable = Record<StringKey, string>;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { StringTable } from './en';
|
|
2
|
+
|
|
3
|
+
export const es: StringTable = {
|
|
4
|
+
'home.title': 'Soporte',
|
|
5
|
+
'home.subtitle': 'Inicia una conversación: te respondemos aquí mismo.',
|
|
6
|
+
'home.close': 'Cerrar soporte',
|
|
7
|
+
'home.open': 'Abiertas',
|
|
8
|
+
'home.resolved': 'Resueltas',
|
|
9
|
+
'home.empty': 'Aún no hay conversaciones',
|
|
10
|
+
'home.emptyHint':
|
|
11
|
+
'Todo lo que envíes llega al equipo, y sus respuestas vuelven a esta ventana.',
|
|
12
|
+
'home.noMessages': 'Aún no hay mensajes',
|
|
13
|
+
'home.you': 'Tú',
|
|
14
|
+
'home.threadA11y': 'Conversación de {type}',
|
|
15
|
+
'home.threadUnreadA11y': 'Conversación de {type}, {count} sin leer',
|
|
16
|
+
'home.newA11y': 'Nuevo: {type}',
|
|
17
|
+
'home.language': 'Idioma',
|
|
18
|
+
|
|
19
|
+
'type.feedback': 'Comentarios',
|
|
20
|
+
'type.feature_request': 'Sugerencia',
|
|
21
|
+
'type.bug_report': 'Informe de error',
|
|
22
|
+
'hint.feedback': 'Cuéntanos qué opinas',
|
|
23
|
+
'hint.feature_request': 'Propón una mejora',
|
|
24
|
+
'hint.bug_report': 'Algo no funciona',
|
|
25
|
+
'prompt.feedback': '¿Qué deberíamos saber?',
|
|
26
|
+
'prompt.feature_request': '¿Qué te gustaría ver?',
|
|
27
|
+
'prompt.bug_report': '¿Qué pasó y qué esperabas?',
|
|
28
|
+
'sub.feedback': 'Bueno o malo: va directo al equipo.',
|
|
29
|
+
'sub.feature_request': 'Cuéntanos qué intentas hacer.',
|
|
30
|
+
'sub.bug_report': 'Los pasos, la pantalla y lo que esperabas ayudan.',
|
|
31
|
+
|
|
32
|
+
'compose.back': 'Volver a las conversaciones',
|
|
33
|
+
'compose.sent': 'Enviado',
|
|
34
|
+
'compose.sentHint':
|
|
35
|
+
'Te responderemos aquí mismo. Encontrarás la conversación en Abiertas, y el botón muestra un aviso cuando contestemos.',
|
|
36
|
+
'compose.done': 'Listo',
|
|
37
|
+
'compose.send': 'Enviar',
|
|
38
|
+
'compose.sending': 'Enviando…',
|
|
39
|
+
'compose.minChars': 'Al menos {count} caracteres',
|
|
40
|
+
|
|
41
|
+
'thread.support': 'Soporte',
|
|
42
|
+
'thread.new': 'Nuevo',
|
|
43
|
+
'thread.resolvedAt': 'Resuelta · {date}',
|
|
44
|
+
'thread.readOnly': 'Esta conversación está resuelta y es de solo lectura',
|
|
45
|
+
'thread.placeholder': 'Escribe una respuesta…',
|
|
46
|
+
'chat.placeholder': 'Escribe un mensaje…',
|
|
47
|
+
'review.appStore': 'Valorar en la App Store',
|
|
48
|
+
'review.playStore': 'Valorar en Google Play',
|
|
49
|
+
'thread.sendA11y': 'Enviar respuesta',
|
|
50
|
+
'thread.sendingA11y': 'Enviando',
|
|
51
|
+
'thread.translating': 'Traduciendo…',
|
|
52
|
+
|
|
53
|
+
'status.open': 'Abierta',
|
|
54
|
+
'status.resolved': 'Resuelta',
|
|
55
|
+
|
|
56
|
+
'error.tryAgain': 'Reintentar',
|
|
57
|
+
'error.rateLimited': 'Demasiadas solicitudes: inténtalo más tarde',
|
|
58
|
+
'error.offline': 'Sin conexión: revisa tu red',
|
|
59
|
+
'error.sendFailed': 'No se pudo enviar: inténtalo de nuevo',
|
|
60
|
+
'error.loadFailed': 'No se pudieron cargar tus conversaciones',
|
|
61
|
+
'error.unavailable': 'El soporte no está disponible ahora mismo',
|
|
62
|
+
'error.loadRateLimited': 'Demasiadas solicitudes: inténtalo en un momento',
|
|
63
|
+
|
|
64
|
+
'lang.title': 'Elige tu idioma',
|
|
65
|
+
'lang.subtitle':
|
|
66
|
+
'Escribe en el idioma que prefieras: traducimos entre tú y el equipo de soporte.',
|
|
67
|
+
'lang.continue': 'Continuar',
|
|
68
|
+
'lang.change': 'Cambiar idioma',
|
|
69
|
+
'lang.saveFailed': 'No se pudo guardar: inténtalo de nuevo',
|
|
70
|
+
|
|
71
|
+
'time.justNow': 'ahora mismo',
|
|
72
|
+
'time.minutes': 'hace {count} min',
|
|
73
|
+
'time.hours': 'hace {count} h',
|
|
74
|
+
'time.days': 'hace {count} d',
|
|
75
|
+
'time.weeks': 'hace {count} sem',
|
|
76
|
+
'time.months': 'hace {count} meses',
|
|
77
|
+
'time.years': 'hace {count} años',
|
|
78
|
+
'time.today': 'Hoy',
|
|
79
|
+
'time.yesterday': 'Ayer',
|
|
80
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { StringTable } from './en';
|
|
2
|
+
|
|
3
|
+
export const fr: StringTable = {
|
|
4
|
+
'home.title': 'Assistance',
|
|
5
|
+
'home.subtitle': 'Démarrez une conversation — nous répondons ici même.',
|
|
6
|
+
'home.close': "Fermer l'assistance",
|
|
7
|
+
'home.open': 'En cours',
|
|
8
|
+
'home.resolved': 'Résolues',
|
|
9
|
+
'home.empty': 'Aucune conversation pour le moment',
|
|
10
|
+
'home.emptyHint':
|
|
11
|
+
"Tout ce que vous envoyez arrive chez l'équipe, et ses réponses reviennent dans cette fenêtre.",
|
|
12
|
+
'home.noMessages': 'Aucun message pour le moment',
|
|
13
|
+
'home.you': 'Vous',
|
|
14
|
+
'home.threadA11y': 'Conversation : {type}',
|
|
15
|
+
'home.threadUnreadA11y': 'Conversation : {type}, {count} non lus',
|
|
16
|
+
'home.newA11y': 'Nouveau : {type}',
|
|
17
|
+
'home.language': 'Langue',
|
|
18
|
+
|
|
19
|
+
'type.feedback': 'Avis',
|
|
20
|
+
'type.feature_request': 'Suggestion',
|
|
21
|
+
'type.bug_report': 'Signalement de bug',
|
|
22
|
+
'hint.feedback': 'Dites-nous ce que vous en pensez',
|
|
23
|
+
'hint.feature_request': 'Proposez une amélioration',
|
|
24
|
+
'hint.bug_report': 'Quelque chose ne fonctionne pas',
|
|
25
|
+
'prompt.feedback': 'Que devrions-nous savoir ?',
|
|
26
|
+
'prompt.feature_request': 'Que souhaiteriez-vous voir ?',
|
|
27
|
+
'prompt.bug_report': "Que s'est-il passé, et à quoi vous attendiez-vous ?",
|
|
28
|
+
'sub.feedback': "Bon ou mauvais — cela va directement à l'équipe.",
|
|
29
|
+
'sub.feature_request': 'Dites-nous ce que vous essayez de faire.',
|
|
30
|
+
'sub.bug_report':
|
|
31
|
+
'Les étapes, l’écran concerné et ce que vous attendiez nous aident.',
|
|
32
|
+
|
|
33
|
+
'compose.back': 'Retour aux conversations',
|
|
34
|
+
'compose.sent': 'Envoyé',
|
|
35
|
+
'compose.sentHint':
|
|
36
|
+
'Nous répondrons ici même. Vous retrouverez la conversation dans En cours, et le bouton affiche une pastille dès que nous répondons.',
|
|
37
|
+
'compose.done': 'Terminé',
|
|
38
|
+
'compose.send': 'Envoyer',
|
|
39
|
+
'compose.sending': 'Envoi…',
|
|
40
|
+
'compose.minChars': 'Au moins {count} caractères',
|
|
41
|
+
|
|
42
|
+
'thread.support': 'Assistance',
|
|
43
|
+
'thread.new': 'Nouveau',
|
|
44
|
+
'thread.resolvedAt': 'Résolue · {date}',
|
|
45
|
+
'thread.readOnly': 'Cette conversation est résolue et en lecture seule',
|
|
46
|
+
'thread.placeholder': 'Écrivez une réponse…',
|
|
47
|
+
'chat.placeholder': 'Écrivez un message…',
|
|
48
|
+
'review.appStore': "Noter sur l'App Store",
|
|
49
|
+
'review.playStore': 'Noter sur Google Play',
|
|
50
|
+
'thread.sendA11y': 'Envoyer la réponse',
|
|
51
|
+
'thread.sendingA11y': 'Envoi en cours',
|
|
52
|
+
'thread.translating': 'Traduction…',
|
|
53
|
+
|
|
54
|
+
'status.open': 'En cours',
|
|
55
|
+
'status.resolved': 'Résolue',
|
|
56
|
+
|
|
57
|
+
'error.tryAgain': 'Réessayer',
|
|
58
|
+
'error.rateLimited': 'Trop de demandes — réessayez plus tard',
|
|
59
|
+
'error.offline': 'Vous êtes hors ligne — vérifiez votre connexion',
|
|
60
|
+
'error.sendFailed': "Envoi impossible — réessayez",
|
|
61
|
+
'error.loadFailed': 'Impossible de charger vos conversations',
|
|
62
|
+
'error.unavailable': "L'assistance est indisponible pour le moment",
|
|
63
|
+
'error.loadRateLimited': 'Trop de demandes — réessayez dans un instant',
|
|
64
|
+
|
|
65
|
+
'lang.title': 'Choisissez votre langue',
|
|
66
|
+
'lang.subtitle':
|
|
67
|
+
"Écrivez dans la langue de votre choix — nous traduisons entre vous et l'équipe d'assistance.",
|
|
68
|
+
'lang.continue': 'Continuer',
|
|
69
|
+
'lang.change': 'Changer de langue',
|
|
70
|
+
'lang.saveFailed': 'Enregistrement impossible — réessayez',
|
|
71
|
+
|
|
72
|
+
'time.justNow': "à l'instant",
|
|
73
|
+
'time.minutes': 'il y a {count} min',
|
|
74
|
+
'time.hours': 'il y a {count} h',
|
|
75
|
+
'time.days': 'il y a {count} j',
|
|
76
|
+
'time.weeks': 'il y a {count} sem.',
|
|
77
|
+
'time.months': 'il y a {count} mois',
|
|
78
|
+
'time.years': 'il y a {count} ans',
|
|
79
|
+
'time.today': "Aujourd'hui",
|
|
80
|
+
'time.yesterday': 'Hier',
|
|
81
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { StringTable } from './en';
|
|
2
|
+
|
|
3
|
+
export const hi: StringTable = {
|
|
4
|
+
'home.title': 'सहायता',
|
|
5
|
+
'home.subtitle': 'बातचीत शुरू करें — हम यहीं जवाब देते हैं।',
|
|
6
|
+
'home.close': 'सहायता बंद करें',
|
|
7
|
+
'home.open': 'खुली',
|
|
8
|
+
'home.resolved': 'हल हो चुकीं',
|
|
9
|
+
'home.empty': 'अभी कोई बातचीत नहीं',
|
|
10
|
+
'home.emptyHint':
|
|
11
|
+
'आप जो भी भेजेंगे वह टीम तक पहुँचता है, और उनके जवाब इसी विंडो में लौट आते हैं।',
|
|
12
|
+
'home.noMessages': 'अभी कोई संदेश नहीं',
|
|
13
|
+
'home.you': 'आप',
|
|
14
|
+
'home.threadA11y': 'बातचीत: {type}',
|
|
15
|
+
'home.threadUnreadA11y': 'बातचीत: {type}, {count} अपठित',
|
|
16
|
+
'home.newA11y': 'नया: {type}',
|
|
17
|
+
'home.language': 'भाषा',
|
|
18
|
+
|
|
19
|
+
'type.feedback': 'फ़ीडबैक',
|
|
20
|
+
'type.feature_request': 'फ़ीचर अनुरोध',
|
|
21
|
+
'type.bug_report': 'बग रिपोर्ट',
|
|
22
|
+
'hint.feedback': 'हमें बताएँ आप क्या सोचते हैं',
|
|
23
|
+
'hint.feature_request': 'कोई सुधार सुझाएँ',
|
|
24
|
+
'hint.bug_report': 'कुछ काम नहीं कर रहा',
|
|
25
|
+
'prompt.feedback': 'हमें क्या जानना चाहिए?',
|
|
26
|
+
'prompt.feature_request': 'आप क्या देखना चाहेंगे?',
|
|
27
|
+
'prompt.bug_report': 'क्या हुआ, और आपको क्या उम्मीद थी?',
|
|
28
|
+
'sub.feedback': 'अच्छा हो या बुरा — यह सीधे टीम तक जाता है।',
|
|
29
|
+
'sub.feature_request': 'बताएँ आप क्या करने की कोशिश कर रहे हैं।',
|
|
30
|
+
'sub.bug_report': 'चरण, स्क्रीन और आपकी अपेक्षा — सब मदद करते हैं।',
|
|
31
|
+
|
|
32
|
+
'compose.back': 'बातचीत पर वापस जाएँ',
|
|
33
|
+
'compose.sent': 'भेज दिया',
|
|
34
|
+
'compose.sentHint':
|
|
35
|
+
'हम यहीं जवाब देंगे। बातचीत आपको “खुली” में मिलेगी, और जवाब आने पर बटन पर निशान दिखेगा।',
|
|
36
|
+
'compose.done': 'हो गया',
|
|
37
|
+
'compose.send': 'भेजें',
|
|
38
|
+
'compose.sending': 'भेजा जा रहा है…',
|
|
39
|
+
'compose.minChars': 'कम से कम {count} अक्षर',
|
|
40
|
+
|
|
41
|
+
'thread.support': 'सहायता',
|
|
42
|
+
'thread.new': 'नया',
|
|
43
|
+
'thread.resolvedAt': 'हल हो चुकी · {date}',
|
|
44
|
+
'thread.readOnly': 'यह बातचीत हल हो चुकी है और केवल पढ़ने के लिए है',
|
|
45
|
+
'thread.placeholder': 'जवाब लिखें…',
|
|
46
|
+
'chat.placeholder': 'संदेश लिखें…',
|
|
47
|
+
'review.appStore': 'App Store पर रेटिंग दें',
|
|
48
|
+
'review.playStore': 'Google Play पर रेटिंग दें',
|
|
49
|
+
'thread.sendA11y': 'जवाब भेजें',
|
|
50
|
+
'thread.sendingA11y': 'भेजा जा रहा है',
|
|
51
|
+
'thread.translating': 'अनुवाद हो रहा है…',
|
|
52
|
+
|
|
53
|
+
'status.open': 'खुली',
|
|
54
|
+
'status.resolved': 'हल हो चुकी',
|
|
55
|
+
|
|
56
|
+
'error.tryAgain': 'फिर कोशिश करें',
|
|
57
|
+
'error.rateLimited': 'बहुत ज़्यादा अनुरोध — बाद में कोशिश करें',
|
|
58
|
+
'error.offline': 'आप ऑफ़लाइन हैं — अपना कनेक्शन जाँचें',
|
|
59
|
+
'error.sendFailed': 'भेजा नहीं जा सका — फिर कोशिश करें',
|
|
60
|
+
'error.loadFailed': 'आपकी बातचीत लोड नहीं हो सकी',
|
|
61
|
+
'error.unavailable': 'सहायता अभी उपलब्ध नहीं है',
|
|
62
|
+
'error.loadRateLimited': 'बहुत ज़्यादा अनुरोध — थोड़ी देर में कोशिश करें',
|
|
63
|
+
|
|
64
|
+
'lang.title': 'अपनी भाषा चुनें',
|
|
65
|
+
'lang.subtitle':
|
|
66
|
+
'जिस भाषा में सहज हों उसी में लिखें — हम आपके और सहायता टीम के बीच अनुवाद करते हैं।',
|
|
67
|
+
'lang.continue': 'जारी रखें',
|
|
68
|
+
'lang.change': 'भाषा बदलें',
|
|
69
|
+
'lang.saveFailed': 'सहेजा नहीं जा सका — फिर कोशिश करें',
|
|
70
|
+
|
|
71
|
+
'time.justNow': 'अभी',
|
|
72
|
+
'time.minutes': '{count} मिनट पहले',
|
|
73
|
+
'time.hours': '{count} घंटे पहले',
|
|
74
|
+
'time.days': '{count} दिन पहले',
|
|
75
|
+
'time.weeks': '{count} सप्ताह पहले',
|
|
76
|
+
'time.months': '{count} माह पहले',
|
|
77
|
+
'time.years': '{count} वर्ष पहले',
|
|
78
|
+
'time.today': 'आज',
|
|
79
|
+
'time.yesterday': 'कल',
|
|
80
|
+
};
|