@peaske7/readit 0.1.6 → 0.1.8
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/biome.json +1 -1
- package/bun.lock +86 -72
- package/package.json +12 -11
- package/src/App.tsx +36 -16
- package/src/cli/index.ts +338 -70
- package/src/components/ActionsMenu.tsx +12 -10
- package/src/components/DocumentViewer/CodeBlock.tsx +131 -54
- package/src/components/DocumentViewer/DocumentViewer.tsx +10 -8
- package/src/components/DocumentViewer/InlineCode.tsx +60 -0
- package/src/components/FloatingTOC.tsx +4 -2
- package/src/components/Header.tsx +3 -1
- package/src/components/InlineEditor.tsx +4 -2
- package/src/components/MarginNote.tsx +17 -8
- package/src/components/RawModal.tsx +9 -7
- package/src/components/ReanchorConfirm.tsx +6 -3
- package/src/components/SettingsModal.tsx +112 -23
- package/src/components/ShortcutCapture.tsx +4 -1
- package/src/components/ShortcutList.tsx +50 -9
- package/src/components/comments/CommentBadge.tsx +7 -1
- package/src/components/comments/CommentInput.tsx +13 -18
- package/src/components/comments/CommentListItem.tsx +15 -5
- package/src/components/comments/CommentManager.tsx +14 -7
- package/src/components/comments/CommentNav.tsx +8 -3
- package/src/contexts/CommentContext.tsx +16 -9
- package/src/contexts/LayoutContext.tsx +17 -5
- package/src/contexts/LocaleContext.tsx +35 -0
- package/src/hooks/useClipboard.ts +11 -8
- package/src/hooks/useDocument.ts +33 -18
- package/src/hooks/useEditorScheme.ts +51 -0
- package/src/hooks/useFontPreference.ts +5 -22
- package/src/hooks/useKeybindings.ts +6 -18
- package/src/hooks/useLocalePreference.ts +42 -0
- package/src/index.css +87 -26
- package/src/lib/editor-links.ts +59 -0
- package/src/lib/highlight/dom.ts +126 -54
- package/src/lib/highlight/highlighter.ts +10 -10
- package/src/lib/i18n/completeness.test.ts +51 -0
- package/src/lib/i18n/en.ts +139 -0
- package/src/lib/i18n/index.ts +3 -0
- package/src/lib/i18n/ja.ts +141 -0
- package/src/lib/i18n/translations.test.ts +39 -0
- package/src/lib/i18n/translations.ts +27 -0
- package/src/lib/i18n/types.ts +145 -0
- package/src/lib/shortcut-registry.ts +1 -1
- package/src/main.tsx +4 -1
- package/src/server/index.ts +197 -124
- package/src/store/index.test.ts +22 -0
- package/src/store/index.ts +24 -4
- package/src/types/index.ts +12 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import type { Translations } from "./types";
|
|
2
|
+
|
|
3
|
+
export const en: Translations = {
|
|
4
|
+
// App
|
|
5
|
+
"app.loading": "Loading...",
|
|
6
|
+
"app.noDocuments": "No documents open.",
|
|
7
|
+
"app.noDocumentsHintPrefix": "Run",
|
|
8
|
+
"app.noDocumentsHintSuffix": "to add a file.",
|
|
9
|
+
"app.footer": "Made with ❤️ by Jay and Claude",
|
|
10
|
+
|
|
11
|
+
// Header
|
|
12
|
+
"header.selectTextToReanchor": "Select text to re-anchor",
|
|
13
|
+
|
|
14
|
+
// Actions menu
|
|
15
|
+
"actions.ariaLabel": "Actions menu",
|
|
16
|
+
"actions.centered": "Centered",
|
|
17
|
+
"actions.fullscreen": "Fullscreen",
|
|
18
|
+
"actions.settings": "Settings",
|
|
19
|
+
"actions.reload": "Reload",
|
|
20
|
+
"actions.copyAllAI": "Copy All (AI)",
|
|
21
|
+
"actions.copyAllAITitle": "Copy in prompt format for AI assistants",
|
|
22
|
+
"actions.copyAllRaw": "Copy All (Raw)",
|
|
23
|
+
"actions.copyAllRawTitle": "Copy as plain text",
|
|
24
|
+
"actions.exportJson": "Export JSON",
|
|
25
|
+
"actions.viewRaw": "View Raw",
|
|
26
|
+
|
|
27
|
+
// Settings
|
|
28
|
+
"settings.title": "Settings",
|
|
29
|
+
"settings.theme": "Theme",
|
|
30
|
+
"settings.font": "Font",
|
|
31
|
+
"settings.language": "Language",
|
|
32
|
+
"settings.keyboardShortcuts": "Keyboard Shortcuts",
|
|
33
|
+
"settings.clickToRebind": "Click a key to rebind",
|
|
34
|
+
"settings.theme.system": "System",
|
|
35
|
+
"settings.theme.light": "Light",
|
|
36
|
+
"settings.theme.dark": "Dark",
|
|
37
|
+
"settings.font.serif": "Serif",
|
|
38
|
+
"settings.font.sansSerif": "Sans-serif",
|
|
39
|
+
"settings.editor": "Editor",
|
|
40
|
+
"settings.editor.none": "None",
|
|
41
|
+
"settings.editor.vscode": "VS Code",
|
|
42
|
+
"settings.editor.vscodeInsiders": "VS Code Insiders",
|
|
43
|
+
"settings.editor.cursor": "Cursor",
|
|
44
|
+
|
|
45
|
+
// Comment input
|
|
46
|
+
"comment.placeholder": "Add your comment...",
|
|
47
|
+
"comment.cancel": "Cancel",
|
|
48
|
+
"comment.addNote": "Add Note",
|
|
49
|
+
"comment.highlight": "Highlight",
|
|
50
|
+
"comment.copyRawTitle": "Copy raw text (⌘C)",
|
|
51
|
+
"comment.copyRawLabel": "Copy raw text",
|
|
52
|
+
"comment.copyLLMTitle": "Copy with context for LLM (⌘⇧C)",
|
|
53
|
+
"comment.copyLLMLabel": "Copy for LLM",
|
|
54
|
+
|
|
55
|
+
// Margin note
|
|
56
|
+
"marginNote.addNote": "Add note",
|
|
57
|
+
"marginNote.delete": "Delete",
|
|
58
|
+
"marginNote.edit": "Edit",
|
|
59
|
+
"marginNote.copy": "Copy",
|
|
60
|
+
"marginNote.copyTitle": "Copy raw text (⌘C)",
|
|
61
|
+
"marginNote.llm": "LLM",
|
|
62
|
+
"marginNote.llmTitle": "Copy with context for LLM (⌘⇧C)",
|
|
63
|
+
|
|
64
|
+
// Comment manager
|
|
65
|
+
"commentManager.unresolved": "unresolved",
|
|
66
|
+
"commentManager.deleteAllConfirm": "Delete all {{count}} comments?",
|
|
67
|
+
"commentManager.delete": "Delete",
|
|
68
|
+
"commentManager.cancel": "Cancel",
|
|
69
|
+
"commentManager.copyAllTitle": "Copy all comments",
|
|
70
|
+
"commentManager.deleteAllTitle": "Delete all comments",
|
|
71
|
+
"commentManager.noComments": "No comments yet",
|
|
72
|
+
|
|
73
|
+
// Comment list item
|
|
74
|
+
"commentList.edit": "Edit",
|
|
75
|
+
"commentList.delete": "Delete",
|
|
76
|
+
"commentList.goTo": "Go to",
|
|
77
|
+
"commentList.reanchor": "Re-anchor",
|
|
78
|
+
"commentList.unresolved": "unresolved",
|
|
79
|
+
|
|
80
|
+
// Comment nav
|
|
81
|
+
"commentNav.previous": "Previous comment (Alt+↑)",
|
|
82
|
+
"commentNav.next": "Next comment (Alt+↓)",
|
|
83
|
+
"commentNav.of": "{{current}} of {{total}}",
|
|
84
|
+
|
|
85
|
+
// Inline editor
|
|
86
|
+
"editor.save": "Save",
|
|
87
|
+
"editor.cancel": "Cancel",
|
|
88
|
+
|
|
89
|
+
// Reanchor confirm
|
|
90
|
+
"reanchor.question": "Re-anchor to this selection?",
|
|
91
|
+
"reanchor.confirm": "Confirm",
|
|
92
|
+
"reanchor.cancel": "Cancel",
|
|
93
|
+
|
|
94
|
+
// Raw comments modal
|
|
95
|
+
"rawModal.title": "Raw Comments",
|
|
96
|
+
"rawModal.copyTitle": "Copy to clipboard",
|
|
97
|
+
"rawModal.loading": "Loading...",
|
|
98
|
+
"rawModal.noComments": "No comments file yet. Add comments to create one.",
|
|
99
|
+
"rawModal.copiedToClipboard": "Copied to clipboard",
|
|
100
|
+
"rawModal.failedToCopy": "Failed to copy",
|
|
101
|
+
|
|
102
|
+
// Shortcut groups
|
|
103
|
+
"shortcutGroup.copy": "Copy",
|
|
104
|
+
"shortcutGroup.navigate": "Navigate",
|
|
105
|
+
"shortcutGroup.other": "Other",
|
|
106
|
+
"shortcuts.resetToDefaults": "Reset to defaults",
|
|
107
|
+
"shortcuts.enableDisable": "Enable/disable shortcut",
|
|
108
|
+
"shortcutCapture.pressKeys": "Press keys...",
|
|
109
|
+
|
|
110
|
+
// Shortcut labels
|
|
111
|
+
"shortcut.copyAll.label": "Copy All (AI)",
|
|
112
|
+
"shortcut.copyAll.description": "Copy all comments in AI prompt format",
|
|
113
|
+
"shortcut.copyAllRaw.label": "Copy All (Raw)",
|
|
114
|
+
"shortcut.copyAllRaw.description": "Copy all comments as raw text",
|
|
115
|
+
"shortcut.navigateNext.label": "Next Comment",
|
|
116
|
+
"shortcut.navigateNext.description": "Navigate to next comment",
|
|
117
|
+
"shortcut.navigatePrevious.label": "Previous Comment",
|
|
118
|
+
"shortcut.navigatePrevious.description": "Navigate to previous comment",
|
|
119
|
+
"shortcut.copySelectionRaw.label": "Copy Selection",
|
|
120
|
+
"shortcut.copySelectionRaw.description": "Copy selected text",
|
|
121
|
+
"shortcut.copySelectionLLM.label": "Copy Selection (LLM)",
|
|
122
|
+
"shortcut.copySelectionLLM.description":
|
|
123
|
+
"Copy selected text with context for LLM",
|
|
124
|
+
"shortcut.clearSelection.label": "Clear Selection",
|
|
125
|
+
"shortcut.clearSelection.description": "Clear text selection",
|
|
126
|
+
|
|
127
|
+
// Toast messages
|
|
128
|
+
"toast.copied": 'Copied: "{{text}}"',
|
|
129
|
+
"toast.copiedForLLM": 'Copied for LLM: "{{text}}"',
|
|
130
|
+
"toast.copiedAllComments": "Copied all comments",
|
|
131
|
+
"toast.copiedAllRaw": "Copied all comments as raw text",
|
|
132
|
+
|
|
133
|
+
// Floating TOC
|
|
134
|
+
"floatingTOC.label": "Table of Contents",
|
|
135
|
+
|
|
136
|
+
// Comment badge
|
|
137
|
+
"commentBadge.title": "{{count}} comment",
|
|
138
|
+
"commentBadge.titlePlural": "{{count}} comments",
|
|
139
|
+
};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import type { Translations } from "./types";
|
|
2
|
+
|
|
3
|
+
export const ja: Translations = {
|
|
4
|
+
// App
|
|
5
|
+
"app.loading": "読み込み中...",
|
|
6
|
+
"app.noDocuments": "開いているドキュメントがありません。",
|
|
7
|
+
"app.noDocumentsHintPrefix": "",
|
|
8
|
+
"app.noDocumentsHintSuffix": "を実行してファイルを追加してください。",
|
|
9
|
+
"app.footer": "Made with ❤️ by Jay and Claude",
|
|
10
|
+
|
|
11
|
+
// Header
|
|
12
|
+
"header.selectTextToReanchor": "テキストを選択して再アンカー",
|
|
13
|
+
|
|
14
|
+
// Actions menu
|
|
15
|
+
"actions.ariaLabel": "操作メニュー",
|
|
16
|
+
"actions.centered": "中央揃え",
|
|
17
|
+
"actions.fullscreen": "全画面",
|
|
18
|
+
"actions.settings": "設定",
|
|
19
|
+
"actions.reload": "再読み込み",
|
|
20
|
+
"actions.copyAllAI": "全てコピー (AI)",
|
|
21
|
+
"actions.copyAllAITitle": "AIアシスタント用プロンプト形式でコピー",
|
|
22
|
+
"actions.copyAllRaw": "全てコピー (テキスト)",
|
|
23
|
+
"actions.copyAllRawTitle": "プレーンテキストとしてコピー",
|
|
24
|
+
"actions.exportJson": "JSONエクスポート",
|
|
25
|
+
"actions.viewRaw": "生データを表示",
|
|
26
|
+
|
|
27
|
+
// Settings
|
|
28
|
+
"settings.title": "設定",
|
|
29
|
+
"settings.theme": "テーマ",
|
|
30
|
+
"settings.font": "フォント",
|
|
31
|
+
"settings.language": "言語",
|
|
32
|
+
"settings.keyboardShortcuts": "キーボードショートカット",
|
|
33
|
+
"settings.clickToRebind": "キーをクリックして変更",
|
|
34
|
+
"settings.theme.system": "システム",
|
|
35
|
+
"settings.theme.light": "ライト",
|
|
36
|
+
"settings.theme.dark": "ダーク",
|
|
37
|
+
"settings.font.serif": "明朝体",
|
|
38
|
+
"settings.font.sansSerif": "ゴシック体",
|
|
39
|
+
"settings.editor": "エディター",
|
|
40
|
+
"settings.editor.none": "なし",
|
|
41
|
+
"settings.editor.vscode": "VS Code",
|
|
42
|
+
"settings.editor.vscodeInsiders": "VS Code Insiders",
|
|
43
|
+
"settings.editor.cursor": "Cursor",
|
|
44
|
+
|
|
45
|
+
// Comment input
|
|
46
|
+
"comment.placeholder": "コメントを入力...",
|
|
47
|
+
"comment.cancel": "キャンセル",
|
|
48
|
+
"comment.addNote": "メモを追加",
|
|
49
|
+
"comment.highlight": "ハイライト",
|
|
50
|
+
"comment.copyRawTitle": "テキストをコピー (⌘C)",
|
|
51
|
+
"comment.copyRawLabel": "テキストをコピー",
|
|
52
|
+
"comment.copyLLMTitle": "LLM用にコンテキスト付きでコピー (⌘⇧C)",
|
|
53
|
+
"comment.copyLLMLabel": "LLM用にコピー",
|
|
54
|
+
|
|
55
|
+
// Margin note
|
|
56
|
+
"marginNote.addNote": "メモを追加",
|
|
57
|
+
"marginNote.delete": "削除",
|
|
58
|
+
"marginNote.edit": "編集",
|
|
59
|
+
"marginNote.copy": "コピー",
|
|
60
|
+
"marginNote.copyTitle": "テキストをコピー (⌘C)",
|
|
61
|
+
"marginNote.llm": "LLM",
|
|
62
|
+
"marginNote.llmTitle": "LLM用にコンテキスト付きでコピー (⌘⇧C)",
|
|
63
|
+
|
|
64
|
+
// Comment manager
|
|
65
|
+
"commentManager.unresolved": "未解決",
|
|
66
|
+
"commentManager.deleteAllConfirm":
|
|
67
|
+
"{{count}}件のコメントを全て削除しますか?",
|
|
68
|
+
"commentManager.delete": "削除",
|
|
69
|
+
"commentManager.cancel": "キャンセル",
|
|
70
|
+
"commentManager.copyAllTitle": "全てのコメントをコピー",
|
|
71
|
+
"commentManager.deleteAllTitle": "全てのコメントを削除",
|
|
72
|
+
"commentManager.noComments": "コメントはまだありません",
|
|
73
|
+
|
|
74
|
+
// Comment list item
|
|
75
|
+
"commentList.edit": "編集",
|
|
76
|
+
"commentList.delete": "削除",
|
|
77
|
+
"commentList.goTo": "移動",
|
|
78
|
+
"commentList.reanchor": "再アンカー",
|
|
79
|
+
"commentList.unresolved": "未解決",
|
|
80
|
+
|
|
81
|
+
// Comment nav
|
|
82
|
+
"commentNav.previous": "前のコメント (Alt+↑)",
|
|
83
|
+
"commentNav.next": "次のコメント (Alt+↓)",
|
|
84
|
+
"commentNav.of": "{{current}} / {{total}}",
|
|
85
|
+
|
|
86
|
+
// Inline editor
|
|
87
|
+
"editor.save": "保存",
|
|
88
|
+
"editor.cancel": "キャンセル",
|
|
89
|
+
|
|
90
|
+
// Reanchor confirm
|
|
91
|
+
"reanchor.question": "この選択範囲に再アンカーしますか?",
|
|
92
|
+
"reanchor.confirm": "確認",
|
|
93
|
+
"reanchor.cancel": "キャンセル",
|
|
94
|
+
|
|
95
|
+
// Raw comments modal
|
|
96
|
+
"rawModal.title": "コメント生データ",
|
|
97
|
+
"rawModal.copyTitle": "クリップボードにコピー",
|
|
98
|
+
"rawModal.loading": "読み込み中...",
|
|
99
|
+
"rawModal.noComments":
|
|
100
|
+
"コメントファイルはまだありません。コメントを追加して作成してください。",
|
|
101
|
+
"rawModal.copiedToClipboard": "クリップボードにコピーしました",
|
|
102
|
+
"rawModal.failedToCopy": "コピーに失敗しました",
|
|
103
|
+
|
|
104
|
+
// Shortcut groups
|
|
105
|
+
"shortcutGroup.copy": "コピー",
|
|
106
|
+
"shortcutGroup.navigate": "ナビゲーション",
|
|
107
|
+
"shortcutGroup.other": "その他",
|
|
108
|
+
"shortcuts.resetToDefaults": "初期設定に戻す",
|
|
109
|
+
"shortcuts.enableDisable": "ショートカットの有効/無効",
|
|
110
|
+
"shortcutCapture.pressKeys": "キーを入力...",
|
|
111
|
+
|
|
112
|
+
// Shortcut labels
|
|
113
|
+
"shortcut.copyAll.label": "全てコピー (AI)",
|
|
114
|
+
"shortcut.copyAll.description": "全コメントをAIプロンプト形式でコピー",
|
|
115
|
+
"shortcut.copyAllRaw.label": "全てコピー (テキスト)",
|
|
116
|
+
"shortcut.copyAllRaw.description": "全コメントをテキストとしてコピー",
|
|
117
|
+
"shortcut.navigateNext.label": "次のコメント",
|
|
118
|
+
"shortcut.navigateNext.description": "次のコメントに移動",
|
|
119
|
+
"shortcut.navigatePrevious.label": "前のコメント",
|
|
120
|
+
"shortcut.navigatePrevious.description": "前のコメントに移動",
|
|
121
|
+
"shortcut.copySelectionRaw.label": "選択をコピー",
|
|
122
|
+
"shortcut.copySelectionRaw.description": "選択テキストをコピー",
|
|
123
|
+
"shortcut.copySelectionLLM.label": "選択をコピー (LLM)",
|
|
124
|
+
"shortcut.copySelectionLLM.description":
|
|
125
|
+
"選択テキストをLLM用コンテキスト付きでコピー",
|
|
126
|
+
"shortcut.clearSelection.label": "選択を解除",
|
|
127
|
+
"shortcut.clearSelection.description": "テキスト選択を解除",
|
|
128
|
+
|
|
129
|
+
// Toast messages
|
|
130
|
+
"toast.copied": 'コピーしました: "{{text}}"',
|
|
131
|
+
"toast.copiedForLLM": 'LLM用にコピーしました: "{{text}}"',
|
|
132
|
+
"toast.copiedAllComments": "全てのコメントをコピーしました",
|
|
133
|
+
"toast.copiedAllRaw": "全てのコメントをテキストとしてコピーしました",
|
|
134
|
+
|
|
135
|
+
// Floating TOC
|
|
136
|
+
"floatingTOC.label": "目次",
|
|
137
|
+
|
|
138
|
+
// Comment badge
|
|
139
|
+
"commentBadge.title": "{{count}}件のコメント",
|
|
140
|
+
"commentBadge.titlePlural": "{{count}}件のコメント",
|
|
141
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { createT } from "./translations";
|
|
3
|
+
import { Locales } from "./types";
|
|
4
|
+
|
|
5
|
+
describe("createT", () => {
|
|
6
|
+
it("returns English strings for en locale", () => {
|
|
7
|
+
const t = createT(Locales.EN);
|
|
8
|
+
expect(t("app.loading")).toBe("Loading...");
|
|
9
|
+
expect(t("settings.title")).toBe("Settings");
|
|
10
|
+
expect(t("comment.placeholder")).toBe("Add your comment...");
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("returns Japanese strings for ja locale", () => {
|
|
14
|
+
const t = createT(Locales.JA);
|
|
15
|
+
expect(t("app.loading")).toBe("読み込み中...");
|
|
16
|
+
expect(t("settings.title")).toBe("設定");
|
|
17
|
+
expect(t("comment.placeholder")).toBe("コメントを入力...");
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("interpolates {{placeholder}} params", () => {
|
|
21
|
+
const tEn = createT(Locales.EN);
|
|
22
|
+
expect(tEn("commentNav.of", { current: 1, total: 5 })).toBe("1 of 5");
|
|
23
|
+
|
|
24
|
+
const tJa = createT(Locales.JA);
|
|
25
|
+
expect(tJa("commentNav.of", { current: 1, total: 5 })).toBe("1 / 5");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("interpolates multiple params", () => {
|
|
29
|
+
const t = createT(Locales.EN);
|
|
30
|
+
expect(t("commentManager.deleteAllConfirm", { count: 3 })).toBe(
|
|
31
|
+
"Delete all 3 comments?",
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("returns string unchanged when no params provided", () => {
|
|
36
|
+
const t = createT(Locales.EN);
|
|
37
|
+
expect(t("app.footer")).toBe("Made with ❤️ by Jay and Claude");
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { en } from "./en";
|
|
2
|
+
import { ja } from "./ja";
|
|
3
|
+
import type { Locale, TranslationKey, Translations } from "./types";
|
|
4
|
+
import { Locales } from "./types";
|
|
5
|
+
|
|
6
|
+
const translationMap: Record<Locale, Translations> = {
|
|
7
|
+
[Locales.JA]: ja,
|
|
8
|
+
[Locales.EN]: en,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function createT(locale: Locale) {
|
|
12
|
+
const translations = translationMap[locale];
|
|
13
|
+
|
|
14
|
+
return function t(
|
|
15
|
+
key: TranslationKey,
|
|
16
|
+
params?: Record<string, string | number>,
|
|
17
|
+
): string {
|
|
18
|
+
let value = translations[key];
|
|
19
|
+
if (!params) return value;
|
|
20
|
+
|
|
21
|
+
for (const [param, replacement] of Object.entries(params)) {
|
|
22
|
+
value = value.replaceAll(`{{${param}}}`, String(replacement));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return value;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
export const Locales = {
|
|
2
|
+
JA: "ja",
|
|
3
|
+
EN: "en",
|
|
4
|
+
} as const;
|
|
5
|
+
|
|
6
|
+
export type Locale = (typeof Locales)[keyof typeof Locales];
|
|
7
|
+
|
|
8
|
+
export interface Translations {
|
|
9
|
+
// App
|
|
10
|
+
"app.loading": string;
|
|
11
|
+
"app.noDocuments": string;
|
|
12
|
+
"app.noDocumentsHintPrefix": string;
|
|
13
|
+
"app.noDocumentsHintSuffix": string;
|
|
14
|
+
"app.footer": string;
|
|
15
|
+
|
|
16
|
+
// Header
|
|
17
|
+
"header.selectTextToReanchor": string;
|
|
18
|
+
|
|
19
|
+
// Actions menu
|
|
20
|
+
"actions.ariaLabel": string;
|
|
21
|
+
"actions.centered": string;
|
|
22
|
+
"actions.fullscreen": string;
|
|
23
|
+
"actions.settings": string;
|
|
24
|
+
"actions.reload": string;
|
|
25
|
+
"actions.copyAllAI": string;
|
|
26
|
+
"actions.copyAllAITitle": string;
|
|
27
|
+
"actions.copyAllRaw": string;
|
|
28
|
+
"actions.copyAllRawTitle": string;
|
|
29
|
+
"actions.exportJson": string;
|
|
30
|
+
"actions.viewRaw": string;
|
|
31
|
+
|
|
32
|
+
// Settings
|
|
33
|
+
"settings.title": string;
|
|
34
|
+
"settings.theme": string;
|
|
35
|
+
"settings.font": string;
|
|
36
|
+
"settings.language": string;
|
|
37
|
+
"settings.keyboardShortcuts": string;
|
|
38
|
+
"settings.clickToRebind": string;
|
|
39
|
+
"settings.theme.system": string;
|
|
40
|
+
"settings.theme.light": string;
|
|
41
|
+
"settings.theme.dark": string;
|
|
42
|
+
"settings.font.serif": string;
|
|
43
|
+
"settings.font.sansSerif": string;
|
|
44
|
+
"settings.editor": string;
|
|
45
|
+
"settings.editor.none": string;
|
|
46
|
+
"settings.editor.vscode": string;
|
|
47
|
+
"settings.editor.vscodeInsiders": string;
|
|
48
|
+
"settings.editor.cursor": string;
|
|
49
|
+
|
|
50
|
+
// Comment input
|
|
51
|
+
"comment.placeholder": string;
|
|
52
|
+
"comment.cancel": string;
|
|
53
|
+
"comment.addNote": string;
|
|
54
|
+
"comment.highlight": string;
|
|
55
|
+
"comment.copyRawTitle": string;
|
|
56
|
+
"comment.copyRawLabel": string;
|
|
57
|
+
"comment.copyLLMTitle": string;
|
|
58
|
+
"comment.copyLLMLabel": string;
|
|
59
|
+
|
|
60
|
+
// Margin note
|
|
61
|
+
"marginNote.addNote": string;
|
|
62
|
+
"marginNote.delete": string;
|
|
63
|
+
"marginNote.edit": string;
|
|
64
|
+
"marginNote.copy": string;
|
|
65
|
+
"marginNote.copyTitle": string;
|
|
66
|
+
"marginNote.llm": string;
|
|
67
|
+
"marginNote.llmTitle": string;
|
|
68
|
+
|
|
69
|
+
// Comment manager
|
|
70
|
+
"commentManager.unresolved": string;
|
|
71
|
+
"commentManager.deleteAllConfirm": string;
|
|
72
|
+
"commentManager.delete": string;
|
|
73
|
+
"commentManager.cancel": string;
|
|
74
|
+
"commentManager.copyAllTitle": string;
|
|
75
|
+
"commentManager.deleteAllTitle": string;
|
|
76
|
+
"commentManager.noComments": string;
|
|
77
|
+
|
|
78
|
+
// Comment list item
|
|
79
|
+
"commentList.edit": string;
|
|
80
|
+
"commentList.delete": string;
|
|
81
|
+
"commentList.goTo": string;
|
|
82
|
+
"commentList.reanchor": string;
|
|
83
|
+
"commentList.unresolved": string;
|
|
84
|
+
|
|
85
|
+
// Comment nav
|
|
86
|
+
"commentNav.previous": string;
|
|
87
|
+
"commentNav.next": string;
|
|
88
|
+
"commentNav.of": string;
|
|
89
|
+
|
|
90
|
+
// Inline editor
|
|
91
|
+
"editor.save": string;
|
|
92
|
+
"editor.cancel": string;
|
|
93
|
+
|
|
94
|
+
// Reanchor confirm
|
|
95
|
+
"reanchor.question": string;
|
|
96
|
+
"reanchor.confirm": string;
|
|
97
|
+
"reanchor.cancel": string;
|
|
98
|
+
|
|
99
|
+
// Raw comments modal
|
|
100
|
+
"rawModal.title": string;
|
|
101
|
+
"rawModal.copyTitle": string;
|
|
102
|
+
"rawModal.loading": string;
|
|
103
|
+
"rawModal.noComments": string;
|
|
104
|
+
"rawModal.copiedToClipboard": string;
|
|
105
|
+
"rawModal.failedToCopy": string;
|
|
106
|
+
|
|
107
|
+
// Shortcut groups
|
|
108
|
+
"shortcutGroup.copy": string;
|
|
109
|
+
"shortcutGroup.navigate": string;
|
|
110
|
+
"shortcutGroup.other": string;
|
|
111
|
+
"shortcuts.resetToDefaults": string;
|
|
112
|
+
"shortcuts.enableDisable": string;
|
|
113
|
+
"shortcutCapture.pressKeys": string;
|
|
114
|
+
|
|
115
|
+
// Shortcut labels (rendered in ShortcutList)
|
|
116
|
+
"shortcut.copyAll.label": string;
|
|
117
|
+
"shortcut.copyAll.description": string;
|
|
118
|
+
"shortcut.copyAllRaw.label": string;
|
|
119
|
+
"shortcut.copyAllRaw.description": string;
|
|
120
|
+
"shortcut.navigateNext.label": string;
|
|
121
|
+
"shortcut.navigateNext.description": string;
|
|
122
|
+
"shortcut.navigatePrevious.label": string;
|
|
123
|
+
"shortcut.navigatePrevious.description": string;
|
|
124
|
+
"shortcut.copySelectionRaw.label": string;
|
|
125
|
+
"shortcut.copySelectionRaw.description": string;
|
|
126
|
+
"shortcut.copySelectionLLM.label": string;
|
|
127
|
+
"shortcut.copySelectionLLM.description": string;
|
|
128
|
+
"shortcut.clearSelection.label": string;
|
|
129
|
+
"shortcut.clearSelection.description": string;
|
|
130
|
+
|
|
131
|
+
// Toast messages
|
|
132
|
+
"toast.copied": string;
|
|
133
|
+
"toast.copiedForLLM": string;
|
|
134
|
+
"toast.copiedAllComments": string;
|
|
135
|
+
"toast.copiedAllRaw": string;
|
|
136
|
+
|
|
137
|
+
// Floating TOC
|
|
138
|
+
"floatingTOC.label": string;
|
|
139
|
+
|
|
140
|
+
// Comment badge
|
|
141
|
+
"commentBadge.title": string;
|
|
142
|
+
"commentBadge.titlePlural": string;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export type TranslationKey = keyof Translations;
|
package/src/main.tsx
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import ReactDOM from "react-dom/client";
|
|
3
3
|
import App from "./App";
|
|
4
|
+
import { LocaleProvider } from "./contexts/LocaleContext";
|
|
4
5
|
import "./index.css";
|
|
5
6
|
|
|
6
7
|
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
7
8
|
<React.StrictMode>
|
|
8
|
-
<
|
|
9
|
+
<LocaleProvider>
|
|
10
|
+
<App />
|
|
11
|
+
</LocaleProvider>
|
|
9
12
|
</React.StrictMode>,
|
|
10
13
|
);
|