-
-
Notifications
You must be signed in to change notification settings - Fork 143
キャラクタープリセット機能を実装 #320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
キャラクタープリセット機能を実装 #320
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Walkthrough今回の変更では、各ロケールの翻訳ファイルにキャラクタープリセット用の新規エントリ( Changes
Sequence Diagram(s)sequenceDiagram
participant U as ユーザー
participant HP as Homeコンポーネント
participant SS as settingsStore
participant TS as toastStore
U->>HP: ショートカットキー (Shift + Cmd/Ctrl + 1~5) を入力
HP->>HP: キー入力を解析・該当プリセットを決定
HP->>SS: systemPromptを選択プリセットに更新
HP->>TS: PresetSwitchingメッセージ付きトースト通知の追加
TS-->>U: 通知を表示
sequenceDiagram
participant U as ユーザー
participant CC as Characterコンポーネント
U->>CC: マウス移動イベント
CC->>CC: handleMouseMoveでツールチップ位置・内容更新
U->>CC: マウス離脱イベント
CC->>CC: handleMouseLeaveでツールチップ非表示処理
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (9)
🚧 Files skipped from review as they are similar to previous changes (4)
🔇 Additional comments (10)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
src/pages/index.tsx
Outdated
| return () => { | ||
| window.removeEventListener("keydown", handleKeyDown); | ||
| }; | ||
| }, []); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ショートカットの実装をindex.tsxで行っています。menu.tsxで実装した際、process.envが呼び出せなかったためです。独自のファイルを作成してもprocess.envを呼び出せず、index.tsxで正常な動作を確認できた形になります。
なにか気づいた点がありましたらメッセージをお願いします。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (5)
website/document/en/guide/character/common.md (1)
18-25: キャラクタープリセット環境変数の追加について
追加された「# character preset」セクションでは、5種類の環境変数(NEXT_PUBLIC_CHARACTER_PRESET1~5)が導入されています。全て同一の文字列値 ("You are an AI assistant named Nike.") が設定されていますが、意図的なものであれば問題ありません。将来的に各プリセットに異なる内容を設定する可能性がある場合は、その点も確認してください。src/components/settings/character.tsx (2)
325-331: プリセットの実装を改善する提案プリセットの実装は機能的ですが、以下の改善を提案します:
- プリセットのキーを定数として定義
- 型安全性の追加
+const CHARACTER_PRESET_KEYS = { + PRESET_1: 'characterPreset1', + PRESET_2: 'characterPreset2', + PRESET_3: 'characterPreset3', + PRESET_4: 'characterPreset4', + PRESET_5: 'characterPreset5', +} as const; + +type CharacterPreset = { + key: keyof typeof CHARACTER_PRESET_KEYS; + value: string; +}; -const characterPresets = [ +const characterPresets: CharacterPreset[] = [ { key: "characterPreset1", value: settingsStore((s) => s.characterPreset1) }, { key: "characterPreset2", value: settingsStore((s) => s.characterPreset2) }, { key: "characterPreset3", value: settingsStore((s) => s.characterPreset3) }, { key: "characterPreset4", value: settingsStore((s) => s.characterPreset4) }, { key: "characterPreset5", value: settingsStore((s) => s.characterPreset5) }, ];🧰 Tools
🪛 ESLint
[error] 326-326: Replace
·key:·"characterPreset1",·value:·settingsStore((s)·=>·s.characterPreset1)with⏎······key:·'characterPreset1',⏎······value:·settingsStore((s)·=>·s.characterPreset1),⏎···(prettier/prettier)
[error] 327-327: Replace
·key:·"characterPreset2",·value:·settingsStore((s)·=>·s.characterPreset2)with⏎······key:·'characterPreset2',⏎······value:·settingsStore((s)·=>·s.characterPreset2),⏎···(prettier/prettier)
[error] 328-328: Replace
·key:·"characterPreset3",·value:·settingsStore((s)·=>·s.characterPreset3)with⏎······key:·'characterPreset3',⏎······value:·settingsStore((s)·=>·s.characterPreset3),⏎···(prettier/prettier)
[error] 329-329: Replace
·key:·"characterPreset4",·value:·settingsStore((s)·=>·s.characterPreset4)with⏎······key:·'characterPreset4',⏎······value:·settingsStore((s)·=>·s.characterPreset4),⏎···(prettier/prettier)
[error] 330-330: Replace
·key:·"characterPreset5",·value:·settingsStore((s)·=>·s.characterPreset5)with⏎······key:·'characterPreset5',⏎······value:·settingsStore((s)·=>·s.characterPreset5),⏎···(prettier/prettier)
[error] 331-331: Delete
;(prettier/prettier)
332-353: ツールチップのロジックをカスタムフックに抽出ツールチップの状態管理とハンドラーをカスタムフックに抽出することで、コードの再利用性と保守性が向上します:
+interface TooltipState { + x: number; + y: number; + visible: boolean; +} + +const useTooltip = (offsetX: number, offsetY: number) => { + const [tooltipText, setTooltipText] = useState(""); + const [tooltip, setTooltip] = useState<TooltipState>({ + x: 0, + y: 0, + visible: false + }); + + const handleMouseMove = useCallback((e: React.MouseEvent) => { + setTooltip({ + x: e.clientX + offsetX, + y: e.clientY + offsetY, + visible: true + }); + }, [offsetX, offsetY]); + + const handleMouseLeave = useCallback(() => { + setTooltip(prev => ({ ...prev, visible: false })); + }, []); + + return { + tooltipText, + setTooltipText, + tooltip, + handleMouseMove, + handleMouseLeave + }; +};このカスタムフックを使用することで、コンポーネントのコードがよりクリーンになります。
🧰 Tools
🪛 ESLint
[error] 332-332: Replace
"");with'')(prettier/prettier)
[error] 334-334: Replace
·x:·number;·y:·number;·visible:·booleanwith⏎····x:·number⏎····y:·number⏎····visible:·boolean⏎·(prettier/prettier)
[error] 337-337: Insert
,(prettier/prettier)
[error] 338-338: Delete
;(prettier/prettier)
[error] 344-344: Delete
;(prettier/prettier)
[error] 345-345: Delete
;(prettier/prettier)
[error] 348-348: Replace
·x:·e.clientX·+·tooltipOffsetX,·y:·e.clientY·+·tooltipOffsetY,·visible:·true·});with⏎······x:·e.clientX·+·tooltipOffsetX,⏎······y:·e.clientY·+·tooltipOffsetY,⏎······visible:·true,⏎····})(prettier/prettier)
[error] 349-349: Delete
;(prettier/prettier)
[error] 352-352: Delete
;(prettier/prettier)
[error] 353-353: Delete
;(prettier/prettier)
src/features/stores/settings.ts (1)
417-421: フォーマットの修正が必要です静的解析ツールが指摘するように、行末の余分なスペースを削除する必要があります。
以下の修正を提案します:
- characterPreset2: state.characterPreset2, - characterPreset3: state.characterPreset3, - characterPreset4: state.characterPreset4, - characterPreset5: state.characterPreset5, + characterPreset2: state.characterPreset2, + characterPreset3: state.characterPreset3, + characterPreset4: state.characterPreset4, + characterPreset5: state.characterPreset5,🧰 Tools
🪛 ESLint
[error] 418-418: Delete
·(prettier/prettier)
[error] 419-419: Delete
·(prettier/prettier)
[error] 420-420: Delete
·(prettier/prettier)
[error] 421-421: Delete
·(prettier/prettier)
src/pages/index.tsx (1)
32-38: characterPresetsの定義をより効率的に実装することを提案します。配列の定義をより簡潔にできます。また、型安全性も向上させることができます。
以下の実装を提案します:
- const characterPresets = [ - { key: "characterPreset1", value: settingsStore((s) => s.characterPreset1) }, - { key: "characterPreset2", value: settingsStore((s) => s.characterPreset2) }, - { key: "characterPreset3", value: settingsStore((s) => s.characterPreset3) }, - { key: "characterPreset4", value: settingsStore((s) => s.characterPreset4) }, - { key: "characterPreset5", value: settingsStore((s) => s.characterPreset5) }, - ]; + const characterPresets = Array.from({ length: 5 }, (_, i) => ({ + key: `characterPreset${i + 1}`, + value: settingsStore((s) => s[`characterPreset${i + 1}`]) + }));🧰 Tools
🪛 ESLint
[error] 33-33: Replace
·key:·"characterPreset1",·value:·settingsStore((s)·=>·s.characterPreset1)with⏎······key:·'characterPreset1',⏎······value:·settingsStore((s)·=>·s.characterPreset1),⏎···(prettier/prettier)
[error] 34-34: Replace
·key:·"characterPreset2",·value:·settingsStore((s)·=>·s.characterPreset2)with⏎······key:·'characterPreset2',⏎······value:·settingsStore((s)·=>·s.characterPreset2),⏎···(prettier/prettier)
[error] 35-35: Replace
·key:·"characterPreset3",·value:·settingsStore((s)·=>·s.characterPreset3)with⏎······key:·'characterPreset3',⏎······value:·settingsStore((s)·=>·s.characterPreset3),⏎···(prettier/prettier)
[error] 36-36: Replace
·key:·"characterPreset4",·value:·settingsStore((s)·=>·s.characterPreset4)with⏎······key:·'characterPreset4',⏎······value:·settingsStore((s)·=>·s.characterPreset4),⏎···(prettier/prettier)
[error] 37-37: Replace
·key:·"characterPreset5",·value:·settingsStore((s)·=>·s.characterPreset5)with⏎······key:·'characterPreset5',⏎······value:·settingsStore((s)·=>·s.characterPreset5),⏎···(prettier/prettier)
[error] 38-38: Delete
;(prettier/prettier)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (21)
locales/ar/translation.json(2 hunks)locales/de/translation.json(2 hunks)locales/en/translation.json(2 hunks)locales/es/translation.json(2 hunks)locales/fr/translation.json(2 hunks)locales/hi/translation.json(2 hunks)locales/it/translation.json(2 hunks)locales/ja/translation.json(2 hunks)locales/ko/translation.json(2 hunks)locales/pl/translation.json(2 hunks)locales/pt/translation.json(2 hunks)locales/ru/translation.json(2 hunks)locales/th/translation.json(2 hunks)locales/vi/translation.json(2 hunks)locales/zh/translation.json(2 hunks)src/components/settings/character.tsx(2 hunks)src/features/stores/settings.ts(3 hunks)src/pages/index.tsx(3 hunks)website/document/en/guide/character/common.md(2 hunks)website/document/guide/character/common.md(2 hunks)website/document/zh/guide/character/common.md(2 hunks)
🧰 Additional context used
🪛 ESLint
src/components/settings/character.tsx
[error] 326-326: Replace ·key:·"characterPreset1",·value:·settingsStore((s)·=>·s.characterPreset1) with ⏎······key:·'characterPreset1',⏎······value:·settingsStore((s)·=>·s.characterPreset1),⏎···
(prettier/prettier)
[error] 327-327: Replace ·key:·"characterPreset2",·value:·settingsStore((s)·=>·s.characterPreset2) with ⏎······key:·'characterPreset2',⏎······value:·settingsStore((s)·=>·s.characterPreset2),⏎···
(prettier/prettier)
[error] 328-328: Replace ·key:·"characterPreset3",·value:·settingsStore((s)·=>·s.characterPreset3) with ⏎······key:·'characterPreset3',⏎······value:·settingsStore((s)·=>·s.characterPreset3),⏎···
(prettier/prettier)
[error] 329-329: Replace ·key:·"characterPreset4",·value:·settingsStore((s)·=>·s.characterPreset4) with ⏎······key:·'characterPreset4',⏎······value:·settingsStore((s)·=>·s.characterPreset4),⏎···
(prettier/prettier)
[error] 330-330: Replace ·key:·"characterPreset5",·value:·settingsStore((s)·=>·s.characterPreset5) with ⏎······key:·'characterPreset5',⏎······value:·settingsStore((s)·=>·s.characterPreset5),⏎···
(prettier/prettier)
[error] 331-331: Delete ;
(prettier/prettier)
[error] 332-332: Replace ""); with '')
(prettier/prettier)
[error] 334-334: Replace ·x:·number;·y:·number;·visible:·boolean with ⏎····x:·number⏎····y:·number⏎····visible:·boolean⏎·
(prettier/prettier)
[error] 337-337: Insert ,
(prettier/prettier)
[error] 338-338: Delete ;
(prettier/prettier)
[error] 344-344: Delete ;
(prettier/prettier)
[error] 345-345: Delete ;
(prettier/prettier)
[error] 348-348: Replace ·x:·e.clientX·+·tooltipOffsetX,·y:·e.clientY·+·tooltipOffsetY,·visible:·true·}); with ⏎······x:·e.clientX·+·tooltipOffsetX,⏎······y:·e.clientY·+·tooltipOffsetY,⏎······visible:·true,⏎····})
(prettier/prettier)
[error] 349-349: Delete ;
(prettier/prettier)
[error] 352-352: Delete ;
(prettier/prettier)
[error] 353-353: Delete ;
(prettier/prettier)
[error] 532-532: Delete ;
(prettier/prettier)
[error] 533-533: Delete ;
(prettier/prettier)
[error] 535-535: Delete ;
(prettier/prettier)
[error] 536-536: Delete ;
(prettier/prettier)
[error] 540-540: Delete ;
(prettier/prettier)
[error] 541-541: Delete ;
(prettier/prettier)
[error] 544-544: Delete ;
(prettier/prettier)
[error] 545-545: Replace ""); with '')
(prettier/prettier)
src/pages/index.tsx
[error] 33-33: Replace ·key:·"characterPreset1",·value:·settingsStore((s)·=>·s.characterPreset1) with ⏎······key:·'characterPreset1',⏎······value:·settingsStore((s)·=>·s.characterPreset1),⏎···
(prettier/prettier)
[error] 34-34: Replace ·key:·"characterPreset2",·value:·settingsStore((s)·=>·s.characterPreset2) with ⏎······key:·'characterPreset2',⏎······value:·settingsStore((s)·=>·s.characterPreset2),⏎···
(prettier/prettier)
[error] 35-35: Replace ·key:·"characterPreset3",·value:·settingsStore((s)·=>·s.characterPreset3) with ⏎······key:·'characterPreset3',⏎······value:·settingsStore((s)·=>·s.characterPreset3),⏎···
(prettier/prettier)
[error] 36-36: Replace ·key:·"characterPreset4",·value:·settingsStore((s)·=>·s.characterPreset4) with ⏎······key:·'characterPreset4',⏎······value:·settingsStore((s)·=>·s.characterPreset4),⏎···
(prettier/prettier)
[error] 37-37: Replace ·key:·"characterPreset5",·value:·settingsStore((s)·=>·s.characterPreset5) with ⏎······key:·'characterPreset5',⏎······value:·settingsStore((s)·=>·s.characterPreset5),⏎···
(prettier/prettier)
[error] 38-38: Delete ;
(prettier/prettier)
[error] 42-42: Delete ·
(prettier/prettier)
[error] 50-50: Delete ;
(prettier/prettier)
[error] 52-52: Delete ;
(prettier/prettier)
[error] 55-55: Replace ·systemPrompt:·characterPresets[keyNumber·-·1].value·}); with ⏎············systemPrompt:·characterPresets[keyNumber·-·1].value,⏎··········})
(prettier/prettier)
[error] 57-57: Replace ·presetName:·t(Characterpreset${keyNumber}) with ⏎··············presetName:·t(Characterpreset${keyNumber}),⏎···········
(prettier/prettier)
[error] 63-63: Delete ;
(prettier/prettier)
[error] 64-64: Delete ··
(prettier/prettier)
[error] 65-65: Replace "keydown",·handleKeyDown); with 'keydown',·handleKeyDown)
(prettier/prettier)
[error] 67-67: Replace "keydown",·handleKeyDown); with 'keydown',·handleKeyDown)
(prettier/prettier)
[error] 68-68: Delete ;
(prettier/prettier)
[error] 69-69: Delete ;
(prettier/prettier)
src/features/stores/settings.ts
[error] 273-273: Insert ⏎·······
(prettier/prettier)
[error] 274-274: Insert ⏎·······
(prettier/prettier)
[error] 275-275: Insert ⏎·······
(prettier/prettier)
[error] 276-276: Insert ⏎·······
(prettier/prettier)
[error] 277-277: Insert ⏎·······
(prettier/prettier)
[error] 418-418: Delete ·
(prettier/prettier)
[error] 419-419: Delete ·
(prettier/prettier)
[error] 420-420: Delete ·
(prettier/prettier)
[error] 421-421: Delete ·
(prettier/prettier)
🔇 Additional comments (27)
website/document/guide/character/common.md (1)
46-49: キャラクタープリセット説明セクションの追加について
「### キャラクタープリセット」セクションで、複数のキャラクタープロンプトを保存する方法とキーボードショートカット(Cmd + Shift + 15 / Ctrl + Shift + 15)の利用方法が明記されています。説明文も明瞭で読みやすく、ユーザー向けの手順として適切です。locales/fr/translation.json (1)
57-62: 新規翻訳キー(フランス語)の追加について
フランス語の翻訳ファイルにおいて、「characterpresetInfo」及び「Characterpreset1」~「Characterpreset5」のキーが追加されています。文言は明確で、キーボードショートカットの説明も含んでおり、JSON構文も正しい状態です。locales/ja/translation.json (2)
57-62: 新規翻訳キー(日本語)の追加について
日本語翻訳ファイルに、「characterpresetInfo」と「Characterpreset1」~「Characterpreset5」が追加されています。文言はユーザーにとって分かりやすく、設定項目として問題なく統一されています。
211-212: PresetSwitching メッセージの追加について
Toastsセクションにおいて、「PresetSwitching」キーが追加され、プリセット切り替え時の通知メッセージが適切に設定されています。プレースホルダー「{{presetName}}」も正しく使用されており、ユーザーへのフィードバックが明確です。website/document/zh/guide/character/common.md (1)
18-24: 字元預設セクションの追加について
中国語のドキュメントにおいて、「# 字元預設」セクションが追加され、5種類の環境変数(NEXT_PUBLIC_CHARACTER_PRESET1~5)が定義されています。値は「您是一位名叫 Nique 的 AI 助理。」と設定されており、他言語版との一貫性も保たれています。locales/ru/translation.json (2)
57-62: 新規キャラクタープリセットキーの追加について
新たに追加された "characterpresetInfo" と "Characterpreset1" ~ "Characterpreset5" は、ユーザーがキャラクタープリセット機能を直感的に理解できるよう、詳細な指示文と一貫した命名で記述されています。PRの目的に沿って実装されており、問題はありません。
205-206: Toasts セクションの更新について
"SpeechRecognitionError" の文言更新および新規追加された "PresetSwitching" キーは、ユーザーに対して適切なフィードバックを提供するために有効です。特に、プリセット切替の成功時に {{presetName}} を表示する実装が明確に伝わります。locales/zh/translation.json (2)
57-62: キャラクタープリセット関連の新規エントリ(中国語)の実装について
"characterpresetInfo" および "Characterpreset1" ~ "Characterpreset5" の追加は、PRの仕様に沿っており、ユーザーへの操作説明が明確に伝わる内容です。中国語としての表現も一貫しており、内容に問題は見受けられません。
207-208: PresetSwitching キーの実装について
"PresetSwitching" キーが追加され、キャラクタープリセットの切り替え時に「切換至 {{presetName}}。」という通知が表示されるようになっており、ユーザーへのフィードバックが適切に実現されています。locales/en/translation.json (2)
57-62: Character Preset Entries の追加(英語版)について
"characterpresetInfo" および "Characterpreset1" ~ "Characterpreset5" のエントリが正確に追加され、ユーザーに対してキャラクタープリセット機能の使い方を明確に説明しています。UIの一貫性と利便性が向上していると評価できます。
207-209: PresetSwitching キーの追加(英語版)について
Toasts セクションにおいて、新たに "PresetSwitching" キーが導入され、プリセットの切り替え時に "{{presetName}}" の情報を含む通知が行われるようになっています。この変更はフィードバック機能を強化しており、意図通りの動作が期待できます。locales/es/translation.json (1)
57-62: キャラクタープリセットエントリの追加(スペイン語版)について
"characterpresetInfo" と "Characterpreset1" ~ "Characterpreset5" の追加により、スペイン語ユーザーにもキャラクタープリセット機能の説明が分かりやすく提示されています。命名規則と内容が一貫しており、正しい情報が伝わっています。locales/ko/translation.json (2)
57-62: 캐릭터 프리셋 관련 신규 항목 추가(韓国語版)について
"characterpresetInfo" と "Characterpreset1" ~ "Characterpreset5" のエントリが新たに追加され、韓国語においても操作説明が明確に記述されています。表記や内容が一貫しており、機能実装の目的に適合しています。
207-208: PresetSwitching 키의 추가について
Toasts 섹션에 "PresetSwitching" 키가 추가되어, 프리셋 전환 시 "{{presetName}}으로 전환되었습니다."라는 알림이 표시되도록 구현되었습니다。この変更により、ユーザーへのフィ드バックが明確になり、ユーザビリティが向上しています。locales/vi/translation.json (1)
57-62: 翻訳の実装は適切です各言語ファイルでプリセット機能の翻訳が適切に実装されています。
locales/ar/translation.json (1)
57-62: 翻訳の実装は適切ですアラビア語のプリセット機能の翻訳が適切に実装されています。
locales/hi/translation.json (1)
57-62: 翻訳の実装は適切ですヒンディー語のプリセット機能の翻訳が適切に実装されています。
src/features/stores/settings.ts (2)
126-130: インターフェースの実装は適切ですキャラクタープリセット機能のための新しいプロパティが適切に追加されています。
273-277: 環境変数の初期化は適切です各プリセットが
SYSTEM_PROMPTにフォールバックする実装は適切です。🧰 Tools
🪛 ESLint
[error] 273-273: Insert
⏎·······(prettier/prettier)
[error] 274-274: Insert
⏎·······(prettier/prettier)
[error] 275-275: Insert
⏎·······(prettier/prettier)
[error] 276-276: Insert
⏎·······(prettier/prettier)
[error] 277-277: Insert
⏎·······(prettier/prettier)
locales/th/translation.json (2)
57-62: 翻訳の実装は適切ですキャラクタープリセット機能の翻訳が適切に実装されています。各言語で一貫性が保たれています。
206-207: トースト通知の翻訳は適切ですプリセット切り替え時のトースト通知の翻訳が適切に実装されています。
locales/pt/translation.json (1)
57-62: 翻訳の実装が適切に行われています。キャラクタープリセット機能に関する翻訳が完全に実装されており、キーボードショートカットの説明も明確です。
Also applies to: 205-206
locales/de/translation.json (1)
57-62: 翻訳の実装が適切に行われています。キャラクタープリセット機能に関するドイツ語の翻訳が完全に実装されており、キーボードショートカットの説明も明確です。
Also applies to: 205-206
locales/pl/translation.json (2)
57-62: キャラクタープリセットの新規エントリ追加について
新たに追加されたキー("characterpresetInfo"、"Characterpreset1"~"Characterpreset5")は、ユーザーがキャラクタープリセットの機能を理解しやすいように、具体的な説明とショートカット情報を提供しており、非常に良い実装です。
206-207: エラーメッセージの更新について
"SpeechRecognitionError" の末尾のカンマ追加および新規に導入された "PresetSwitching" は、ユーザーに対するフィードバックを改善しており、一貫性も確保されています。locales/it/translation.json (2)
57-62: キャラクタープリセット情報の追加について
イタリア語版にも、"characterpresetInfo" と "Characterpreset1"~"Characterpreset5" が追加され、ショートカットの操作方法が明確に記載されています。ユーザー向けの説明が分かりやすく、実装内容は適切です。
205-206: エラーメッセージの改善について
"SpeechRecognitionError" の表示内容と、新規に追加された "PresetSwitching" メッセージにより、エラー発生時のユーザーへの案内が強化されています。全体として翻訳の一貫性が保たれており、良好な変更です。
src/pages/index.tsx
Outdated
| useEffect(() => { | ||
| const handleKeyDown = (event: KeyboardEvent) => { | ||
| if ((event.metaKey || event.ctrlKey) && event.shiftKey ) { | ||
| // shiftキーを押しながら数字キーを押すためのマッピング | ||
| const keyMap: { [key: string]: number } = { | ||
| Digit1: 1, | ||
| Digit2: 2, | ||
| Digit3: 3, | ||
| Digit4: 4, | ||
| Digit5: 5, | ||
| }; | ||
|
|
||
| const keyNumber = keyMap[event.code]; | ||
|
|
||
| if (keyNumber) { | ||
| settingsStore.setState({ systemPrompt: characterPresets[keyNumber - 1].value }); | ||
| toastStore.getState().addToast({ | ||
| message: t('Toasts.PresetSwitching', { presetName: t(`Characterpreset${keyNumber}`) }), | ||
| type: 'info', | ||
| tag: `character-preset-switching-${keyNumber}`, | ||
| }) | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| window.addEventListener("keydown", handleKeyDown); | ||
| return () => { | ||
| window.removeEventListener("keydown", handleKeyDown); | ||
| }; | ||
| }, []); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
useEffectの依存配列とパフォーマンスの最適化を提案します。
- 空の依存配列は、
t関数への参照が古くなる可能性があります。 - イベントハンドラーをメモ化することで、不要な再生成を防ぐことができます。
以下の実装を提案します:
+ const handleKeyDown = useCallback((event: KeyboardEvent) => {
+ if ((event.metaKey || event.ctrlKey) && event.shiftKey ) {
+ const keyMap: { [key: string]: number } = {
+ Digit1: 1,
+ Digit2: 2,
+ Digit3: 3,
+ Digit4: 4,
+ Digit5: 5,
+ };
+
+ const keyNumber = keyMap[event.code];
+
+ if (keyNumber) {
+ settingsStore.setState({ systemPrompt: characterPresets[keyNumber - 1].value });
+ toastStore.getState().addToast({
+ message: t('Toasts.PresetSwitching', { presetName: t(`Characterpreset${keyNumber}`) }),
+ type: 'info',
+ tag: `character-preset-switching-${keyNumber}`,
+ })
+ }
+ }
+ }, [t, characterPresets]);
+
useEffect(() => {
- const handleKeyDown = (event: KeyboardEvent) => {
- if ((event.metaKey || event.ctrlKey) && event.shiftKey ) {
- const keyMap: { [key: string]: number } = {
- Digit1: 1,
- Digit2: 2,
- Digit3: 3,
- Digit4: 4,
- Digit5: 5,
- };
-
- const keyNumber = keyMap[event.code];
-
- if (keyNumber) {
- settingsStore.setState({ systemPrompt: characterPresets[keyNumber - 1].value });
- toastStore.getState().addToast({
- message: t('Toasts.PresetSwitching', { presetName: t(`Characterpreset${keyNumber}`) }),
- type: 'info',
- tag: `character-preset-switching-${keyNumber}`,
- })
- }
- }
- };
-
window.addEventListener("keydown", handleKeyDown);
return () => {
window.removeEventListener("keydown", handleKeyDown);
};
- }, []);
+ }, [handleKeyDown]);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| useEffect(() => { | |
| const handleKeyDown = (event: KeyboardEvent) => { | |
| if ((event.metaKey || event.ctrlKey) && event.shiftKey ) { | |
| // shiftキーを押しながら数字キーを押すためのマッピング | |
| const keyMap: { [key: string]: number } = { | |
| Digit1: 1, | |
| Digit2: 2, | |
| Digit3: 3, | |
| Digit4: 4, | |
| Digit5: 5, | |
| }; | |
| const keyNumber = keyMap[event.code]; | |
| if (keyNumber) { | |
| settingsStore.setState({ systemPrompt: characterPresets[keyNumber - 1].value }); | |
| toastStore.getState().addToast({ | |
| message: t('Toasts.PresetSwitching', { presetName: t(`Characterpreset${keyNumber}`) }), | |
| type: 'info', | |
| tag: `character-preset-switching-${keyNumber}`, | |
| }) | |
| } | |
| } | |
| }; | |
| window.addEventListener("keydown", handleKeyDown); | |
| return () => { | |
| window.removeEventListener("keydown", handleKeyDown); | |
| }; | |
| }, []); | |
| const handleKeyDown = useCallback((event: KeyboardEvent) => { | |
| if ((event.metaKey || event.ctrlKey) && event.shiftKey) { | |
| const keyMap: { [key: string]: number } = { | |
| Digit1: 1, | |
| Digit2: 2, | |
| Digit3: 3, | |
| Digit4: 4, | |
| Digit5: 5, | |
| }; | |
| const keyNumber = keyMap[event.code]; | |
| if (keyNumber) { | |
| settingsStore.setState({ systemPrompt: characterPresets[keyNumber - 1].value }); | |
| toastStore.getState().addToast({ | |
| message: t('Toasts.PresetSwitching', { presetName: t(`Characterpreset${keyNumber}`) }), | |
| type: 'info', | |
| tag: `character-preset-switching-${keyNumber}`, | |
| }) | |
| } | |
| } | |
| }, [t, characterPresets]); | |
| useEffect(() => { | |
| window.addEventListener("keydown", handleKeyDown); | |
| return () => { | |
| window.removeEventListener("keydown", handleKeyDown); | |
| }; | |
| }, [handleKeyDown]); |
🧰 Tools
🪛 ESLint
[error] 42-42: Delete ·
(prettier/prettier)
[error] 50-50: Delete ;
(prettier/prettier)
[error] 52-52: Delete ;
(prettier/prettier)
[error] 55-55: Replace ·systemPrompt:·characterPresets[keyNumber·-·1].value·}); with ⏎············systemPrompt:·characterPresets[keyNumber·-·1].value,⏎··········})
(prettier/prettier)
[error] 57-57: Replace ·presetName:·t(Characterpreset${keyNumber}) with ⏎··············presetName:·t(Characterpreset${keyNumber}),⏎···········
(prettier/prettier)
[error] 63-63: Delete ;
(prettier/prettier)
[error] 64-64: Delete ··
(prettier/prettier)
[error] 65-65: Replace "keydown",·handleKeyDown); with 'keydown',·handleKeyDown)
(prettier/prettier)
[error] 67-67: Replace "keydown",·handleKeyDown); with 'keydown',·handleKeyDown)
(prettier/prettier)
[error] 68-68: Delete ;
(prettier/prettier)
[error] 69-69: Delete ;
(prettier/prettier)
|
lintが落ちているため確認します。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/components/settings/character.tsx (2)
366-372: マウス移動ごとのState更新に注意してください。
onMouseMoveで毎回 State を更新すると、多数の再レンダリングが発生する可能性があります。パフォーマンスを考慮する場合、throttleやrequestAnimationFrameなどを検討しても良いでしょう。
549-589: プリセットボタンとツールチップの連動は良好ですがARIA対応を検討してください。
Shiftキー判定でプリセットを上書き・読み込みするロジックは明快です。ツールチップにもキーボード/スクリーンリーダ対応を考慮したARIA属性を追加すれば、アクセシビリティが向上します。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)
📒 Files selected for processing (3)
src/components/settings/character.tsx(2 hunks)src/features/stores/settings.ts(3 hunks)src/pages/index.tsx(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/features/stores/settings.ts
🔇 Additional comments (9)
src/components/settings/character.tsx (5)
325-346: キャラクタープリセット配列の定義が適切です。
特に問題は見当たりませんが、パフォーマンスの観点から、レンダリング毎にsettingsStoreの状態を配列生成で参照する場合はメモ化(useMemoなど)を検討しても良いかもしれません。
347-358: ツールチップ用のState管理は妥当です。
この実装で大きな問題はなく、可読性も良好です。
359-365: ツールチップの定数設定が明確です。
ツールチップの最大表示サイズやオフセットなどを定数化してあるのはメンテナビリティに優れています。
374-376: マウスリーブ時のツールチップ非表示ロジックは分かりやすいです。
問題なく実装されています。
546-548: キャラクタープリセットの説明テキストの追加は適切です。
ユーザーへのガイダンスとして有用なため、翻訳リソースの管理もしやすい実装です。src/pages/index.tsx (4)
1-2: 必要な依存のimport追加が正しく行われています。
特に問題ありません。
18-18:toastStoreのインポートに問題はありません。
トースト通知のためにストアを参照する設計は適切です。
31-53: キャラクタープリセット配列の再定義は正しく機能しそうです。
settingsStoreからの参照方法は一貫しており、変更時もリスクが低いと考えられます。
55-88: useEffect の依存関係に注意してください。
翻訳関数やcharacterPresetsなどを使用しているため、過去のコメントでも指摘があったように依存配列への変数指定によるメモ化が望ましいです。今のままだと翻訳文言が変わったときに再レンダリングされず、トーストの内容が古い可能性があります。
|
ご対応ありがとうございます。 ただ、スマホ利用だとキー操作が使えないので、そこはちょっと私の方で代替案を考えようと思います。 あとUIを少し調整したいのですが、そちらは今ちょうど別のプルリクで対応しているので、マージ後に対応します。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/components/settings/character.tsx (1)
569-652: 🛠️ Refactor suggestionプリセット機能のUI実装は適切ですが、アクセシビリティに課題があります
プリセット機能のUIは機能的に問題ありませんが、アクセシビリティとキーボードナビゲーションのサポートに改善の余地があります。
以下の改善を検討してください:
<button key={key} onClick={() => { // プリセット選択時に内容を表示し、systemPromptも更新 settingsStore.setState({ selectedPresetIndex: index, systemPrompt: value, }) toastStore.getState().addToast({ message: t('Toasts.PresetSwitching', { presetName: customName, }), type: 'info', tag: `character-preset-switching-${index + 1}`, }) }} + role="tab" + aria-selected={isSelected} + tabIndex={0} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + settingsStore.setState({ + selectedPresetIndex: index, + systemPrompt: value, + }); + + toastStore.getState().addToast({ + message: t('Toasts.PresetSwitching', { + presetName: customName, + }), + type: 'info', + tag: `character-preset-switching-${index + 1}`, + }); + } + }} className={`px-4 py-2 rounded-md text-sm ${ isSelected ? 'bg-primary text-white' : 'bg-surface1 hover:bg-surface1-hover text-gray-800' }`} >また、テキストエリアとテキスト入力にもラベルとARIA属性を追加することをお勧めします:
<input type="text" value={customName} onChange={(e) => { settingsStore.setState({ [customNameKey]: e.target.value, }) }} + aria-label={t('PresetNameLabel')} className="px-3 py-2 bg-white border border-gray-300 rounded-md text-sm w-full" placeholder={t(`Characterpreset${index + 1}`)} /><textarea value={systemPrompt} onChange={(e) => { const newValue = e.target.value // システムプロンプトとプリセットの内容を同時に更新 settingsStore.setState({ systemPrompt: newValue, [key]: newValue, }) }} + aria-label={t('SystemPromptLabel')} className="px-3 py-2 bg-white border border-gray-300 rounded-md w-full h-64 text-sm" />
🧹 Nitpick comments (5)
src/components/characterPresetMenu.tsx (2)
45-64: handlePresetClickの実装は適切ですが、アクセシビリティ改善の余地があります関数は適切に実装されていますが、キーボードナビゲーションのサポートが不足しています。
以下の改善を検討してください:
const handlePresetClick = ( key: string, value: string, customName: string, index: number ) => { settingsStore.setState({ systemPrompt: value, selectedPresetIndex: index, }) toastStore.getState().addToast({ message: t('Toasts.PresetSwitching', { presetName: customName, }), type: 'info', tag: `character-preset-switching-${index + 1}`, }) setIsOpen(false) } + +// キーボードイベントハンドラを追加 +const handleKeyDown = ( + e: React.KeyboardEvent, + key: string, + value: string, + customName: string, + index: number +) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + handlePresetClick(key, value, customName, index); + } +}
66-107: メインボタンのアクセシビリティを改善できますボタンの実装は機能的ですが、アクセシビリティの観点からいくつかの改善点があります。
以下の改善を検討してください:
<button onClick={() => setIsOpen(!isOpen)} className="w-12 h-12 rounded-full bg-primary text-white shadow-lg flex items-center justify-center" aria-label={t('CharacterSettingsPrompt')} + aria-expanded={isOpen} + aria-controls="preset-menu" > {isOpen ? ( // 上向き矢印(メニューオープン時)src/components/settings/character.tsx (2)
11-31: Character型の定義は適切ですが、コメントに改善の余地があります型定義は明確ですが、各フィールドの目的を説明するJSDocコメントがあるとより良いでしょう。
以下のように各フィールドグループにコメントを追加することを検討してください:
// Character型の定義 type Character = Pick< SettingsState, + // キャラクター名と表示設定 | 'characterName' + | 'showAssistantText' + | 'showCharacterName' + | 'systemPrompt' + // キャラクタープリセット | 'characterPreset1' | 'characterPreset2' | 'characterPreset3' | 'characterPreset4' | 'characterPreset5' + // プリセット名 | 'customPresetName1' | 'customPresetName2' | 'customPresetName3' | 'customPresetName4' | 'customPresetName5' | 'selectedPresetIndex' - | 'showAssistantText' - | 'showCharacterName' - | 'systemPrompt' + // モデルパス | 'selectedVrmPath' | 'selectedLive2DPath' >
348-369: characterPresetsの配列定義は適切ですが、最適化の余地があります配列の定義は問題ありませんが、メモ化することでパフォーマンスを向上させることができます。
useMemoを使用して配列を最適化することを検討してください:
-const characterPresets = [ +const characterPresets = useMemo(() => [ { key: 'characterPreset1', value: settingsStore((s) => s.characterPreset1), }, { key: 'characterPreset2', value: settingsStore((s) => s.characterPreset2), }, { key: 'characterPreset3', value: settingsStore((s) => s.characterPreset3), }, { key: 'characterPreset4', value: settingsStore((s) => s.characterPreset4), }, { key: 'characterPreset5', value: settingsStore((s) => s.characterPreset5), }, -] +], [])src/features/stores/settings.ts (1)
279-294: ストア内のプリセット初期化は適切ですが、デフォルト値のローカライゼーションに課題がありますプリセットの初期化は機能的に問題ありませんが、ハードコードされた日本語のプリセット名は国際化の観点から課題があります。
以下のように、言語に依存しないデフォルト値を使用し、後で翻訳するアプローチを検討してください:
characterPreset5: process.env.NEXT_PUBLIC_CHARACTER_PRESET5 || SYSTEM_PROMPT, -customPresetName1: 'プリセット1', -customPresetName2: 'プリセット2', -customPresetName3: 'プリセット3', -customPresetName4: 'プリセット4', -customPresetName5: 'プリセット5', +customPresetName1: 'Preset 1', +customPresetName2: 'Preset 2', +customPresetName3: 'Preset 3', +customPresetName4: 'Preset 4', +customPresetName5: 'Preset 5', selectedPresetIndex: 0,このようにすれば、アプリケーションが起動したときに現在の言語に基づいて翻訳されるデフォルト値を持つことができます。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)
📒 Files selected for processing (5)
locales/ja/translation.json(3 hunks)src/components/characterPresetMenu.tsx(1 hunks)src/components/settings/character.tsx(3 hunks)src/features/stores/settings.ts(3 hunks)src/pages/index.tsx(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- locales/ja/translation.json
- src/pages/index.tsx
🧰 Additional context used
🧬 Code Definitions (1)
src/components/settings/character.tsx (1)
src/features/stores/settings.ts (1) (1)
SettingsState(171-177)
🔇 Additional comments (9)
src/components/characterPresetMenu.tsx (4)
1-5: 適切なインポートが行われています必要なモジュールが正しくインポートされており、特に問題は見られません。
6-11: コンポーネントの基本構造が適切に設計されていますReact Hooks(useState)とi18nが適切に設定されており、ストアからの状態取得も問題ありません。
12-43: プリセット配列の構造が明確です各プリセットがkey、value、nameKey、customNameを持つオブジェクトとして定義されており、データ構造が明確です。
137-139: エクスポート宣言は適切ですコンポーネントのエクスポート宣言に問題はありません。
src/components/settings/character.tsx (3)
6-8: インポートステートメントの追加は適切です新しいインポートステートメントが適切に追加されています。
370-381: ツールチップ状態の管理が適切に実装されていますツールチップの状態管理が適切に実装されており、問題ありません。
382-399: ツールチップの定数とイベントハンドラの実装は適切ですツールチップの定数と関連するマウスイベントハンドラが適切に実装されています。
src/features/stores/settings.ts (2)
124-142: Character インターフェースへの新しいプロパティの追加は適切です新しいプリセット関連のプロパティがCharacterインターフェースに適切に追加されています。
434-444: プリセットの永続化設定は適切に実装されています新しいプリセット関連のプロパティが状態の永続化に適切に追加されています。
|
@tokusa-inori いちおうショートカットキーも残していますが、Command + Shift + 数字はショートカットと被りやすい & プリセット切り替えにそこまで操作性が必要なのか不明なので、明日また確認したときに削除するかも知れません。 |
|
@tegnike |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
locales/hi/translation.json (2)
57-62: キャラクタープリセットの翻訳キー追加の確認
新たに追加された「characterpresetInfo」と「Characterpreset1」~「Characterpreset5」は、キャラクタープリセット機能の概要やショートカット操作の説明が明確に記述されており、機能の利用方法がユーザに伝わる内容になっています。
ただし、他の言語ファイルとの文言の一貫性や、ユーザにとって直感的な表現になっているかを再度確認することを推奨します。
205-206: エラーメッセージおよびフィードバック表示文言の調整確認
「SpeechRecognitionError」の変更と、新たに追加された「PresetSwitching」は、それぞれ音声認識エラーおよびプリセット切替時のフィードバックを提供するものとして適切に見受けられます。
他のロケールファイルとの整合性も含め、文言の最終確認をお願いします。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)
📒 Files selected for processing (14)
locales/ar/translation.json(2 hunks)locales/de/translation.json(2 hunks)locales/es/translation.json(2 hunks)locales/fr/translation.json(2 hunks)locales/hi/translation.json(2 hunks)locales/it/translation.json(2 hunks)locales/ja/translation.json(2 hunks)locales/ko/translation.json(2 hunks)locales/pl/translation.json(2 hunks)locales/pt/translation.json(2 hunks)locales/ru/translation.json(2 hunks)locales/th/translation.json(2 hunks)locales/vi/translation.json(2 hunks)locales/zh/translation.json(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (13)
- locales/fr/translation.json
- locales/ar/translation.json
- locales/zh/translation.json
- locales/ru/translation.json
- locales/ja/translation.json
- locales/de/translation.json
- locales/vi/translation.json
- locales/pl/translation.json
- locales/th/translation.json
- locales/es/translation.json
- locales/it/translation.json
- locales/ko/translation.json
- locales/pt/translation.json
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (2)
src/components/settings/character.tsx (1)
569-678: プリセット管理UIの実装が包括的ですプリセット管理UIの実装が以下の点で優れています:
- プリセット選択のタブUIが視覚的にわかりやすい
- 選択中のプリセットが強調表示される
- プリセット名の変更機能が実装されている
- キーボード操作が適切にサポートされている
- プリセット内容の編集とリアルタイムな更新機能
ただし、コードの一部が
src/components/characterPresetMenu.tsxと重複しており、将来的なメンテナンス性に影響する可能性があります。コードの共通部分を抽出して共有ロジックとして実装することを検討してください。例えば、プリセット関連の操作を行うカスタムフックを作成して両方のコンポーネントで使用することで、コードの重複を減らすことができます。
// 例: src/hooks/useCharacterPresets.tsx import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import settingsStore from '@/features/stores/settings'; import toastStore from '@/features/stores/toast'; export function useCharacterPresets() { const { t } = useTranslation(); const selectedPresetIndex = settingsStore(s => s.selectedPresetIndex); const characterPresets = [ // プリセット定義... ]; const handlePresetClick = (key, value, customName, index) => { // 共通のプリセット切り替えロジック }; return { characterPresets, selectedPresetIndex, handlePresetClick }; }locales/de/translation.json (1)
57-62: 新規翻訳キーの追加の確認
"characterpresetInfo" および "Characterpreset1" ~ "Characterpreset5" のエントリは、キャラクタープリセット機能に対応するために追加されています。各エントリが他のロケールファイルと整合性が取れているか、また意図した文言になっているか確認してください。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)
📒 Files selected for processing (18)
locales/ar/translation.json(3 hunks)locales/de/translation.json(3 hunks)locales/en/translation.json(3 hunks)locales/es/translation.json(3 hunks)locales/fr/translation.json(3 hunks)locales/hi/translation.json(3 hunks)locales/it/translation.json(3 hunks)locales/ja/translation.json(2 hunks)locales/ko/translation.json(3 hunks)locales/pl/translation.json(3 hunks)locales/pt/translation.json(3 hunks)locales/ru/translation.json(3 hunks)locales/th/translation.json(3 hunks)locales/vi/translation.json(3 hunks)locales/zh/translation.json(3 hunks)src/components/characterPresetMenu.tsx(1 hunks)src/components/settings/character.tsx(3 hunks)src/features/stores/settings.ts(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (13)
- locales/ru/translation.json
- locales/fr/translation.json
- locales/pl/translation.json
- locales/vi/translation.json
- locales/hi/translation.json
- locales/ko/translation.json
- locales/es/translation.json
- locales/th/translation.json
- locales/ar/translation.json
- locales/it/translation.json
- locales/zh/translation.json
- locales/pt/translation.json
- src/features/stores/settings.ts
🧰 Additional context used
🧬 Code Definitions (1)
src/components/settings/character.tsx (1)
src/features/stores/settings.ts (1) (1)
SettingsState(171-177)
🔇 Additional comments (15)
locales/ja/translation.json (2)
57-62: 新しい翻訳キーが適切に追加されています!キャラクタープリセット機能のための翻訳キーが適切に追加されています。プリセット選択の説明とショートカットキーの情報が明確に記述されています。
211-212: JSONフォーマットの修正と新しいトースト通知の追加
- 行211:カンマの追加によりJSONフォーマットが正しく修正されています
- 行212:プリセット切り替え時の通知メッセージが適切に追加されています
src/components/characterPresetMenu.tsx (7)
1-5: 必要なインポートが適切に設定されています必要なReactフックやストア、多言語サポートのためのライブラリが適切にインポートされています。
6-44: キャラクタープリセットの構造が適切に定義されていますコンポーネントの状態管理とキャラクタープリセットの配列が適切に定義されています。各プリセットにキー、値、名前キー、カスタム名が含まれており、データ構造が整理されています。
45-64: プリセットクリック処理の実装が適切ですプリセットクリック時の処理が適切に実装されています。システムプロンプトの更新、選択インデックスの保存、トースト通知の表示などの機能が実装されています。
66-78: キーボードイベントハンドラは良いアクセシビリティ実装ですキーボードでの操作をサポートするイベントハンドラが実装されており、アクセシビリティの観点から優れています。Enterキーやスペースキーでプリセットを選択できる機能は、キーボードユーザーにとって重要です。
80-123: メインボタンのUI実装とアクセシビリティが適切です
- 固定配置されたボタンの実装が適切です
- アクセシビリティ属性(aria-label、aria-expanded、aria-controls)が正しく設定されています
- SVGアイコンの切り替え表示も適切に実装されています
125-160: プリセットメニューUIの実装が良好ですプリセットメニューのUI実装は以下の点で優れています:
- 視覚的なフィードバック(選択中のアイテムのハイライト表示)
- プリセット名の表示
- 適切なアクセシビリティ属性(role、tabIndex、aria-current)
- キーボードイベントハンドラの連携
161-166: コンポーネントのエクスポートが適切に行われていますコンポーネントが適切にエクスポートされており、他のファイルから簡単にインポートして使用できます。
locales/en/translation.json (2)
57-62: 英語の翻訳キーが適切に追加されていますキャラクタープリセット機能のための英語の翻訳キーが適切に追加されています。プリセット選択の説明とショートカットキーの情報が明確に記述されています。
208-209: トースト通知の翻訳が追加されています音声認識関連のメッセージとプリセット切り替え通知の翻訳が適切に追加されています。
src/components/settings/character.tsx (3)
6-31: Character型の定義が適切に拡張されています
Character型がSettingsStateから必要なプロパティをPickを使って選択し、明確に型定義されています。キャラクタープリセットに関連するプロパティが適切に含まれています。
348-369: プリセット配列の定義が適切ですキャラクタープリセットの配列定義が適切に実装されています。各プリセットがキーと値を持ち、settingsStoreから値を取得しています。
370-399: ツールチップ機能の実装が適切ですツールチップのための状態管理と表示・非表示の制御が適切に実装されています。位置調整のための定数も明確に定義されています。
locales/de/translation.json (1)
205-206: トーストメッセージの更新確認
"SpeechRecognitionError" の表現修正と "PresetSwitching" の追加は、ユーザーへのフィードバックとして適切です。実際の動作と合致しているか、また文言の一貫性を再確認してください。
| "DocumentationDescription": "For detailed usage and tutorials of AITuberKit, please visit the URL below.", | ||
| "CharacterpresetInfo": "Selecting a preset will change the character prompt.\nYou can use shortcuts with Cmd + Shift + 1~5 (Mac) / Ctrl + Shift + 1~5 (Windows)." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
重複する翻訳キーが存在します
CharacterpresetInfoというキーが57行目と255行目に重複して定義されています。これにより、後者のみが有効になり、予期しない動作を引き起こす可能性があります。
以下のいずれかの修正を行ってください:
- 重複するキーを削除する
- 異なるキー名に変更する(例:
CharacterpresetInfoShort)
- "CharacterpresetInfo": "Selecting a preset will change the character prompt.\nYou can use shortcuts with Cmd + Shift + 1~5 (Mac) / Ctrl + Shift + 1~5 (Windows)."
+ "CharacterpresetInfoShort": "Selecting a preset will change the character prompt.\nYou can use shortcuts with Cmd + Shift + 1~5 (Mac) / Ctrl + Shift + 1~5 (Windows)."📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "DocumentationDescription": "For detailed usage and tutorials of AITuberKit, please visit the URL below.", | |
| "CharacterpresetInfo": "Selecting a preset will change the character prompt.\nYou can use shortcuts with Cmd + Shift + 1~5 (Mac) / Ctrl + Shift + 1~5 (Windows)." | |
| "DocumentationDescription": "For detailed usage and tutorials of AITuberKit, please visit the URL below.", | |
| "CharacterpresetInfoShort": "Selecting a preset will change the character prompt.\nYou can use shortcuts with Cmd + Shift + 1~5 (Mac) / Ctrl + Shift + 1~5 (Windows)." |
locales/de/translation.json
Outdated
| "DocumentationDescription": "Detaillierte Anleitungen und Tutorials zur Verwendung von AITuberKit finden Sie unter der folgenden URL.", | ||
| "CharacterpresetInfo": "Wenn Sie ein Preset auswählen, wird der Charakterprompt geändert.\nCmd + Shift + 1~5 (Mac) / Ctrl + Shift + 1~5 (Windows) ermöglicht Shortcuts." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
重複キーの可能性についての警告
行57で "characterpresetInfo" が定義されているのに対し、行252で大文字始まりの "CharacterpresetInfo" が再定義されています。JSON ではキーが重複すると予期せぬ挙動を引き起こす可能性があるため、キー名を統一するか、不要なエントリを削除するようご検討ください。
…eset キャラクタープリセット機能を実装

取り込みご検討をお願いいたします。
関連するイシュー
なし
やったこと
キャラクタープリセット機能の追加
できるようになること(ユーザ目線)
設定画面からクリックで呼び出し、キャラクタープロンプトへ上書きできる。
Shiftキーを押しながらプリセットを選ぶと、現在のキャラクタープロンプトがプリセットに保存される。
Cmd + Shift + 1
5 (Mac) / Ctrl + Shift + 15 (Windows)でショートカットができる。動作確認
キャラクタープロンプトが上書きされることを確認。キャラクタープリセットが上書きできることを確認
動作確認環境: Windows11 MS Edge localLLM
その他
ショートカットの実装をindex.tsxで行っています。menu.tsxで実装した際、process.envが呼び出せなかったためです。独自のファイルを作成してもprocess.envを呼び出せず、index.tsxで正常な動作を確認できた形になります。
なにか気づいた点がありましたらメッセージをお願いします。
プリセット名の変更機能は実装していません。ただしtranslation.jsonにあるプリセット名(Characterpreset1など)をいじくれば変更できます。
Summary by CodeRabbit
新機能
バグ修正
ドキュメント