This commit is contained in:
@@ -8,7 +8,6 @@ struct DownloadPanelView: View {
|
|||||||
@State private var selectedDefinitions: [String: String] = [:]
|
@State private var selectedDefinitions: [String: String] = [:]
|
||||||
@State private var downloadDirectory: URL?
|
@State private var downloadDirectory: URL?
|
||||||
@State private var isDownloading = false
|
@State private var isDownloading = false
|
||||||
@State private var showToolsHelp = false
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 16) {
|
VStack(alignment: .leading, spacing: 16) {
|
||||||
@@ -51,20 +50,14 @@ struct DownloadPanelView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
Button("使用下载工具") {
|
|
||||||
showToolsHelp = true
|
|
||||||
}
|
|
||||||
.disabled(isDownloading)
|
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
Button("取消") {
|
Button("取消") {
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
.disabled(isDownloading)
|
.disabled(isDownloading)
|
||||||
|
|
||||||
Button("浏览器下载") {
|
Button("开始下载") {
|
||||||
Task { await startBrowserDownloads() }
|
Task { await startDownloads() }
|
||||||
}
|
}
|
||||||
.disabled(downloadDirectory == nil || isDownloading)
|
.disabled(downloadDirectory == nil || isDownloading)
|
||||||
.buttonStyle(.borderedProminent)
|
.buttonStyle(.borderedProminent)
|
||||||
@@ -81,9 +74,6 @@ struct DownloadPanelView: View {
|
|||||||
}
|
}
|
||||||
selectedDefinitions = defs
|
selectedDefinitions = defs
|
||||||
}
|
}
|
||||||
.sheet(isPresented: $showToolsHelp) {
|
|
||||||
DownloadToolsHelpView(items: items, selectedDefinitions: selectedDefinitions)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func selectDirectory() {
|
private func selectDirectory() {
|
||||||
@@ -97,7 +87,7 @@ struct DownloadPanelView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func startBrowserDownloads() async {
|
private func startDownloads() async {
|
||||||
guard let directory = downloadDirectory else { return }
|
guard let directory = downloadDirectory else { return }
|
||||||
isDownloading = true
|
isDownloading = true
|
||||||
|
|
||||||
@@ -127,75 +117,3 @@ struct DownloadPanelView: View {
|
|||||||
return String(format: "%.2f %@", size, units[i])
|
return String(format: "%.2f %@", size, units[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DownloadToolsHelpView: View {
|
|
||||||
let items: [(video: VideoItem, playInfos: [PlayInfo])]
|
|
||||||
let selectedDefinitions: [String: String]
|
|
||||||
@Environment(\.dismiss) private var dismiss
|
|
||||||
|
|
||||||
var selectedURLs: [String] {
|
|
||||||
items.compactMap { item -> String? in
|
|
||||||
guard let definition = selectedDefinitions[item.video.videoId] else { return nil }
|
|
||||||
return item.playInfos.first(where: { $0.definition == definition })?.playURL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var wgetCommand: String {
|
|
||||||
selectedURLs.map { "wget \"\($0)\"" }.joined(separator: "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
var aria2Command: String {
|
|
||||||
selectedURLs.map { "aria2c \"\($0)\"" }.joined(separator: "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
VStack(alignment: .leading, spacing: 16) {
|
|
||||||
Text("使用下载工具")
|
|
||||||
.font(.title2)
|
|
||||||
|
|
||||||
Text("浏览器对批量下载限制较多,推荐使用 aria2 或 wget 等命令行工具。先点击下方按钮复制全部链接,再粘贴到终端执行。")
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
|
|
||||||
HStack {
|
|
||||||
Button("复制全部链接") {
|
|
||||||
let pasteboard = NSPasteboard.general
|
|
||||||
pasteboard.clearContents()
|
|
||||||
pasteboard.setString(selectedURLs.joined(separator: "\n"), forType: .string)
|
|
||||||
}
|
|
||||||
Spacer()
|
|
||||||
Button("关闭") {
|
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text("aria2 示例(推荐)")
|
|
||||||
.font(.headline)
|
|
||||||
Text("aria2 支持断点续传、多线程下载,适合大文件。")
|
|
||||||
.font(.caption)
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
ScrollView {
|
|
||||||
Text(aria2Command)
|
|
||||||
.font(.system(.caption, design: .monospaced))
|
|
||||||
.padding(8)
|
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
|
||||||
.background(Color(.textBackgroundColor))
|
|
||||||
.cornerRadius(6)
|
|
||||||
}
|
|
||||||
.frame(maxHeight: 120)
|
|
||||||
|
|
||||||
Text("wget 示例")
|
|
||||||
.font(.headline)
|
|
||||||
ScrollView {
|
|
||||||
Text(wgetCommand)
|
|
||||||
.font(.system(.caption, design: .monospaced))
|
|
||||||
.padding(8)
|
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
|
||||||
.background(Color(.textBackgroundColor))
|
|
||||||
.cornerRadius(6)
|
|
||||||
}
|
|
||||||
.frame(maxHeight: 120)
|
|
||||||
}
|
|
||||||
.padding()
|
|
||||||
.frame(minWidth: 500, minHeight: 400)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user