이동 버튼 여러 개 (표시 이름 · 폴더, 환경 설정 > MKV 만들기), 세부 정보 오른쪽 아래에 표시 이름으로 위로 쌓기. 예전 이동 폴더는 '이동' 버튼으로
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>main
parent
22364ec16a
commit
d7efce87a6
|
|
@ -160,14 +160,17 @@
|
||||||
"{0} 인코더가 FFmpeg 에 없습니다.": "FFmpeg does not have the {0} encoder.",
|
"{0} 인코더가 FFmpeg 에 없습니다.": "FFmpeg does not have the {0} encoder.",
|
||||||
"{0} 추가": "Add {0}",
|
"{0} 추가": "Add {0}",
|
||||||
"{0}. {1} (대기)": "{0}. {1} (waiting)",
|
"{0}. {1} (대기)": "{0}. {1} (waiting)",
|
||||||
|
"{0}: 이 동영상을 {1} 로 옮깁니다": "{0}: moves this video to {1}",
|
||||||
"{0}: 이미 이동 폴더에 있습니다": "{0}: already in the move folder",
|
"{0}: 이미 이동 폴더에 있습니다": "{0}: already in the move folder",
|
||||||
"{0}: 작업 중이라 옮기지 않았습니다": "{0}: not moved because it is being processed",
|
"{0}: 작업 중이라 옮기지 않았습니다": "{0}: not moved because it is being processed",
|
||||||
|
"{0}: 체크한 동영상 {1}개를 {2} 로 옮깁니다": "{0}: moves the {1} checked videos to {2}",
|
||||||
"{0}개": "{0}",
|
"{0}개": "{0}",
|
||||||
"{0}개 · {1}": "{0} · {1}",
|
"{0}개 · {1}": "{0} · {1}",
|
||||||
"{0}개 · 주소 {1}개": "{0} · {1} links",
|
"{0}개 · 주소 {1}개": "{0} · {1} links",
|
||||||
"{0}개 선택": "{0} selected",
|
"{0}개 선택": "{0} selected",
|
||||||
"{0}개를 \"기타 즐겨찾기\" 에 가져왔습니다.": "Imported {0} into \"Other bookmarks\".",
|
"{0}개를 \"기타 즐겨찾기\" 에 가져왔습니다.": "Imported {0} into \"Other bookmarks\".",
|
||||||
"{0}개를 옮겼습니다 → {1}": "Moved {0} → {1}",
|
"{0}개를 옮겼습니다 → {1}": "Moved {0} → {1}",
|
||||||
|
"{0}개를 옮겼습니다 → {1} ({2})": "Moved {0} → {1} ({2})",
|
||||||
"{0}분 {1}초": "{0} min {1} s",
|
"{0}분 {1}초": "{0} min {1} s",
|
||||||
"{0}시간 {1}분": "{0} h {1} min",
|
"{0}시간 {1}분": "{0} h {1} min",
|
||||||
"{0}줄": "{0} lines",
|
"{0}줄": "{0} lines",
|
||||||
|
|
@ -493,6 +496,7 @@
|
||||||
"업데이트 · 설치하고 남은 파일": "Update · install leftovers",
|
"업데이트 · 설치하고 남은 파일": "Update · install leftovers",
|
||||||
"업데이트 실패: {0}": "Update failed: {0}",
|
"업데이트 실패: {0}": "Update failed: {0}",
|
||||||
"없음": "None",
|
"없음": "None",
|
||||||
|
"없음: 세부 정보의 [이동] 을 처음 누를 때 폴더를 골라 하나 만듭니다": "None: one is created when you first press [Move] in the details",
|
||||||
"여기에 놓으면 MKV 만들기의 동영상 목록에 추가합니다": "Drop here to add to the Make MKV video list",
|
"여기에 놓으면 MKV 만들기의 동영상 목록에 추가합니다": "Drop here to add to the Make MKV video list",
|
||||||
"여러 동영상을 MKV 로 만들 때 동시에 처리할 개수 (재인코딩은 CPU 를 많이 씁니다)": "How many to process at once when making several videos into MKV (re-encoding uses a lot of CPU)",
|
"여러 동영상을 MKV 로 만들 때 동시에 처리할 개수 (재인코딩은 CPU 를 많이 씁니다)": "How many to process at once when making several videos into MKV (re-encoding uses a lot of CPU)",
|
||||||
"연도": "Year",
|
"연도": "Year",
|
||||||
|
|
@ -560,6 +564,7 @@
|
||||||
"이 버전에는 Windows 용 zip 이 없습니다.": "This version has no zip for Windows.",
|
"이 버전에는 Windows 용 zip 이 없습니다.": "This version has no zip for Windows.",
|
||||||
"이 브라우저의 즐겨찾기 파일을 찾지 못했습니다.": "Could not find this browser's bookmarks file.",
|
"이 브라우저의 즐겨찾기 파일을 찾지 못했습니다.": "Could not find this browser's bookmarks file.",
|
||||||
"이 언어 지우기": "Remove this language",
|
"이 언어 지우기": "Remove this language",
|
||||||
|
"이 이동 버튼 지우기": "Delete this move button",
|
||||||
"이 파일에 맞는 자막 우선 (영상 해시)": "Prefer subtitles that match this file (video hash)",
|
"이 파일에 맞는 자막 우선 (영상 해시)": "Prefer subtitles that match this file (video hash)",
|
||||||
"이 파일용": "For this file",
|
"이 파일용": "For this file",
|
||||||
"이 폴더 선택": "Choose this folder",
|
"이 폴더 선택": "Choose this folder",
|
||||||
|
|
@ -569,11 +574,16 @@
|
||||||
"이 폴더에는 고를 파일이 없습니다": "There are no files to choose in this folder",
|
"이 폴더에는 고를 파일이 없습니다": "There are no files to choose in this folder",
|
||||||
"이동": "Move",
|
"이동": "Move",
|
||||||
"이동 ({0})": "Move ({0})",
|
"이동 ({0})": "Move ({0})",
|
||||||
|
"이동 버튼 (세부 정보 오른쪽 아래, 위로 하나씩)": "Move buttons (bottom right of the details, stacked upward)",
|
||||||
|
"이동 버튼 추가": "Add move button",
|
||||||
|
"이동 버튼의 폴더": "Folder of the move button",
|
||||||
"이동 폴더": "Move folder",
|
"이동 폴더": "Move folder",
|
||||||
"이동 폴더 (환경 설정에서 바꿀 수 있음)": "Move folder (can be changed in Settings)",
|
"이동 폴더 (환경 설정에서 바꿀 수 있음)": "Move folder (can be changed in Settings)",
|
||||||
"이동: {0} → {1}{2}": "Moved: {0} → {1}{2}",
|
"이동: {0} → {1}{2}": "Moved: {0} → {1}{2}",
|
||||||
|
"이동: 옮길 폴더를 골라 이동 버튼을 만듭니다 (환경 설정 > MKV 만들기 > 이동 버튼에서 여러 개 만들 수 있음)": "Move: choose a folder to create a move button (you can make several in Settings > Make MKV > Move buttons)",
|
||||||
"이동: 이 동영상을 이동 폴더로 옮깁니다{0}": "Move: moves this video to the move folder{0}",
|
"이동: 이 동영상을 이동 폴더로 옮깁니다{0}": "Move: moves this video to the move folder{0}",
|
||||||
"이동: 체크한 동영상 {0}개를 이동 폴더로 옮깁니다": "Move: moves the {0} checked videos to the move folder",
|
"이동: 체크한 동영상 {0}개를 이동 폴더로 옮깁니다": "Move: moves the {0} checked videos to the move folder",
|
||||||
|
"이동할 폴더가 정해지지 않았습니다 (환경 설정 > MKV 만들기 > 이동 버튼)": "No move folder is set (Settings > Make MKV > Move buttons)",
|
||||||
"이동할 폴더가 정해지지 않았습니다 (환경 설정 > 저장 위치)": "No move folder is set (Settings > Save locations)",
|
"이동할 폴더가 정해지지 않았습니다 (환경 설정 > 저장 위치)": "No move folder is set (Settings > Save locations)",
|
||||||
"이동할 폴더를 만들 수 없습니다: {0} ({1})": "Cannot create the move folder: {0} ({1})",
|
"이동할 폴더를 만들 수 없습니다: {0} ({1})": "Cannot create the move folder: {0} ({1})",
|
||||||
"이름": "Name",
|
"이름": "Name",
|
||||||
|
|
@ -799,6 +809,8 @@
|
||||||
"폴더: {0}": "Folder: {0}",
|
"폴더: {0}": "Folder: {0}",
|
||||||
"폴더가 아닙니다: {0}": "Not a folder: {0}",
|
"폴더가 아닙니다: {0}": "Not a folder: {0}",
|
||||||
"폴란드어": "Polish",
|
"폴란드어": "Polish",
|
||||||
|
"표시 이름": "Display name",
|
||||||
|
"표시 이름은 바로 고칠 수 있습니다. 동영상 줄을 세 번 누르면 첫 번째 버튼의 폴더로 옮깁니다": "You can edit display names right here. Pressing a video row three times moves it to the first button's folder",
|
||||||
"표준": "Standard",
|
"표준": "Standard",
|
||||||
"푸는 중": "Extracting",
|
"푸는 중": "Extracting",
|
||||||
"프랑스어": "French",
|
"프랑스어": "French",
|
||||||
|
|
|
||||||
|
|
@ -160,14 +160,17 @@
|
||||||
"{0} 인코더가 FFmpeg 에 없습니다.": "FFmpeg に {0} エンコーダーがありません。",
|
"{0} 인코더가 FFmpeg 에 없습니다.": "FFmpeg に {0} エンコーダーがありません。",
|
||||||
"{0} 추가": "{0} を追加",
|
"{0} 추가": "{0} を追加",
|
||||||
"{0}. {1} (대기)": "{0}. {1}(待機)",
|
"{0}. {1} (대기)": "{0}. {1}(待機)",
|
||||||
|
"{0}: 이 동영상을 {1} 로 옮깁니다": "{0}: この動画を {1} に移動します",
|
||||||
"{0}: 이미 이동 폴더에 있습니다": "{0}: 既に移動フォルダーにあります",
|
"{0}: 이미 이동 폴더에 있습니다": "{0}: 既に移動フォルダーにあります",
|
||||||
"{0}: 작업 중이라 옮기지 않았습니다": "{0}: 作業中のため移動しませんでした",
|
"{0}: 작업 중이라 옮기지 않았습니다": "{0}: 作業中のため移動しませんでした",
|
||||||
|
"{0}: 체크한 동영상 {1}개를 {2} 로 옮깁니다": "{0}: チェックした動画 {1}個を {2} に移動します",
|
||||||
"{0}개": "{0}個",
|
"{0}개": "{0}個",
|
||||||
"{0}개 · {1}": "{0}個・{1}",
|
"{0}개 · {1}": "{0}個・{1}",
|
||||||
"{0}개 · 주소 {1}개": "{0}個・URL {1}個",
|
"{0}개 · 주소 {1}개": "{0}個・URL {1}個",
|
||||||
"{0}개 선택": "{0}個選択",
|
"{0}개 선택": "{0}個選択",
|
||||||
"{0}개를 \"기타 즐겨찾기\" 에 가져왔습니다.": "{0}個を「その他のブックマーク」に取り込みました。",
|
"{0}개를 \"기타 즐겨찾기\" 에 가져왔습니다.": "{0}個を「その他のブックマーク」に取り込みました。",
|
||||||
"{0}개를 옮겼습니다 → {1}": "{0}個を移動しました → {1}",
|
"{0}개를 옮겼습니다 → {1}": "{0}個を移動しました → {1}",
|
||||||
|
"{0}개를 옮겼습니다 → {1} ({2})": "{0}個を移動しました → {1}({2})",
|
||||||
"{0}분 {1}초": "{0}分 {1}秒",
|
"{0}분 {1}초": "{0}分 {1}秒",
|
||||||
"{0}시간 {1}분": "{0}時間 {1}分",
|
"{0}시간 {1}분": "{0}時間 {1}分",
|
||||||
"{0}줄": "{0}行",
|
"{0}줄": "{0}行",
|
||||||
|
|
@ -493,6 +496,7 @@
|
||||||
"업데이트 · 설치하고 남은 파일": "更新・インストールの残り",
|
"업데이트 · 설치하고 남은 파일": "更新・インストールの残り",
|
||||||
"업데이트 실패: {0}": "更新失敗: {0}",
|
"업데이트 실패: {0}": "更新失敗: {0}",
|
||||||
"없음": "なし",
|
"없음": "なし",
|
||||||
|
"없음: 세부 정보의 [이동] 을 처음 누를 때 폴더를 골라 하나 만듭니다": "なし: 詳細の[移動]を初めて押したときにフォルダーを選んで作成します",
|
||||||
"여기에 놓으면 MKV 만들기의 동영상 목록에 추가합니다": "ここにドロップすると MKV 作成の動画リストに追加します",
|
"여기에 놓으면 MKV 만들기의 동영상 목록에 추가합니다": "ここにドロップすると MKV 作成の動画リストに追加します",
|
||||||
"여러 동영상을 MKV 로 만들 때 동시에 처리할 개수 (재인코딩은 CPU 를 많이 씁니다)": "複数の動画を MKV にするとき同時に処理する数(再エンコードは CPU を多く使います)",
|
"여러 동영상을 MKV 로 만들 때 동시에 처리할 개수 (재인코딩은 CPU 를 많이 씁니다)": "複数の動画を MKV にするとき同時に処理する数(再エンコードは CPU を多く使います)",
|
||||||
"연도": "年",
|
"연도": "年",
|
||||||
|
|
@ -560,6 +564,7 @@
|
||||||
"이 버전에는 Windows 용 zip 이 없습니다.": "このバージョンには Windows 用 zip がありません。",
|
"이 버전에는 Windows 용 zip 이 없습니다.": "このバージョンには Windows 用 zip がありません。",
|
||||||
"이 브라우저의 즐겨찾기 파일을 찾지 못했습니다.": "このブラウザーのブックマークファイルが見つかりませんでした。",
|
"이 브라우저의 즐겨찾기 파일을 찾지 못했습니다.": "このブラウザーのブックマークファイルが見つかりませんでした。",
|
||||||
"이 언어 지우기": "この言語を削除",
|
"이 언어 지우기": "この言語を削除",
|
||||||
|
"이 이동 버튼 지우기": "この移動ボタンを削除",
|
||||||
"이 파일에 맞는 자막 우선 (영상 해시)": "このファイルに合う字幕を優先(動画ハッシュ)",
|
"이 파일에 맞는 자막 우선 (영상 해시)": "このファイルに合う字幕を優先(動画ハッシュ)",
|
||||||
"이 파일용": "このファイル用",
|
"이 파일용": "このファイル用",
|
||||||
"이 폴더 선택": "このフォルダーを選択",
|
"이 폴더 선택": "このフォルダーを選択",
|
||||||
|
|
@ -569,11 +574,16 @@
|
||||||
"이 폴더에는 고를 파일이 없습니다": "このフォルダーには選べるファイルがありません",
|
"이 폴더에는 고를 파일이 없습니다": "このフォルダーには選べるファイルがありません",
|
||||||
"이동": "移動",
|
"이동": "移動",
|
||||||
"이동 ({0})": "移動({0})",
|
"이동 ({0})": "移動({0})",
|
||||||
|
"이동 버튼 (세부 정보 오른쪽 아래, 위로 하나씩)": "移動ボタン(詳細の右下、上に 1つずつ)",
|
||||||
|
"이동 버튼 추가": "移動ボタンを追加",
|
||||||
|
"이동 버튼의 폴더": "移動ボタンのフォルダー",
|
||||||
"이동 폴더": "移動フォルダー",
|
"이동 폴더": "移動フォルダー",
|
||||||
"이동 폴더 (환경 설정에서 바꿀 수 있음)": "移動フォルダー(環境設定で変更できます)",
|
"이동 폴더 (환경 설정에서 바꿀 수 있음)": "移動フォルダー(環境設定で変更できます)",
|
||||||
"이동: {0} → {1}{2}": "移動: {0} → {1}{2}",
|
"이동: {0} → {1}{2}": "移動: {0} → {1}{2}",
|
||||||
|
"이동: 옮길 폴더를 골라 이동 버튼을 만듭니다 (환경 설정 > MKV 만들기 > 이동 버튼에서 여러 개 만들 수 있음)": "移動: 移動先フォルダーを選んで移動ボタンを作ります(環境設定 > MKV 作成 > 移動ボタンで複数作れます)",
|
||||||
"이동: 이 동영상을 이동 폴더로 옮깁니다{0}": "移動: この動画を移動フォルダーに移します{0}",
|
"이동: 이 동영상을 이동 폴더로 옮깁니다{0}": "移動: この動画を移動フォルダーに移します{0}",
|
||||||
"이동: 체크한 동영상 {0}개를 이동 폴더로 옮깁니다": "移動: チェックした動画 {0}個を移動フォルダーに移します",
|
"이동: 체크한 동영상 {0}개를 이동 폴더로 옮깁니다": "移動: チェックした動画 {0}個を移動フォルダーに移します",
|
||||||
|
"이동할 폴더가 정해지지 않았습니다 (환경 설정 > MKV 만들기 > 이동 버튼)": "移動先フォルダーが決まっていません(環境設定 > MKV 作成 > 移動ボタン)",
|
||||||
"이동할 폴더가 정해지지 않았습니다 (환경 설정 > 저장 위치)": "移動フォルダーが決まっていません(環境設定 > 保存先)",
|
"이동할 폴더가 정해지지 않았습니다 (환경 설정 > 저장 위치)": "移動フォルダーが決まっていません(環境設定 > 保存先)",
|
||||||
"이동할 폴더를 만들 수 없습니다: {0} ({1})": "移動フォルダーを作成できません: {0}({1})",
|
"이동할 폴더를 만들 수 없습니다: {0} ({1})": "移動フォルダーを作成できません: {0}({1})",
|
||||||
"이름": "名前",
|
"이름": "名前",
|
||||||
|
|
@ -799,6 +809,8 @@
|
||||||
"폴더: {0}": "フォルダー: {0}",
|
"폴더: {0}": "フォルダー: {0}",
|
||||||
"폴더가 아닙니다: {0}": "フォルダーではありません: {0}",
|
"폴더가 아닙니다: {0}": "フォルダーではありません: {0}",
|
||||||
"폴란드어": "ポーランド語",
|
"폴란드어": "ポーランド語",
|
||||||
|
"표시 이름": "表示名",
|
||||||
|
"표시 이름은 바로 고칠 수 있습니다. 동영상 줄을 세 번 누르면 첫 번째 버튼의 폴더로 옮깁니다": "表示名はその場で変更できます。動画の行を 3回押すと最初のボタンのフォルダーに移動します",
|
||||||
"표준": "標準",
|
"표준": "標準",
|
||||||
"푸는 중": "展開中",
|
"푸는 중": "展開中",
|
||||||
"프랑스어": "フランス語",
|
"프랑스어": "フランス語",
|
||||||
|
|
|
||||||
|
|
@ -160,14 +160,17 @@
|
||||||
"{0} 인코더가 FFmpeg 에 없습니다.": "FFmpeg 中没有 {0} 编码器。",
|
"{0} 인코더가 FFmpeg 에 없습니다.": "FFmpeg 中没有 {0} 编码器。",
|
||||||
"{0} 추가": "添加 {0}",
|
"{0} 추가": "添加 {0}",
|
||||||
"{0}. {1} (대기)": "{0}. {1}(等待)",
|
"{0}. {1} (대기)": "{0}. {1}(等待)",
|
||||||
|
"{0}: 이 동영상을 {1} 로 옮깁니다": "{0}: 将此视频移到 {1}",
|
||||||
"{0}: 이미 이동 폴더에 있습니다": "{0}: 已在移动文件夹中",
|
"{0}: 이미 이동 폴더에 있습니다": "{0}: 已在移动文件夹中",
|
||||||
"{0}: 작업 중이라 옮기지 않았습니다": "{0}: 正在处理,未移动",
|
"{0}: 작업 중이라 옮기지 않았습니다": "{0}: 正在处理,未移动",
|
||||||
|
"{0}: 체크한 동영상 {1}개를 {2} 로 옮깁니다": "{0}: 将勾选的 {1} 个视频移到 {2}",
|
||||||
"{0}개": "{0} 个",
|
"{0}개": "{0} 个",
|
||||||
"{0}개 · {1}": "{0} 个 · {1}",
|
"{0}개 · {1}": "{0} 个 · {1}",
|
||||||
"{0}개 · 주소 {1}개": "{0} 个 · 地址 {1} 个",
|
"{0}개 · 주소 {1}개": "{0} 个 · 地址 {1} 个",
|
||||||
"{0}개 선택": "已选 {0} 个",
|
"{0}개 선택": "已选 {0} 个",
|
||||||
"{0}개를 \"기타 즐겨찾기\" 에 가져왔습니다.": "已将 {0} 个导入“其他书签”。",
|
"{0}개를 \"기타 즐겨찾기\" 에 가져왔습니다.": "已将 {0} 个导入“其他书签”。",
|
||||||
"{0}개를 옮겼습니다 → {1}": "已移动 {0} 个 → {1}",
|
"{0}개를 옮겼습니다 → {1}": "已移动 {0} 个 → {1}",
|
||||||
|
"{0}개를 옮겼습니다 → {1} ({2})": "已移动 {0} 个 → {1}({2})",
|
||||||
"{0}분 {1}초": "{0} 分 {1} 秒",
|
"{0}분 {1}초": "{0} 分 {1} 秒",
|
||||||
"{0}시간 {1}분": "{0} 小时 {1} 分",
|
"{0}시간 {1}분": "{0} 小时 {1} 分",
|
||||||
"{0}줄": "{0} 行",
|
"{0}줄": "{0} 行",
|
||||||
|
|
@ -493,6 +496,7 @@
|
||||||
"업데이트 · 설치하고 남은 파일": "更新 · 安装残留",
|
"업데이트 · 설치하고 남은 파일": "更新 · 安装残留",
|
||||||
"업데이트 실패: {0}": "更新失败: {0}",
|
"업데이트 실패: {0}": "更新失败: {0}",
|
||||||
"없음": "无",
|
"없음": "无",
|
||||||
|
"없음: 세부 정보의 [이동] 을 처음 누를 때 폴더를 골라 하나 만듭니다": "无: 首次在详细信息中点击[移动]时选择文件夹并创建",
|
||||||
"여기에 놓으면 MKV 만들기의 동영상 목록에 추가합니다": "拖放到此处即可加入制作 MKV 的视频列表",
|
"여기에 놓으면 MKV 만들기의 동영상 목록에 추가합니다": "拖放到此处即可加入制作 MKV 的视频列表",
|
||||||
"여러 동영상을 MKV 로 만들 때 동시에 처리할 개수 (재인코딩은 CPU 를 많이 씁니다)": "将多个视频制作成 MKV 时同时处理的数量(重新编码会占用大量 CPU)",
|
"여러 동영상을 MKV 로 만들 때 동시에 처리할 개수 (재인코딩은 CPU 를 많이 씁니다)": "将多个视频制作成 MKV 时同时处理的数量(重新编码会占用大量 CPU)",
|
||||||
"연도": "年份",
|
"연도": "年份",
|
||||||
|
|
@ -560,6 +564,7 @@
|
||||||
"이 버전에는 Windows 용 zip 이 없습니다.": "此版本没有 Windows 版 zip。",
|
"이 버전에는 Windows 용 zip 이 없습니다.": "此版本没有 Windows 版 zip。",
|
||||||
"이 브라우저의 즐겨찾기 파일을 찾지 못했습니다.": "未找到此浏览器的书签文件。",
|
"이 브라우저의 즐겨찾기 파일을 찾지 못했습니다.": "未找到此浏览器的书签文件。",
|
||||||
"이 언어 지우기": "删除此语言",
|
"이 언어 지우기": "删除此语言",
|
||||||
|
"이 이동 버튼 지우기": "删除此移动按钮",
|
||||||
"이 파일에 맞는 자막 우선 (영상 해시)": "优先匹配此文件的字幕(视频哈希)",
|
"이 파일에 맞는 자막 우선 (영상 해시)": "优先匹配此文件的字幕(视频哈希)",
|
||||||
"이 파일용": "适用于此文件",
|
"이 파일용": "适用于此文件",
|
||||||
"이 폴더 선택": "选择此文件夹",
|
"이 폴더 선택": "选择此文件夹",
|
||||||
|
|
@ -569,11 +574,16 @@
|
||||||
"이 폴더에는 고를 파일이 없습니다": "此文件夹中没有可选择的文件",
|
"이 폴더에는 고를 파일이 없습니다": "此文件夹中没有可选择的文件",
|
||||||
"이동": "移动",
|
"이동": "移动",
|
||||||
"이동 ({0})": "移动({0})",
|
"이동 ({0})": "移动({0})",
|
||||||
|
"이동 버튼 (세부 정보 오른쪽 아래, 위로 하나씩)": "移动按钮(详细信息右下角,向上依次排列)",
|
||||||
|
"이동 버튼 추가": "添加移动按钮",
|
||||||
|
"이동 버튼의 폴더": "移动按钮的文件夹",
|
||||||
"이동 폴더": "移动目标文件夹",
|
"이동 폴더": "移动目标文件夹",
|
||||||
"이동 폴더 (환경 설정에서 바꿀 수 있음)": "移动目标文件夹(可在设置中更改)",
|
"이동 폴더 (환경 설정에서 바꿀 수 있음)": "移动目标文件夹(可在设置中更改)",
|
||||||
"이동: {0} → {1}{2}": "已移动: {0} → {1}{2}",
|
"이동: {0} → {1}{2}": "已移动: {0} → {1}{2}",
|
||||||
|
"이동: 옮길 폴더를 골라 이동 버튼을 만듭니다 (환경 설정 > MKV 만들기 > 이동 버튼에서 여러 개 만들 수 있음)": "移动: 选择目标文件夹以创建移动按钮(可在 设置 > 制作 MKV > 移动按钮 中创建多个)",
|
||||||
"이동: 이 동영상을 이동 폴더로 옮깁니다{0}": "移动: 将此视频移到移动目标文件夹{0}",
|
"이동: 이 동영상을 이동 폴더로 옮깁니다{0}": "移动: 将此视频移到移动目标文件夹{0}",
|
||||||
"이동: 체크한 동영상 {0}개를 이동 폴더로 옮깁니다": "移动: 将勾选的 {0} 个视频移到移动目标文件夹",
|
"이동: 체크한 동영상 {0}개를 이동 폴더로 옮깁니다": "移动: 将勾选的 {0} 个视频移到移动目标文件夹",
|
||||||
|
"이동할 폴더가 정해지지 않았습니다 (환경 설정 > MKV 만들기 > 이동 버튼)": "尚未设置移动目标文件夹(设置 > 制作 MKV > 移动按钮)",
|
||||||
"이동할 폴더가 정해지지 않았습니다 (환경 설정 > 저장 위치)": "尚未设置移动目标文件夹(设置 > 保存位置)",
|
"이동할 폴더가 정해지지 않았습니다 (환경 설정 > 저장 위치)": "尚未设置移动目标文件夹(设置 > 保存位置)",
|
||||||
"이동할 폴더를 만들 수 없습니다: {0} ({1})": "无法创建移动目标文件夹: {0}({1})",
|
"이동할 폴더를 만들 수 없습니다: {0} ({1})": "无法创建移动目标文件夹: {0}({1})",
|
||||||
"이름": "名称",
|
"이름": "名称",
|
||||||
|
|
@ -799,6 +809,8 @@
|
||||||
"폴더: {0}": "文件夹: {0}",
|
"폴더: {0}": "文件夹: {0}",
|
||||||
"폴더가 아닙니다: {0}": "不是文件夹: {0}",
|
"폴더가 아닙니다: {0}": "不是文件夹: {0}",
|
||||||
"폴란드어": "波兰语",
|
"폴란드어": "波兰语",
|
||||||
|
"표시 이름": "显示名称",
|
||||||
|
"표시 이름은 바로 고칠 수 있습니다. 동영상 줄을 세 번 누르면 첫 번째 버튼의 폴더로 옮깁니다": "显示名称可直接修改。连续点击视频行三次会移到第一个按钮的文件夹",
|
||||||
"표준": "标准",
|
"표준": "标准",
|
||||||
"푸는 중": "正在解压",
|
"푸는 중": "正在解压",
|
||||||
"프랑스어": "法语",
|
"프랑스어": "法语",
|
||||||
|
|
|
||||||
|
|
@ -425,12 +425,11 @@ class AppController extends ChangeNotifier {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 동영상을 이동 폴더 (환경 설정) 로 옮긴다. 옆에 있는 같은 이름의 자막 파일 (a.srt · a.ko.smi …) 과
|
/// 동영상을 [dest] (환경 설정의 이동 버튼 폴더) 로 옮긴다. 옆에 있는 같은 이름의 자막 파일 (a.srt · a.ko.smi …) 과
|
||||||
/// 만든 결과물 (jj_mkv 의 a.mkv · a_AI.srt · a_ko.srt …) 도 함께 (결과물은 이동 폴더의 jj_mkv 로).
|
/// 만든 결과물 (jj_mkv 의 a.mkv · a_AI.srt · a_ko.srt …) 도 함께 (결과물은 이동 폴더의 jj_mkv 로).
|
||||||
/// 옮긴 동영상은 목록에서 뺀다. 작업 중인 것은 옮기지 않는다. 반환: (옮긴 수, 못 옮긴 이유들)
|
/// 옮긴 동영상은 목록에서 뺀다. 작업 중인 것은 옮기지 않는다. 반환: (옮긴 수, 못 옮긴 이유들)
|
||||||
Future<(int, List<String>)> moveVideos(List<VideoItem> targets) async {
|
Future<(int, List<String>)> moveVideos(List<VideoItem> targets, String dest) async {
|
||||||
final dest = settings.moveTargetDir;
|
if (dest.isEmpty) return (0, [tr('이동할 폴더가 정해지지 않았습니다 (환경 설정 > MKV 만들기 > 이동 버튼)')]);
|
||||||
if (dest == null || dest.isEmpty) return (0, [tr('이동할 폴더가 정해지지 않았습니다 (환경 설정 > 저장 위치)')]);
|
|
||||||
var moved = 0;
|
var moved = 0;
|
||||||
final errors = <String>[];
|
final errors = <String>[];
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,34 @@ import '../core/download_detect.dart';
|
||||||
import '../core/encode_options.dart';
|
import '../core/encode_options.dart';
|
||||||
import '../core/playlist.dart';
|
import '../core/playlist.dart';
|
||||||
|
|
||||||
|
/// MKV 세부 정보의 이동 버튼 하나: 표시 이름 · 옮길 폴더
|
||||||
|
class MoveTarget {
|
||||||
|
final String name;
|
||||||
|
final String dir;
|
||||||
|
const MoveTarget(this.name, this.dir);
|
||||||
|
|
||||||
|
MoveTarget copyWith({String? name, String? dir}) => MoveTarget(name ?? this.name, dir ?? this.dir);
|
||||||
|
|
||||||
|
Map<String, Object?> toJson() => {'name': name, 'dir': dir};
|
||||||
|
|
||||||
|
factory MoveTarget.fromJson(Map<Object?, Object?> j) =>
|
||||||
|
MoveTarget((j['name'] as String?)?.trim().isNotEmpty == true ? j['name'] as String : '이동', j['dir'] as String);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) => other is MoveTarget && other.name == name && other.dir == dir;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(name, dir);
|
||||||
|
}
|
||||||
|
|
||||||
/// 환경 설정 (settings.json 에 저장)
|
/// 환경 설정 (settings.json 에 저장)
|
||||||
class AppSettings {
|
class AppSettings {
|
||||||
/// MKV·자막 저장 위치. null 이면 동영상이 있는 폴더 아래 jj_mkv
|
/// MKV·자막 저장 위치. null 이면 동영상이 있는 폴더 아래 jj_mkv
|
||||||
String? mkvOutputRoot;
|
String? mkvOutputRoot;
|
||||||
|
|
||||||
/// MKV 목록의 [이동] · 세 번 누르기로 동영상을 옮길 폴더. null 이면 처음 옮길 때 고른다
|
/// MKV 세부 정보 오른쪽 아래의 이동 버튼들 (표시 이름 · 폴더). 세 번 누르기는 첫 번째 버튼의 폴더로.
|
||||||
String? moveTargetDir;
|
/// 비어 있으면 [이동] 을 처음 누를 때 폴더를 골라 하나 만든다.
|
||||||
|
List<MoveTarget> moveTargets = [];
|
||||||
|
|
||||||
/// 웹 브라우저에서 YouTube 광고 자동 건너뛰기 (건너뛰기 버튼 누르기 · 건너뛸 수 없는 광고는 빨리 감기 · 소리 끄기)
|
/// 웹 브라우저에서 YouTube 광고 자동 건너뛰기 (건너뛰기 버튼 누르기 · 건너뛸 수 없는 광고는 빨리 감기 · 소리 끄기)
|
||||||
bool youtubeAdSkip = true;
|
bool youtubeAdSkip = true;
|
||||||
|
|
@ -130,7 +151,7 @@ class AppSettings {
|
||||||
|
|
||||||
Map<String, Object?> toJson() => {
|
Map<String, Object?> toJson() => {
|
||||||
'mkvOutputRoot': mkvOutputRoot,
|
'mkvOutputRoot': mkvOutputRoot,
|
||||||
'moveTargetDir': moveTargetDir,
|
'moveTargets': [for (final t in moveTargets) t.toJson()],
|
||||||
'youtubeAdSkip': youtubeAdSkip,
|
'youtubeAdSkip': youtubeAdSkip,
|
||||||
'youtubeAdHide': youtubeAdHide,
|
'youtubeAdHide': youtubeAdHide,
|
||||||
'downloadRoot': downloadRoot,
|
'downloadRoot': downloadRoot,
|
||||||
|
|
@ -193,7 +214,12 @@ class AppSettings {
|
||||||
final e = (j['encode'] as Map?) ?? const {};
|
final e = (j['encode'] as Map?) ?? const {};
|
||||||
return AppSettings()
|
return AppSettings()
|
||||||
..mkvOutputRoot = j['mkvOutputRoot'] as String?
|
..mkvOutputRoot = j['mkvOutputRoot'] as String?
|
||||||
..moveTargetDir = j['moveTargetDir'] as String?
|
..moveTargets = [
|
||||||
|
for (final x in (j['moveTargets'] as List?) ?? const [])
|
||||||
|
if (x is Map && x['dir'] is String) MoveTarget.fromJson(x),
|
||||||
|
// 예전 판의 이동 폴더 하나 → "이동" 버튼으로
|
||||||
|
if (j['moveTargets'] == null && j['moveTargetDir'] is String) MoveTarget('이동', j['moveTargetDir'] as String),
|
||||||
|
]
|
||||||
..youtubeAdSkip = j['youtubeAdSkip'] as bool? ?? true
|
..youtubeAdSkip = j['youtubeAdSkip'] as bool? ?? true
|
||||||
..youtubeAdHide = j['youtubeAdHide'] as bool? ?? true
|
..youtubeAdHide = j['youtubeAdHide'] as bool? ?? true
|
||||||
..downloadRoot = j['downloadRoot'] as String?
|
..downloadRoot = j['downloadRoot'] as String?
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ import '../core/output_paths.dart';
|
||||||
import 'ai_dialog.dart';
|
import 'ai_dialog.dart';
|
||||||
import 'app_actions.dart';
|
import 'app_actions.dart';
|
||||||
import 'downloads_page.dart';
|
import 'downloads_page.dart';
|
||||||
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
|
import '../app/settings.dart' show MoveTarget;
|
||||||
import 'folder_picker.dart';
|
import 'folder_picker.dart';
|
||||||
import 'player_page.dart';
|
import 'player_page.dart';
|
||||||
import 'subtitle_editor_page.dart';
|
import 'subtitle_editor_page.dart';
|
||||||
|
|
@ -707,25 +710,41 @@ class _VideoDetail extends StatelessWidget {
|
||||||
// 이 동영상을 처리하는 중일 때만 잠금 (다른 작업 중이면 대기열에 넣는다)
|
// 이 동영상을 처리하는 중일 때만 잠금 (다른 작업 중이면 대기열에 넣는다)
|
||||||
final locked = v.status == JobStatus.running;
|
final locked = v.status == JobStatus.running;
|
||||||
|
|
||||||
// 오른쪽 아래 [이동]: 체크한 동영상이 있으면 그것들, 없으면 지금 보고 있는 이 동영상
|
// 오른쪽 아래 이동 버튼들 (환경 설정 > MKV 만들기 > 이동 버튼): 표시 이름으로, 위로 하나씩.
|
||||||
final moveTargets = c.checked.isEmpty ? [v] : c.batchTargets;
|
// 체크한 동영상이 있으면 그것들, 없으면 지금 보고 있는 이 동영상을 그 버튼의 폴더로 옮긴다.
|
||||||
|
final moving = c.checked.isEmpty ? [v] : c.batchTargets;
|
||||||
|
final canMove = moving.any((x) => x.status != JobStatus.running);
|
||||||
|
final count = c.checked.isEmpty ? '' : ' (${c.checked.length})';
|
||||||
|
final buttons = c.settings.moveTargets;
|
||||||
|
Widget button(MoveTarget? t) => Tooltip(
|
||||||
|
message: t == null
|
||||||
|
? tr('이동: 옮길 폴더를 골라 이동 버튼을 만듭니다 (환경 설정 > MKV 만들기 > 이동 버튼에서 여러 개 만들 수 있음)')
|
||||||
|
: c.checked.isEmpty
|
||||||
|
? trf('{0}: 이 동영상을 {1} 로 옮깁니다', [t.name, t.dir])
|
||||||
|
: trf('{0}: 체크한 동영상 {1}개를 {2} 로 옮깁니다', [t.name, c.checked.length, t.dir]),
|
||||||
|
child: FloatingActionButton.extended(
|
||||||
|
heroTag: null,
|
||||||
|
onPressed: canMove ? () => moveToTarget(context, c, moving, target: t) : null,
|
||||||
|
icon: const Icon(Icons.drive_file_move_outline),
|
||||||
|
label: Text('${t?.name ?? tr('이동')}$count'),
|
||||||
|
),
|
||||||
|
);
|
||||||
return Stack(children: [
|
return Stack(children: [
|
||||||
_list(context, info, video, audioCount, locked),
|
_list(context, info, video, audioCount, locked),
|
||||||
Positioned(
|
Positioned(
|
||||||
right: 16,
|
right: 16,
|
||||||
bottom: 16,
|
bottom: 16,
|
||||||
child: Tooltip(
|
child: Column(
|
||||||
message: c.checked.isEmpty
|
mainAxisSize: MainAxisSize.min,
|
||||||
? trf('이동: 이 동영상을 이동 폴더로 옮깁니다{0}', [c.settings.moveTargetDir == null ? '' : ' (${c.settings.moveTargetDir})'])
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
: trf('이동: 체크한 동영상 {0}개를 이동 폴더로 옮깁니다', [c.checked.length]),
|
children: [
|
||||||
child: FloatingActionButton.extended(
|
if (buttons.isEmpty) button(null),
|
||||||
heroTag: null,
|
// 첫 번째 버튼이 맨 아래 (예전 [이동] 자리), 다음 버튼은 그 위로
|
||||||
onPressed: moveTargets.any((x) => x.status != JobStatus.running)
|
for (var i = buttons.length - 1; i >= 0; i--) ...[
|
||||||
? () => moveToTarget(context, c, moveTargets)
|
button(buttons[i]),
|
||||||
: null,
|
if (i > 0) const SizedBox(height: 10),
|
||||||
icon: const Icon(Icons.drive_file_move_outline),
|
],
|
||||||
label: Text(c.checked.isEmpty ? tr('이동') : trf('이동 ({0})', [c.checked.length])),
|
],
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
@ -1044,19 +1063,23 @@ class _LogStrip extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 동영상을 이동 폴더로 옮긴다 (MKV 목록의 [이동] · 세 번 누르기). 이동 폴더를 아직 안 정했으면 먼저 고른다.
|
/// 동영상을 이동 버튼의 폴더로 옮긴다 (세부 정보의 이동 버튼 · 세 번 누르기). [target] 이 없으면 첫 번째 버튼,
|
||||||
Future<void> moveToTarget(BuildContext context, AppController c, List<VideoItem> targets) async {
|
/// 이동 버튼이 하나도 없으면 폴더를 골라 하나 만든다 (표시 이름은 폴더 이름).
|
||||||
if (targets.isEmpty) return;
|
Future<void> moveToTarget(BuildContext context, AppController c, List<VideoItem> videos, {MoveTarget? target}) async {
|
||||||
|
if (videos.isEmpty) return;
|
||||||
final messenger = ScaffoldMessenger.maybeOf(context);
|
final messenger = ScaffoldMessenger.maybeOf(context);
|
||||||
if (c.settings.moveTargetDir == null) {
|
var t = target ?? c.settings.moveTargets.firstOrNull;
|
||||||
|
if (t == null) {
|
||||||
final d = await pickFolder(context, tr('이동 폴더 (환경 설정에서 바꿀 수 있음)'));
|
final d = await pickFolder(context, tr('이동 폴더 (환경 설정에서 바꿀 수 있음)'));
|
||||||
if (d == null) return;
|
if (d == null) return;
|
||||||
await c.updateSettings((x) => x.moveTargetDir = d);
|
t = MoveTarget(p.basename(d).isEmpty ? tr('이동') : p.basename(d), d);
|
||||||
|
final add = t;
|
||||||
|
await c.updateSettings((x) => x.moveTargets = [...x.moveTargets, add]);
|
||||||
}
|
}
|
||||||
final (moved, errors) = await c.moveVideos(targets);
|
final (moved, errors) = await c.moveVideos(videos, t.dir);
|
||||||
messenger?.showSnackBar(SnackBar(
|
messenger?.showSnackBar(SnackBar(
|
||||||
content: Text([
|
content: Text([
|
||||||
if (moved > 0) trf('{0}개를 옮겼습니다 → {1}', [moved, c.settings.moveTargetDir]),
|
if (moved > 0) trf('{0}개를 옮겼습니다 → {1} ({2})', [moved, t.name, t.dir]),
|
||||||
...errors,
|
...errors,
|
||||||
].join('\n')),
|
].join('\n')),
|
||||||
));
|
));
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
import '../app/app_controller.dart';
|
import '../app/app_controller.dart';
|
||||||
import '../core/download_detect.dart';
|
import '../core/download_detect.dart';
|
||||||
|
|
@ -373,15 +374,31 @@ class _SettingsPageState extends State<SettingsPage> {
|
||||||
},
|
},
|
||||||
onReset: () => c.updateSettings((x) => x.mkvOutputRoot = null),
|
onReset: () => c.updateSettings((x) => x.mkvOutputRoot = null),
|
||||||
),
|
),
|
||||||
_folderTile(
|
_subTitle(tr('이동 버튼 (세부 정보 오른쪽 아래, 위로 하나씩)')),
|
||||||
title: tr('이동 폴더'),
|
for (var i = 0; i < s.moveTargets.length; i++) _moveTargetTile(i, s.moveTargets[i]),
|
||||||
value: s.moveTargetDir,
|
Padding(
|
||||||
defaultText: tr('정하지 않음: MKV 목록에서 [이동] 을 처음 누를 때 고릅니다'),
|
padding: const EdgeInsets.fromLTRB(16, 4, 16, 8),
|
||||||
onPick: () async {
|
child: Row(children: [
|
||||||
final d = await _pickDir(tr('이동 폴더'), s.moveTargetDir);
|
OutlinedButton.icon(
|
||||||
if (d != null) await c.updateSettings((x) => x.moveTargetDir = d);
|
onPressed: () async {
|
||||||
|
final d = await _pickDir(tr('이동 버튼의 폴더'));
|
||||||
|
if (d == null) return;
|
||||||
|
final name = p.basename(d).isEmpty ? tr('이동') : p.basename(d);
|
||||||
|
await c.updateSettings((x) => x.moveTargets = [...x.moveTargets, MoveTarget(name, d)]);
|
||||||
},
|
},
|
||||||
onReset: () => c.updateSettings((x) => x.moveTargetDir = null),
|
icon: const Icon(Icons.add, size: 18),
|
||||||
|
label: Text(tr('이동 버튼 추가')),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
s.moveTargets.isEmpty
|
||||||
|
? tr('없음: 세부 정보의 [이동] 을 처음 누를 때 폴더를 골라 하나 만듭니다')
|
||||||
|
: tr('표시 이름은 바로 고칠 수 있습니다. 동영상 줄을 세 번 누르면 첫 번째 버튼의 폴더로 옮깁니다'),
|
||||||
|
style: const TextStyle(fontSize: 12, color: JjColors.textDim),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
_group('subtitle', Icons.subtitles_outlined, tr('자막 (AI · 인터넷)'), [
|
_group('subtitle', Icons.subtitles_outlined, tr('자막 (AI · 인터넷)'), [
|
||||||
|
|
@ -709,6 +726,45 @@ class _SettingsPageState extends State<SettingsPage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 이동 버튼 하나: 표시 이름 (바로 고침) · 폴더 · 순서 올리기 · 폴더 바꾸기 · 지우기
|
||||||
|
Widget _moveTargetTile(int i, MoveTarget t) {
|
||||||
|
final s = c.settings;
|
||||||
|
void update(List<MoveTarget> Function(List<MoveTarget>) f) =>
|
||||||
|
c.updateSettings((x) => x.moveTargets = f([...x.moveTargets]));
|
||||||
|
return ListTile(
|
||||||
|
key: ValueKey('move_${i}_${t.dir}'),
|
||||||
|
leading: const Icon(Icons.drive_file_move_outline, color: JjColors.accent),
|
||||||
|
title: TextFormField(
|
||||||
|
initialValue: t.name,
|
||||||
|
decoration: InputDecoration(isDense: true, labelText: tr('표시 이름')),
|
||||||
|
onChanged: (v) => update((l) => l..[i] = t.copyWith(name: v.trim().isEmpty ? tr('이동') : v.trim())),
|
||||||
|
),
|
||||||
|
subtitle: Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 4),
|
||||||
|
child: Text(t.dir, maxLines: 2, overflow: TextOverflow.ellipsis),
|
||||||
|
),
|
||||||
|
trailing: Row(mainAxisSize: MainAxisSize.min, children: [
|
||||||
|
IconButton(
|
||||||
|
tooltip: tr('위로'),
|
||||||
|
icon: const Icon(Icons.arrow_upward, size: 18),
|
||||||
|
onPressed: i == 0 ? null : () => update((l) => l..insert(i - 1, l.removeAt(i))),
|
||||||
|
),
|
||||||
|
OutlinedButton(
|
||||||
|
onPressed: () async {
|
||||||
|
final d = await _pickDir(tr('이동 버튼의 폴더'), t.dir);
|
||||||
|
if (d != null) update((l) => l..[i] = t.copyWith(dir: d));
|
||||||
|
},
|
||||||
|
child: Text(tr('폴더 선택')),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
tooltip: tr('이 이동 버튼 지우기'),
|
||||||
|
icon: const Icon(Icons.delete_outline),
|
||||||
|
onPressed: s.moveTargets.length > i ? () => update((l) => l..removeAt(i)) : null,
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// 묶음 이름 → 위치 (바로가기 버튼으로 그 묶음까지 스크롤)
|
/// 묶음 이름 → 위치 (바로가기 버튼으로 그 묶음까지 스크롤)
|
||||||
final _groupKeys = <String, GlobalKey>{};
|
final _groupKeys = <String, GlobalKey>{};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ void main() {
|
||||||
test('이동: 동영상 + 옆의 같은 이름 자막을 옮기고 목록에서 뺀다. 같은 이름이 있으면 (2)', () async {
|
test('이동: 동영상 + 옆의 같은 이름 자막을 옮기고 목록에서 뺀다. 같은 이름이 있으면 (2)', () async {
|
||||||
final c = _controller();
|
final c = _controller();
|
||||||
final dest = p.join(dir.path, 'done');
|
final dest = p.join(dir.path, 'done');
|
||||||
c.settings.moveTargetDir = dest;
|
|
||||||
final a = VideoItem(make('a.mp4').path)
|
final a = VideoItem(make('a.mp4').path)
|
||||||
..subtitles.add(SubtitleEntry.external(path: make('a.ko.srt').path, language: undetermined))
|
..subtitles.add(SubtitleEntry.external(path: make('a.ko.srt').path, language: undetermined))
|
||||||
..subtitles.add(SubtitleEntry.external(path: make('other.srt').path, language: undetermined));
|
..subtitles.add(SubtitleEntry.external(path: make('other.srt').path, language: undetermined));
|
||||||
|
|
@ -43,7 +42,7 @@ void main() {
|
||||||
c.videos.addAll([a, b, busy]);
|
c.videos.addAll([a, b, busy]);
|
||||||
c.selected = a;
|
c.selected = a;
|
||||||
|
|
||||||
final (moved, errors) = await c.moveVideos([a, b, busy]);
|
final (moved, errors) = await c.moveVideos([a, b, busy], dest);
|
||||||
expect(moved, 2);
|
expect(moved, 2);
|
||||||
expect(errors.single, contains('작업 중'));
|
expect(errors.single, contains('작업 중'));
|
||||||
expect(File(p.join(dest, 'a.mp4')).existsSync(), isTrue);
|
expect(File(p.join(dest, 'a.mp4')).existsSync(), isTrue);
|
||||||
|
|
@ -80,25 +79,28 @@ void main() {
|
||||||
final c = _controller();
|
final c = _controller();
|
||||||
final a = VideoItem(make('a.mp4').path);
|
final a = VideoItem(make('a.mp4').path);
|
||||||
c.videos.add(a);
|
c.videos.add(a);
|
||||||
final (moved, errors) = await c.moveVideos([a]);
|
final (moved, errors) = await c.moveVideos([a], '');
|
||||||
expect(moved, 0);
|
expect(moved, 0);
|
||||||
expect(errors.single, contains('이동할 폴더'));
|
expect(errors.single, contains('이동할 폴더'));
|
||||||
expect(File(a.path).existsSync(), isTrue);
|
expect(File(a.path).existsSync(), isTrue);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('이동 폴더 설정 저장', () {
|
test('이동 버튼 설정 저장 (표시 이름 · 폴더 · 순서), 예전 이동 폴더 하나는 "이동" 버튼으로', () {
|
||||||
final s = AppSettings()..moveTargetDir = r'D:\done';
|
final s = AppSettings()
|
||||||
expect(AppSettings.fromJson(s.toJson()).moveTargetDir, r'D:\done');
|
..moveTargets = const [MoveTarget('완료', r'D:\done'), MoveTarget('보관', r'E:\archive')];
|
||||||
expect(AppSettings().moveTargetDir, isNull);
|
expect(AppSettings.fromJson(s.toJson()).moveTargets, s.moveTargets);
|
||||||
|
expect(AppSettings().moveTargets, isEmpty);
|
||||||
|
expect(AppSettings.fromJson({'moveTargetDir': r'D:\old'}).moveTargets, const [MoveTarget('이동', r'D:\old')]);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('MKV 목록: 세 번 누르면 이동 · 세부 정보의 [이동] 은 체크한 것 (없으면 보고 있는 것)', (tester) async {
|
testWidgets('MKV 목록: 세 번 누르면 첫 번째 이동 버튼으로 · 세부 정보의 이동 버튼 (표시 이름) 은 그 폴더로', (tester) async {
|
||||||
tester.view.physicalSize = const Size(1600, 900);
|
tester.view.physicalSize = const Size(1600, 900);
|
||||||
tester.view.devicePixelRatio = 1;
|
tester.view.devicePixelRatio = 1;
|
||||||
addTearDown(tester.view.reset);
|
addTearDown(tester.view.reset);
|
||||||
final c = _controller();
|
final c = _controller();
|
||||||
final dest = p.join(dir.path, 'done');
|
final dest = p.join(dir.path, 'done');
|
||||||
c.settings.moveTargetDir = dest;
|
final archive = p.join(dir.path, 'archive');
|
||||||
|
c.settings.moveTargets = [MoveTarget('완료함', dest), MoveTarget('보관함', archive)];
|
||||||
final a = VideoItem(make('a.mp4').path);
|
final a = VideoItem(make('a.mp4').path);
|
||||||
final b = VideoItem(make('b.mp4').path);
|
final b = VideoItem(make('b.mp4').path);
|
||||||
final d = VideoItem(make('d.mp4').path);
|
final d = VideoItem(make('d.mp4').path);
|
||||||
|
|
@ -124,13 +126,21 @@ void main() {
|
||||||
expect(File(p.join(dest, 'b.mp4')).existsSync(), isTrue);
|
expect(File(p.join(dest, 'b.mp4')).existsSync(), isTrue);
|
||||||
expect(c.videos.map((v) => v.fileName), ['a.mp4', 'd.mp4']);
|
expect(c.videos.map((v) => v.fileName), ['a.mp4', 'd.mp4']);
|
||||||
|
|
||||||
// 체크 없음: [이동] → 보고 있는 동영상 (a)
|
// 세부 정보 오른쪽 아래: 표시 이름 버튼 두 개 (첫 번째가 아래, 두 번째가 그 위)
|
||||||
c.select(a);
|
c.select(a);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('이동'), findsOneWidget);
|
expect(find.text('완료함'), findsOneWidget);
|
||||||
await tester.tap(find.text('이동'));
|
expect(find.text('보관함'), findsOneWidget);
|
||||||
|
expect(find.text('이동'), findsNothing);
|
||||||
|
expect(tester.getCenter(find.text('보관함')).dy, lessThan(tester.getCenter(find.text('완료함')).dy));
|
||||||
|
// 체크 없음: [보관함] → 보고 있는 동영상 (a) 를 보관 폴더로
|
||||||
|
await tester.tap(find.text('보관함'));
|
||||||
await settleIo();
|
await settleIo();
|
||||||
expect(File(p.join(dest, 'a.mp4')).existsSync(), isTrue);
|
expect(File(p.join(archive, 'a.mp4')).existsSync(), isTrue);
|
||||||
expect(c.videos.map((v) => v.fileName), ['d.mp4']);
|
expect(c.videos.map((v) => v.fileName), ['d.mp4']);
|
||||||
|
// 체크하면 버튼에 개수
|
||||||
|
c.toggleChecked(d);
|
||||||
|
await tester.pump();
|
||||||
|
expect(find.text('완료함 (1)'), findsOneWidget);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue