From e32cd7d648c6429ebfc9f696bd6f063d87c3cef8 Mon Sep 17 00:00:00 2001 From: RyuJongJin <266630912+RyuJongJin@users.noreply.github.com> Date: Mon, 12 Oct 2026 02:03:54 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8B=A8=EC=B6=95=ED=82=A4=20=EC=95=88?= =?UTF-8?q?=EB=82=B4=20'(Alt+=E2=86=90)'=20=EB=93=B1=EC=9D=80=20PC=20?= =?UTF-8?q?=EC=97=90=EC=84=9C=EB=A7=8C=20-=20=ED=83=9C=EB=B8=94=EB=A6=BF?= =?UTF-8?q?=20=C2=B7=20=ED=8F=B0=EC=9D=80=20=EC=9D=B4=EB=A6=84=EB=A7=8C=20?= =?UTF-8?q?(194)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 사용자 편의 · 접근성 (기기 확인): 키보드가 없는 태블릿에 Alt 안내가 보이고 TalkBack 도 읽었다 - keyHint Co-Authored-By: Claude Opus 5.5 --- assets/l10n/en.json | 19 +++++++------------ assets/l10n/ja.json | 19 +++++++------------ assets/l10n/zh-Hans.json | 19 +++++++------------ lib/ui/browser_page.dart | 17 +++++++++-------- lib/ui/explorer_page.dart | 5 +++-- lib/ui/key_hint.dart | 5 +++++ lib/ui/subtitle_editor_page.dart | 3 ++- test/key_hint_test.dart | 11 +++++++++++ 8 files changed, 51 insertions(+), 47 deletions(-) create mode 100644 lib/ui/key_hint.dart create mode 100644 test/key_hint_test.dart diff --git a/assets/l10n/en.json b/assets/l10n/en.json index 3bea859..8dcb56b 100644 --- a/assets/l10n/en.json +++ b/assets/l10n/en.json @@ -689,7 +689,7 @@ "다음": "Next", "다음 (N)": "Next (N)", "다음 {0}개 기다림": "{0} more waiting", - "다음 페이지 (Alt+→)": "Next page (Alt+→)", + "다음 페이지": "Next page", "다음부터 묻지 않기 (환경 설정 > 실행 에서 바꿀 수 있음)": "Don't ask again (can be changed in Settings > Run)", "단계": "Steps", "단축키 해제": "Unregister hotkey", @@ -777,7 +777,6 @@ "두 창으로": "Two panes", "두 창으로 보기 (좌우)": "Show two panes (side by side)", "뒤로": "Back", - "뒤로 (Alt+←)": "Back (Alt+←)", "뒤로 보내고 계속": "Keep running in background", "뒤에서 계속": "Continue in background", "드라이브의 맨 위 폴더는 지울 수 없습니다": "The top folder of a drive can't be deleted", @@ -1078,7 +1077,7 @@ "새 화면 \"AI 그림\" 을 위쪽 이동 버튼에 넣었습니다 (글 → 그림 · 그림 → 그림, 모델은 환경 설정에서 받기). 끄기: 환경 설정 > 컴포넌트": "Added a new \"AI images\" screen to the top navigation buttons (text → image · image → image; download models in Settings). To turn off: Settings > Components", "새로 고침": "Refresh", "새로 넣은 비밀번호는 아직 저장되지 않았습니다. 앱을 끄면 사라집니다.": "The password you entered has not been saved yet. It will be lost when you close the app.", - "새로고침 (F5)": "Reload (F5)", + "새로고침": "Reload", "색 보정": "Color correction", "색온도": "Temperature", "서버 · 서비스 (기기 밖)": "Servers · services (off device)", @@ -1236,7 +1235,7 @@ "압축 파일 안에 없습니다": "Not in the archive", "압축 파일 안에 프로그램이 없습니다.": "The program is not in the archive.", "압축을 풀 수 없습니다: {0}": "Cannot extract the archive: {0}", - "앞으로 (Alt+→)": "Forward (Alt+→)", + "앞으로": "Forward", "앞의 rsync 가 끝난 뒤에 하세요.": "Wait until the previous rsync finishes.", "앞의 복사 · 이동이 끝난 뒤에 하세요.": "Wait until the current copy · move finishes.", "앱 목록 · 홈 화면과 앱 안 왼쪽 위 버튼의 아이콘입니다. 바꾸면 홈 화면에 둔 아이콘이 없어질 수 있어 앱 목록에서 다시 끌어다 놓아야 할 수 있습니다": "Icon in the app list, home screen and the top-left button in the app. After changing it, the icon on your home screen may disappear and you may need to drag it from the app list again", @@ -1551,7 +1550,7 @@ "이전": "Previous", "이전 (P)": "Previous (P)", "이전 설정을 되살렸습니다": "Previous settings restored", - "이전 페이지 (Alt+←)": "Previous page (Alt+←)", + "이전 페이지": "Previous page", "이탈리아어": "Italian", "인도네시아어": "Indonesian", "인식된 말이 없습니다.": "No speech was recognized.", @@ -1631,7 +1630,7 @@ "작업 취소": "Cancel job", "작업 현황": "Job status", "작업 현황 닫기": "Close job status", - "작업 현황 보기 · 화면 분할 (Ctrl+Shift+J)": "Show job status · split screen (Ctrl+Shift+J)", + "작업 현황 보기 · 화면 분할": "Show job status · split screen", "작업 확인 (진행 중인 작업 없음)": "Job check (no jobs in progress)", "작업이 진행 중입니다": "Tasks are running", "작업하다 남은 임시 파일 · 받다 만 다운로드 (.part 등) · 받다 만 AI 모델 · 업데이트하고 남은 파일 · 지난 작업 기록을 찾아 지웁니다. 받은 동영상 · 만든 MKV · 자막은 지우지 않고, 진행 중인 작업 · 다운로드가 쓰는 것은 건너뜁니다": "Finds and deletes temporary files left from jobs · unfinished downloads (.part etc.) · unfinished AI models · update leftovers · old job logs. Downloaded videos · made MKVs · subtitles are not deleted, and anything used by running jobs · downloads is skipped", @@ -1648,7 +1647,7 @@ "재생 속도": "Playback speed", "재생 오류: {0}": "Playback error: {0}", "재생/일시정지 (Space)": "Play/pause (Space)", - "재생/정지 (Ctrl+Space)": "Play/stop (Ctrl+Space)", + "재생/정지": "Play/stop", "재생목록 불러오는 중… {0}": "Loading playlist… {0}", "재생목록 주소면 목록 전체 받기": "Download the whole list for playlist URLs", "재생목록을 읽을 수 없습니다: {0}": "Cannot read the playlist: {0}", @@ -1738,7 +1737,7 @@ "주말 종일": "Weekends, all day", "주소": "Address", "주소 (http · https · 마그넷) 를 찾지 못했거나 이미 받는 중입니다.": "No address (http · https · magnet) found, or it's already downloading.", - "주소 입력 또는 검색 (Ctrl+L)": "Enter an address or search (Ctrl+L)", + "주소 입력 또는 검색": "Enter an address or search", "주소로 열기": "Open by address", "주소를 https 로 바꾸고 다시 확인": "Switch the address to https and check again", "주소에 영상이 없습니다 (404)": "No video at this address (404)", @@ -1754,15 +1753,11 @@ "즐겨찾기 HTML 가져오기": "Import bookmarks HTML", "즐겨찾기 검색 (이름 · 주소)": "Search bookmarks (name · address)", "즐겨찾기 관리": "Manage bookmarks", - "즐겨찾기 관리 (Ctrl+Shift+B)": "Manage bookmarks (Ctrl+Shift+B)", "즐겨찾기 관리자": "Bookmark manager", - "즐겨찾기 관리자 (Ctrl+Shift+O)": "Bookmark manager (Ctrl+Shift+O)", "즐겨찾기 관리자에서 보기": "Show in bookmark manager", "즐겨찾기 내보내기 (HTML)": "Export bookmarks (HTML)", "즐겨찾기 수정": "Edit bookmark", - "즐겨찾기 수정 (Ctrl+D)": "Edit bookmark (Ctrl+D)", "즐겨찾기 추가": "Add bookmark", - "즐겨찾기 추가 (Ctrl+D)": "Add bookmark (Ctrl+D)", "즐겨찾기 추가…": "Add bookmark…", "즐겨찾기 추가됨": "Bookmark added", "즐겨찾기 표시줄": "Bookmarks bar", diff --git a/assets/l10n/ja.json b/assets/l10n/ja.json index 22b6828..641f3d6 100644 --- a/assets/l10n/ja.json +++ b/assets/l10n/ja.json @@ -689,7 +689,7 @@ "다음": "次へ", "다음 (N)": "次へ(N)", "다음 {0}개 기다림": "次の {0} 件が待機中", - "다음 페이지 (Alt+→)": "次のページ(Alt+→)", + "다음 페이지": "次のページ", "다음부터 묻지 않기 (환경 설정 > 실행 에서 바꿀 수 있음)": "次回から確認しない(環境設定 > 実行 で変更できます)", "단계": "ステップ", "단축키 해제": "ショートカット解除", @@ -777,7 +777,6 @@ "두 창으로": "2 画面に", "두 창으로 보기 (좌우)": "2 画面で表示 (左右)", "뒤로": "戻る", - "뒤로 (Alt+←)": "戻る (Alt+←)", "뒤로 보내고 계속": "裏で続ける", "뒤에서 계속": "バックグラウンドで続ける", "드라이브의 맨 위 폴더는 지울 수 없습니다": "ドライブの最上位フォルダーは削除できません", @@ -1078,7 +1077,7 @@ "새 화면 \"AI 그림\" 을 위쪽 이동 버튼에 넣었습니다 (글 → 그림 · 그림 → 그림, 모델은 환경 설정에서 받기). 끄기: 환경 설정 > 컴포넌트": "新しい画面「AI 画像」を上部の移動ボタンに追加しました (テキスト → 画像・画像 → 画像、モデルは環境設定でダウンロード)。オフにする: 環境設定 > コンポーネント", "새로 고침": "更新", "새로 넣은 비밀번호는 아직 저장되지 않았습니다. 앱을 끄면 사라집니다.": "入力したパスワードはまだ保存されていません。アプリを終了すると消えます。", - "새로고침 (F5)": "再読み込み(F5)", + "새로고침": "再読み込み", "색 보정": "カラー補正", "색온도": "色温度", "서버 · 서비스 (기기 밖)": "サーバー・サービス (端末外)", @@ -1236,7 +1235,7 @@ "압축 파일 안에 없습니다": "圧縮ファイル内にありません", "압축 파일 안에 프로그램이 없습니다.": "圧縮ファイル内にプログラムがありません。", "압축을 풀 수 없습니다: {0}": "圧縮ファイルを展開できません: {0}", - "앞으로 (Alt+→)": "進む (Alt+→)", + "앞으로": "進む", "앞의 rsync 가 끝난 뒤에 하세요.": "前の rsync が終わってから行ってください。", "앞의 복사 · 이동이 끝난 뒤에 하세요.": "前のコピー · 移動が終わってから行ってください。", "앱 목록 · 홈 화면과 앱 안 왼쪽 위 버튼의 아이콘입니다. 바꾸면 홈 화면에 둔 아이콘이 없어질 수 있어 앱 목록에서 다시 끌어다 놓아야 할 수 있습니다": "アプリ一覧・ホーム画面とアプリ内左上のボタンのアイコンです。変更するとホーム画面のアイコンが消えることがあり、アプリ一覧から再度ドラッグする必要がある場合があります", @@ -1551,7 +1550,7 @@ "이전": "前へ", "이전 (P)": "前へ(P)", "이전 설정을 되살렸습니다": "以前の設定を復元しました", - "이전 페이지 (Alt+←)": "前のページ(Alt+←)", + "이전 페이지": "前のページ", "이탈리아어": "イタリア語", "인도네시아어": "インドネシア語", "인식된 말이 없습니다.": "認識された音声がありません。", @@ -1631,7 +1630,7 @@ "작업 취소": "作業をキャンセル", "작업 현황": "作業状況", "작업 현황 닫기": "作業状況を閉じる", - "작업 현황 보기 · 화면 분할 (Ctrl+Shift+J)": "作業状況を表示・画面分割(Ctrl+Shift+J)", + "작업 현황 보기 · 화면 분할": "作業状況を表示・画面分割", "작업 확인 (진행 중인 작업 없음)": "作業確認(進行中の作業なし)", "작업이 진행 중입니다": "作業中です", "작업하다 남은 임시 파일 · 받다 만 다운로드 (.part 등) · 받다 만 AI 모델 · 업데이트하고 남은 파일 · 지난 작업 기록을 찾아 지웁니다. 받은 동영상 · 만든 MKV · 자막은 지우지 않고, 진행 중인 작업 · 다운로드가 쓰는 것은 건너뜁니다": "作業で残った一時ファイル・ダウンロード途中のファイル(.part など)・途中の AI モデル・更新の残り・古い作業記録を探して削除します。ダウンロードした動画・作成した MKV・字幕は削除せず、進行中の作業・ダウンロードが使っているものはスキップします", @@ -1648,7 +1647,7 @@ "재생 속도": "再生速度", "재생 오류: {0}": "再生エラー: {0}", "재생/일시정지 (Space)": "再生/一時停止(Space)", - "재생/정지 (Ctrl+Space)": "再生/停止(Ctrl+Space)", + "재생/정지": "再生/停止", "재생목록 불러오는 중… {0}": "再生リストを読み込み中… {0}", "재생목록 주소면 목록 전체 받기": "再生リストの URL ならリスト全体をダウンロード", "재생목록을 읽을 수 없습니다: {0}": "再生リストを読めません: {0}", @@ -1738,7 +1737,7 @@ "주말 종일": "週末 終日", "주소": "アドレス", "주소 (http · https · 마그넷) 를 찾지 못했거나 이미 받는 중입니다.": "アドレス (http・https・マグネット) が見つからないか、すでにダウンロード中です。", - "주소 입력 또는 검색 (Ctrl+L)": "アドレスを入力または検索(Ctrl+L)", + "주소 입력 또는 검색": "アドレスを入力または検索", "주소로 열기": "アドレスで開く", "주소를 https 로 바꾸고 다시 확인": "アドレスを https に変えてもう一度確認", "주소에 영상이 없습니다 (404)": "このアドレスに動画がありません (404)", @@ -1754,15 +1753,11 @@ "즐겨찾기 HTML 가져오기": "ブックマーク HTML を取り込む", "즐겨찾기 검색 (이름 · 주소)": "ブックマークを検索(名前・アドレス)", "즐겨찾기 관리": "ブックマーク管理", - "즐겨찾기 관리 (Ctrl+Shift+B)": "ブックマーク管理(Ctrl+Shift+B)", "즐겨찾기 관리자": "ブックマークマネージャー", - "즐겨찾기 관리자 (Ctrl+Shift+O)": "ブックマークマネージャー(Ctrl+Shift+O)", "즐겨찾기 관리자에서 보기": "ブックマークマネージャーで表示", "즐겨찾기 내보내기 (HTML)": "ブックマークを書き出す(HTML)", "즐겨찾기 수정": "ブックマークを編集", - "즐겨찾기 수정 (Ctrl+D)": "ブックマークを編集(Ctrl+D)", "즐겨찾기 추가": "ブックマークを追加", - "즐겨찾기 추가 (Ctrl+D)": "ブックマークを追加(Ctrl+D)", "즐겨찾기 추가…": "ブックマークを追加…", "즐겨찾기 추가됨": "ブックマークを追加しました", "즐겨찾기 표시줄": "ブックマークバー", diff --git a/assets/l10n/zh-Hans.json b/assets/l10n/zh-Hans.json index 1f464b8..36a8462 100644 --- a/assets/l10n/zh-Hans.json +++ b/assets/l10n/zh-Hans.json @@ -689,7 +689,7 @@ "다음": "下一个", "다음 (N)": "下一个(N)", "다음 {0}개 기다림": "另有 {0} 个等待中", - "다음 페이지 (Alt+→)": "下一页(Alt+→)", + "다음 페이지": "下一页", "다음부터 묻지 않기 (환경 설정 > 실행 에서 바꿀 수 있음)": "下次不再询问(可在 设置 > 运行 中更改)", "단계": "步数", "단축키 해제": "注销快捷键", @@ -777,7 +777,6 @@ "두 창으로": "双窗格", "두 창으로 보기 (좌우)": "以双窗格显示 (左右)", "뒤로": "后退", - "뒤로 (Alt+←)": "后退 (Alt+←)", "뒤로 보내고 계속": "转到后台继续", "뒤에서 계속": "在后台继续", "드라이브의 맨 위 폴더는 지울 수 없습니다": "无法删除驱动器的根文件夹", @@ -1078,7 +1077,7 @@ "새 화면 \"AI 그림\" 을 위쪽 이동 버튼에 넣었습니다 (글 → 그림 · 그림 → 그림, 모델은 환경 설정에서 받기). 끄기: 환경 설정 > 컴포넌트": "已将新画面“AI 图片”加入顶部导航按钮 (文字 → 图片 · 图片 → 图片,模型在设置中下载)。关闭: 设置 > 组件", "새로 고침": "刷新", "새로 넣은 비밀번호는 아직 저장되지 않았습니다. 앱을 끄면 사라집니다.": "输入的密码尚未保存。关闭应用后会丢失。", - "새로고침 (F5)": "刷新(F5)", + "새로고침": "刷新", "색 보정": "色彩校正", "색온도": "色温", "서버 · 서비스 (기기 밖)": "服务器 · 服务 (设备外)", @@ -1236,7 +1235,7 @@ "압축 파일 안에 없습니다": "压缩文件中没有", "압축 파일 안에 프로그램이 없습니다.": "压缩文件中没有程序。", "압축을 풀 수 없습니다: {0}": "无法解压: {0}", - "앞으로 (Alt+→)": "前进 (Alt+→)", + "앞으로": "前进", "앞의 rsync 가 끝난 뒤에 하세요.": "请等上一个 rsync 结束后再运行。", "앞의 복사 · 이동이 끝난 뒤에 하세요.": "请等待前一个复制 · 移动完成。", "앱 목록 · 홈 화면과 앱 안 왼쪽 위 버튼의 아이콘입니다. 바꾸면 홈 화면에 둔 아이콘이 없어질 수 있어 앱 목록에서 다시 끌어다 놓아야 할 수 있습니다": "应用列表、主屏幕以及应用内左上角按钮的图标。更改后主屏幕上的图标可能会消失,可能需要从应用列表重新拖放", @@ -1551,7 +1550,7 @@ "이전": "上一个", "이전 (P)": "上一个(P)", "이전 설정을 되살렸습니다": "已恢复之前的设置", - "이전 페이지 (Alt+←)": "上一页(Alt+←)", + "이전 페이지": "上一页", "이탈리아어": "意大利语", "인도네시아어": "印尼语", "인식된 말이 없습니다.": "未识别到语音。", @@ -1631,7 +1630,7 @@ "작업 취소": "取消任务", "작업 현황": "任务状态", "작업 현황 닫기": "关闭任务状态", - "작업 현황 보기 · 화면 분할 (Ctrl+Shift+J)": "显示任务状态 · 分屏(Ctrl+Shift+J)", + "작업 현황 보기 · 화면 분할": "显示任务状态 · 分屏", "작업 확인 (진행 중인 작업 없음)": "任务检查(没有进行中的任务)", "작업이 진행 중입니다": "任务正在进行", "작업하다 남은 임시 파일 · 받다 만 다운로드 (.part 등) · 받다 만 AI 모델 · 업데이트하고 남은 파일 · 지난 작업 기록을 찾아 지웁니다. 받은 동영상 · 만든 MKV · 자막은 지우지 않고, 진행 중인 작업 · 다운로드가 쓰는 것은 건너뜁니다": "查找并删除任务残留的临时文件 · 未完成的下载(.part 等)· 未下载完的 AI 模型 · 更新残留 · 旧任务记录。不会删除已下载的视频 · 制作的 MKV · 字幕,正在进行的任务 · 下载所用的文件会跳过", @@ -1648,7 +1647,7 @@ "재생 속도": "播放速度", "재생 오류: {0}": "播放错误: {0}", "재생/일시정지 (Space)": "播放/暂停(Space)", - "재생/정지 (Ctrl+Space)": "播放/停止(Ctrl+Space)", + "재생/정지": "播放/停止", "재생목록 불러오는 중… {0}": "正在加载播放列表… {0}", "재생목록 주소면 목록 전체 받기": "如果是播放列表地址则下载整个列表", "재생목록을 읽을 수 없습니다: {0}": "无法读取播放列表: {0}", @@ -1738,7 +1737,7 @@ "주말 종일": "周末 全天", "주소": "地址", "주소 (http · https · 마그넷) 를 찾지 못했거나 이미 받는 중입니다.": "未找到地址 (http · https · 磁力),或已在下载。", - "주소 입력 또는 검색 (Ctrl+L)": "输入地址或搜索(Ctrl+L)", + "주소 입력 또는 검색": "输入地址或搜索", "주소로 열기": "按地址打开", "주소를 https 로 바꾸고 다시 확인": "将地址改为 https 并重新检查", "주소에 영상이 없습니다 (404)": "此地址没有视频 (404)", @@ -1754,15 +1753,11 @@ "즐겨찾기 HTML 가져오기": "导入书签 HTML", "즐겨찾기 검색 (이름 · 주소)": "搜索书签(名称 · 地址)", "즐겨찾기 관리": "管理书签", - "즐겨찾기 관리 (Ctrl+Shift+B)": "管理书签(Ctrl+Shift+B)", "즐겨찾기 관리자": "书签管理器", - "즐겨찾기 관리자 (Ctrl+Shift+O)": "书签管理器(Ctrl+Shift+O)", "즐겨찾기 관리자에서 보기": "在书签管理器中显示", "즐겨찾기 내보내기 (HTML)": "导出书签(HTML)", "즐겨찾기 수정": "编辑书签", - "즐겨찾기 수정 (Ctrl+D)": "编辑书签(Ctrl+D)", "즐겨찾기 추가": "添加书签", - "즐겨찾기 추가 (Ctrl+D)": "添加书签(Ctrl+D)", "즐겨찾기 추가…": "添加书签…", "즐겨찾기 추가됨": "已添加书签", "즐겨찾기 표시줄": "书签栏", diff --git a/lib/ui/browser_page.dart b/lib/ui/browser_page.dart index f3c5232..e4040e5 100644 --- a/lib/ui/browser_page.dart +++ b/lib/ui/browser_page.dart @@ -24,6 +24,7 @@ import 'app_actions.dart'; import 'bookmark_ui.dart'; import 'confirm.dart'; import 'downloads_page.dart'; +import 'key_hint.dart'; import 'theme.dart'; import 'work_panel.dart'; import '../l10n/tr.dart'; @@ -604,11 +605,11 @@ class _BrowserPageState extends State with RouteAware { const SizedBox(width: 4), ], // 웹 페이지 이동 (앱 화면 이동인 왼쪽 버튼과 구분되는 모양) - btn(Icons.arrow_back_ios_new, tr('이전 페이지 (Alt+←)'), _canBack ? () => _nav?.back() : null), - btn(Icons.arrow_forward_ios, tr('다음 페이지 (Alt+→)'), _canFwd ? () => _nav?.forward() : null), + btn(Icons.arrow_back_ios_new, keyHint(tr('이전 페이지'), 'Alt+←'), _canBack ? () => _nav?.back() : null), + btn(Icons.arrow_forward_ios, keyHint(tr('다음 페이지'), 'Alt+→'), _canFwd ? () => _nav?.forward() : null), _progress < 1 ? btn(Icons.close, tr('중지'), () => _nav?.stop()) - : btn(Icons.refresh, tr('새로고침 (F5)'), () => _nav?.reload()), + : btn(Icons.refresh, keyHint(tr('새로고침'), 'F5'), () => _nav?.reload()), if (!compact) btn(Icons.home_outlined, tr('홈'), () => _go(widget.c.settings.homeUrl)), const SizedBox(width: 6), Expanded( @@ -620,12 +621,12 @@ class _BrowserPageState extends State with RouteAware { isDense: true, filled: true, fillColor: JjColors.bg, - hintText: tr('주소 입력 또는 검색 (Ctrl+L)'), + hintText: keyHint(tr('주소 입력 또는 검색'), 'Ctrl+L'), prefixIcon: Icon(_url.startsWith('https') ? Icons.lock_outline : Icons.public, size: 16), prefixIconConstraints: const BoxConstraints(minWidth: 32), border: OutlineInputBorder(borderRadius: BorderRadius.circular(18), borderSide: BorderSide.none), suffixIcon: IconButton( - tooltip: starred ? tr('즐겨찾기 수정 (Ctrl+D)') : tr('즐겨찾기 추가 (Ctrl+D)'), + tooltip: starred ? keyHint(tr('즐겨찾기 수정'), 'Ctrl+D') : keyHint(tr('즐겨찾기 추가'), 'Ctrl+D'), icon: Icon(starred ? Icons.star : Icons.star_border, size: 18, color: starred ? Colors.amber : JjColors.textDim), onPressed: _star, @@ -686,10 +687,10 @@ class _BrowserPageState extends State with RouteAware { ), ), if (!compact) - btn(_work ? Icons.view_sidebar : Icons.view_sidebar_outlined, tr('작업 현황 보기 · 화면 분할 (Ctrl+Shift+J)'), + btn(_work ? Icons.view_sidebar : Icons.view_sidebar_outlined, keyHint(tr('작업 현황 보기 · 화면 분할'), 'Ctrl+Shift+J'), _toggleWork, color: widget.c.busy ? JjColors.accent : null), if (!compact) - btn(_panel ? Icons.bookmarks : Icons.bookmarks_outlined, tr('즐겨찾기 관리 (Ctrl+Shift+B)'), + btn(_panel ? Icons.bookmarks : Icons.bookmarks_outlined, keyHint(tr('즐겨찾기 관리'), 'Ctrl+Shift+B'), () => setState(() => _panel = !_panel)) else PopupMenuButton( @@ -1404,7 +1405,7 @@ class _BookmarkPanelState extends State { const Spacer(), if (widget.onOpenManager != null) IconButton( - tooltip: tr('즐겨찾기 관리자 (Ctrl+Shift+O)'), + tooltip: keyHint(tr('즐겨찾기 관리자'), 'Ctrl+Shift+O'), iconSize: 18, icon: const Icon(Icons.open_in_full), onPressed: () => widget.onOpenManager!(folderId: _folderId), diff --git a/lib/ui/explorer_page.dart b/lib/ui/explorer_page.dart index dc157ae..54d52f9 100644 --- a/lib/ui/explorer_page.dart +++ b/lib/ui/explorer_page.dart @@ -24,6 +24,7 @@ import '../core/webdav.dart' show DavRegistry; import '../platform/android/android_storage.dart'; import 'app_actions.dart'; import 'explorer_look.dart'; +import 'key_hint.dart'; import 'monitor_page.dart'; import 'player_page.dart'; import 'rsync_setup.dart'; @@ -3164,13 +3165,13 @@ class _ExplorerPageState extends State { List _headerStart(_Pane pane) => [ // 75: 이 창의 뒤로 · 앞으로 (가 본 폴더) IconButton( - tooltip: tr('뒤로 (Alt+←)'), + tooltip: keyHint(tr('뒤로'), 'Alt+←'), visualDensity: VisualDensity.compact, icon: const Icon(Icons.arrow_back, size: 16), onPressed: pane.back.isEmpty ? null : () => _travel(pane, forward: false), ), IconButton( - tooltip: tr('앞으로 (Alt+→)'), + tooltip: keyHint(tr('앞으로'), 'Alt+→'), visualDensity: VisualDensity.compact, icon: const Icon(Icons.arrow_forward, size: 16), onPressed: pane.forward.isEmpty ? null : () => _travel(pane, forward: true), diff --git a/lib/ui/key_hint.dart b/lib/ui/key_hint.dart new file mode 100644 index 0000000..a73ae34 --- /dev/null +++ b/lib/ui/key_hint.dart @@ -0,0 +1,5 @@ +import 'dart:io'; + +/// 194: 단축키 안내 "(Alt+←)" 는 키보드를 쓰는 PC 에서만 붙인다. +/// 태블릿 · 폰에서는 이름만 (누를 키가 없고, TalkBack 도 "Alt 왼쪽 화살표" 까지 읽었다) +String keyHint(String text, String keys) => Platform.isAndroid ? text : '$text ($keys)'; diff --git a/lib/ui/subtitle_editor_page.dart b/lib/ui/subtitle_editor_page.dart index d6d8f52..c3caa3b 100644 --- a/lib/ui/subtitle_editor_page.dart +++ b/lib/ui/subtitle_editor_page.dart @@ -11,6 +11,7 @@ import '../core/srt.dart'; import '../core/text_codec.dart'; import '../services/preview_player.dart'; import 'app_actions.dart'; +import 'key_hint.dart'; import 'theme.dart'; import 'timeline.dart'; import '../l10n/tr.dart'; @@ -428,7 +429,7 @@ class _SubtitleEditorPageState extends State { onPressed: () => _seekBy(-5000), ), IconButton( - tooltip: tr('재생/정지 (Ctrl+Space)'), + tooltip: keyHint(tr('재생/정지'), 'Ctrl+Space'), iconSize: 30, icon: Icon(_playing ? Icons.pause_circle : Icons.play_circle, color: JjColors.accent), diff --git a/test/key_hint_test.dart b/test/key_hint_test.dart new file mode 100644 index 0000000..8c716e5 --- /dev/null +++ b/test/key_hint_test.dart @@ -0,0 +1,11 @@ +import 'dart:io'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:jj_mkvmaker/ui/key_hint.dart'; + +/// 194: 단축키 안내는 PC 에서만 (태블릿 · 폰은 이름만 - TalkBack 도 이름만 읽게) +void main() { + test('194: keyHint - PC 는 "이름 (키)", Android 는 이름만', () { + expect(keyHint('뒤로', 'Alt+←'), Platform.isAndroid ? '뒤로' : '뒤로 (Alt+←)'); + }); +}