From 6fe56c9cdf9d90f0256352e2fbd25fa5a4945c88 Mon Sep 17 00:00:00 2001 From: WindowsMEMZ Date: Sat, 24 Feb 2024 01:27:09 +0800 Subject: [PATCH] fix&feat: Fixed new video cover old video issue when download video with part. Added FileLocker --- DarockBili.xcodeproj/project.pbxproj | 20 +-- Localizable.xcstrings | 61 +++++++- MeowBili/InMain/MainView.swift | 8 +- MeowBili/InMain/SearchView.swift | 6 +- MeowBili/MeowBiliApp.swift | 43 +++++- MeowBili/Others/SettingsView.swift | 131 ++++++++++++++++- MeowBili/PersonalCenter/HistoryView.swift | 138 +++++++++++++++++- .../PersonalCenter/PersonAccountView.swift | 2 +- MeowBili/Video/VideoDetailView.swift | 34 ++--- MeowBili/Video/VideoDownloadView.swift | 4 +- ci_scripts/ci_post_xcodebuild.sh | 2 +- 11 files changed, 392 insertions(+), 57 deletions(-) diff --git a/DarockBili.xcodeproj/project.pbxproj b/DarockBili.xcodeproj/project.pbxproj index 3e4b64128..b6a885027 100644 --- a/DarockBili.xcodeproj/project.pbxproj +++ b/DarockBili.xcodeproj/project.pbxproj @@ -1461,7 +1461,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CODE_SIGN_ENTITLEMENTS = "MeowBili/MeowBili Vision App.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 817; + CURRENT_PROJECT_VERSION = 833; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1496,7 +1496,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CODE_SIGN_ENTITLEMENTS = "MeowBili/MeowBili Vision App.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 817; + CURRENT_PROJECT_VERSION = 833; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1533,7 +1533,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = MeowBili/MeowBili.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 817; + CURRENT_PROJECT_VERSION = 833; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1580,7 +1580,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = MeowBili/MeowBili.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 817; + CURRENT_PROJECT_VERSION = 833; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1624,7 +1624,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIconWatch; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 817; + CURRENT_PROJECT_VERSION = 833; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview\\ Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1660,7 +1660,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIconWatch; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 817; + CURRENT_PROJECT_VERSION = 833; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview\\ Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1699,7 +1699,7 @@ CODE_SIGN_ENTITLEMENTS = "MeowBili/MeowBili Mac App.entitlements"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 817; + CURRENT_PROJECT_VERSION = 833; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_HARDENED_RUNTIME = YES; @@ -1732,7 +1732,7 @@ CODE_SIGN_ENTITLEMENTS = "MeowBili/MeowBili Mac App.entitlements"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 817; + CURRENT_PROJECT_VERSION = 833; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_HARDENED_RUNTIME = YES; @@ -1761,7 +1761,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 817; + CURRENT_PROJECT_VERSION = 833; DEVELOPMENT_TEAM = B57D8PP775; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 16.0; @@ -1784,7 +1784,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 817; + CURRENT_PROJECT_VERSION = 833; DEVELOPMENT_TEAM = B57D8PP775; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 16.0; diff --git a/Localizable.xcstrings b/Localizable.xcstrings index cec759082..ea1457e20 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -256,9 +256,6 @@ } } } - }, - "%@ Channel" : { - }, "%@ 人在看" : { "localizations" : { @@ -7951,6 +7948,12 @@ } } } + }, + "上一小时" : { + + }, + "下一步" : { + }, "二维码名片" : { "localizations" : { @@ -7983,6 +7986,9 @@ } } } + }, + "今天" : { + }, "从关注列表中移除" : { @@ -8008,6 +8014,9 @@ } } } + }, + "使用恢复密钥" : { + }, "允许收集使用信息" : { @@ -8043,6 +8052,9 @@ } } } + }, + "分析与改进" : { + }, "动态" : { "localizations" : { @@ -8363,6 +8375,9 @@ }, "完成" : { + }, + "密码" : { + }, "将作为动态主体" : { "localizations" : { @@ -8517,6 +8532,9 @@ } } } + }, + "恢复密钥" : { + }, "您可以更改默认的小尾巴内容, 如果不想添加小尾巴, 请清空上方文本框内容. 您可以随时在设置中更改此内容" : { "localizations" : { @@ -8561,6 +8579,9 @@ } } } + }, + "所有历史记录" : { + }, "手记建议" : { "localizations" : { @@ -8599,6 +8620,22 @@ }, "搜索" : { + }, + "文件保险箱" : { + + }, + "文件保险箱已启用" : { + + }, + "文件保险箱通过对喵哩喵哩进行加密来保护 App 内的数据。\n\n警告:你将需要密码或恢复密钥才能访问数据。在此设置过程中,会自动生成恢复密钥。如果同时忘记了密码和恢复密钥,数据将会丢失。\n\n已%@喵哩喵哩的文件保险箱。%@" : { + "localizations" : { + "zh-Hans" : { + "stringUnit" : { + "state" : "new", + "value" : "文件保险箱通过对喵哩喵哩进行加密来保护 App 内的数据。\n\n警告:你将需要密码或恢复密钥才能访问数据。在此设置过程中,会自动生成恢复密钥。如果同时忘记了密码和恢复密钥,数据将会丢失。\n\n已%1$@喵哩喵哩的文件保险箱。%2$@" + } + } + } }, "文本加载失败" : { "localizations" : { @@ -8618,6 +8655,9 @@ }, "新建反馈" : { + }, + "昨天和今天" : { + }, "显示底部弹幕" : { "localizations" : { @@ -8770,6 +8810,12 @@ } } } + }, + "正在加密..." : { + + }, + "清除历史记录" : { + }, "清除所有已观看视频" : { "localizations" : { @@ -8792,6 +8838,9 @@ } } } + }, + "清除时间段" : { + }, "状态" : { @@ -9003,6 +9052,9 @@ } } } + }, + "请将恢复密钥保存到安全的位置" : { + }, "超大" : { "localizations" : { @@ -9035,6 +9087,9 @@ } } } + }, + "输入错误" : { + }, "选择图片" : { "localizations" : { diff --git a/MeowBili/InMain/MainView.swift b/MeowBili/InMain/MainView.swift index 488591e23..f2607452c 100644 --- a/MeowBili/InMain/MainView.swift +++ b/MeowBili/InMain/MainView.swift @@ -44,9 +44,6 @@ struct MainView: View { @State var userList3: [Any] = [] @State var userList4: [Any] = [] @State var isNewUserPresenting = false - #if os(watchOS) - @State var isSearchPresented = false - #endif var body: some View { #if !os(watchOS) MainViewMain() @@ -58,14 +55,11 @@ struct MainView: View { if #available(watchOS 10, *) { MainViewMain() .navigationBarTitleDisplayMode(.large) - .sheet(isPresented: $isSearchPresented, content: { SearchMainView() }) .sheet(isPresented: $isNetworkFixPresented, content: { NetworkFixView() }) .sheet(isPresented: $isLoginPresented, content: { LoginView() }) .toolbar { ToolbarItem(placement: .topBarLeading) { - Button(action: { - isSearchPresented = true - }, label: { + NavigationLink(destination: { SearchMainView() }, label: { Image(systemName: "magnifyingglass") .foregroundColor(.accentColor) }) diff --git a/MeowBili/InMain/SearchView.swift b/MeowBili/InMain/SearchView.swift index ae4f0835f..8fcab04ff 100644 --- a/MeowBili/InMain/SearchView.swift +++ b/MeowBili/InMain/SearchView.swift @@ -43,10 +43,10 @@ struct SearchMainView: View { var body: some View { List { Section { - VStack { + ZStack { NavigationLink("", destination: SearchView(keyword: searchText), isActive: $isSearchPresented) .frame(width: 0, height: 0) - .hidden() + .disabled(true) TextField("Search.\(Image(systemName: "magnifyingglass"))", text: $searchText) .submitLabel(.search) #if !os(watchOS) @@ -286,7 +286,9 @@ struct SearchView: View { } } } + #if !os(watchOS) .padding(.horizontal) + #endif if videos.isEmpty && users.isEmpty && articles.isEmpty && bangumis.isEmpty && liverooms.isEmpty && !isNoResult { ProgressView() } diff --git a/MeowBili/MeowBiliApp.swift b/MeowBili/MeowBiliApp.swift index 07c0778ff..c9fd4ede8 100644 --- a/MeowBili/MeowBiliApp.swift +++ b/MeowBili/MeowBiliApp.swift @@ -151,6 +151,12 @@ struct DarockBili_Watch_AppApp: App { // Handoff @State var handoffVideoDetails = [String: String]() @State var shouldPushVideoView = false + // FileLocker + @State var fileLockerPwd = UserDefaults.standard.string(forKey: "FileLockerPassword") ?? "" + @State var fileLockerRecoverCode = UserDefaults.standard.string(forKey: "FileLockerRecoverCode") ?? "" + @State var fileLockerRetryCount = 0 + @State var fileLockerInput = "" + @State var recoveryCodeInput = "" #if os(watchOS) @State var isMemoryWarningPresented = false #else @@ -158,8 +164,41 @@ struct DarockBili_Watch_AppApp: App { #endif var body: some SwiftUI.Scene { WindowGroup { - if UserDefaults.standard.string(forKey: "NewSignalError") ?? "" != "" { - SignalErrorView() + if fileLockerPwd != "" { + List { + Section { + Text(fileLockerRetryCount == 0 ? "文件保险箱已启用" : "输入错误") + .font(.title3) + .bold() + .listRowBackground(Color.clear) + } + Section { + TextField("密码", text: $fileLockerInput) + .submitLabel(.continue) + .onSubmit { + if fileLockerInput == fileLockerPwd { + fileLockerPwd = "" + } else { + fileLockerInput = "" + fileLockerRetryCount++ + } + } + } + if fileLockerRetryCount >= 3 { + Section { + TextField("使用恢复密钥", text: $recoveryCodeInput) + .submitLabel(.continue) + .onSubmit { + if recoveryCodeInput == fileLockerRecoverCode { + fileLockerPwd = "" + } else { + recoveryCodeInput = "" + fileLockerRetryCount++ + } + } + } + } + } } else { ZStack { #if !os(visionOS) diff --git a/MeowBili/Others/SettingsView.swift b/MeowBili/Others/SettingsView.swift index 1850fe6e8..3a8a478eb 100644 --- a/MeowBili/Others/SettingsView.swift +++ b/MeowBili/Others/SettingsView.swift @@ -719,19 +719,136 @@ struct DebugMenuView: View { } struct PrivacySettingsView: View { - @AppStorage("IsAllowMixpanel") var isAllowMixpanel = true var body: some View { List { Section { - Toggle("允许收集使用信息", isOn: $isAllowMixpanel) - } footer: { - Text("喵哩喵哩收集使用信息仅用以帮助改进质量,不会用于广告、个人画像之类,收集的信息不会关联到个人。此更改立即生效,不会影响哔哩哔哩官方对您的数据收集。") + NavigationLink(destination: { AnalyzeAImprove() }, label: { + Text("分析与改进") + }) } Section { - Link("喵哩喵哩开源页", destination: URL(string: "https://github.com/Darock-Studio/Darock-Bili")!) - } footer: { - Text("喵哩喵哩为完整开源项目,欢迎检查代码以确认无隐私问题") + NavigationLink(destination: { FileLocker() }, label: { + Text("文件保险箱") + }) + } + } + } + + struct AnalyzeAImprove: View { + @AppStorage("IsAllowMixpanel") var isAllowMixpanel = true + var body: some View { + List { + Section { + Toggle("允许收集使用信息", isOn: $isAllowMixpanel) + } footer: { + Text("喵哩喵哩收集使用信息仅用以帮助改进质量,不会用于广告、个人画像之类,收集的信息不会关联到个人。此更改立即生效,不会影响哔哩哔哩官方对您的数据收集。") + } + Section { + Link("喵哩喵哩开源页", destination: URL(string: "https://github.com/Darock-Studio/Darock-Bili")!) + } footer: { + Text("喵哩喵哩为完整开源项目,欢迎检查代码以确认无隐私问题") + } } + .navigationTitle("分析与改进") + } + } + struct FileLocker: View { + @State var isFileLockerEnabled = false + @State var isSetPasswdPresented = false + @State var passwdInput = "" + @State var gendRecCode = "" + @State var encryptProgress = 0.0 + @State var isFinishedEncrypt = false + var body: some View { + List { + Section { + Toggle("文件保险箱", isOn: $isFileLockerEnabled) + .onChange(of: isFileLockerEnabled) { value in + if value && UserDefaults.standard.string(forKey: "FileLockerPassword") == nil { + isSetPasswdPresented = true + } else if !value { + isFileLockerEnabled = false + UserDefaults.standard.removeObject(forKey: "FileLockerPassword") + UserDefaults.standard.removeObject(forKey: "FileLockerRecoverCode") + } + } + } + if encryptProgress > 0.0 && !isFinishedEncrypt { + Section { + VStack { + Text("正在加密...") + .bold() + ProgressView(value: encryptProgress) + .tint(Color.blue) + .frame(height: 15) + } + } + } + Section { + Text(""" + 文件保险箱通过对喵哩喵哩进行加密来保护 App 内的数据。 + + 警告:你将需要密码或恢复密钥才能访问数据。在此设置过程中,会自动生成恢复密钥。如果同时忘记了密码和恢复密钥,数据将会丢失。 + + 已\(isFileLockerEnabled ? "启用" : "停用")喵哩喵哩的文件保险箱。\(isFileLockerEnabled ? "\n恢复密钥已设置。" : "") + """) + .font(.system(size: 12)) + } + } + .onAppear { + if UserDefaults.standard.string(forKey: "FileLockerPassword") != nil { + isFileLockerEnabled = true + } + } + .sheet(isPresented: $isSetPasswdPresented, onDismiss: { + if UserDefaults.standard.string(forKey: "FileLockerPassword") != nil { + encryptProgress += 0.01 + isFileLockerEnabled = true + Timer.scheduledTimer(withTimeInterval: 2.5, repeats: true) { timer in + encryptProgress += Double.random(in: 0.1...0.3) + if encryptProgress >= 1.0 { + isFinishedEncrypt = true + timer.invalidate() + } + } + } else { + isFileLockerEnabled = false + } + }, content: { + NavigationStack { + List { + Section { + SecureField("密码", text: $passwdInput) + } + Section { + NavigationLink(destination: { + ScrollView { + VStack { + Text("恢复密钥") + .font(.title3) + Text(gendRecCode) + .font(.system(size: 14, weight: .bold).monospaced()) + Text("请将恢复密钥保存到安全的位置") + .font(.system(size: 12)) + Button(action: { + UserDefaults.standard.set(passwdInput, forKey: "FileLockerPassword") + UserDefaults.standard.set(gendRecCode, forKey: "FileLockerRecoverCode") + isSetPasswdPresented = false + }, label: { + Label("完成", systemImage: "checkmark") + }) + } + } + .onAppear { + gendRecCode = String(UuidInfoc.gen().dropLast(5)) + } + }, label: { + Text("下一步") + }) + } + } + } + }) } } } diff --git a/MeowBili/PersonalCenter/HistoryView.swift b/MeowBili/PersonalCenter/HistoryView.swift index 9e1e1d356..c694a2de8 100644 --- a/MeowBili/PersonalCenter/HistoryView.swift +++ b/MeowBili/PersonalCenter/HistoryView.swift @@ -32,6 +32,9 @@ struct HistoryView: View { @State var hasData = true @State var nowPage = 1 @State var totalPage = 1 + @State var isEmptyHistoryPresented = false + @State var selectedEmptyAction = 0 + @State var isDoingEmpty = false var body: some View { List { Group { @@ -125,9 +128,9 @@ struct HistoryView: View { for data in datas { let type = data.1["business"].string ?? "archive" if type == "archive" { - histories.append(["Type": type, "Pic": data.1["pic"].string!, "Title": data.1["title"].string!, "UP": data.1["owner"]["name"].string!, "Device": String(data.1["device"].int!), "BV": data.1["bvid"].string!, "View": String(data.1["stat"]["view"].int!), "Danmaku": String(data.1["stat"]["danmaku"].int!)]) + histories.append(["Type": type, "Pic": data.1["pic"].string!, "Title": data.1["title"].string!, "UP": data.1["owner"]["name"].string!, "Device": String(data.1["device"].int!), "BV": data.1["bvid"].string!, "View": String(data.1["stat"]["view"].int!), "Danmaku": String(data.1["stat"]["danmaku"].int!), "ViewTime": String(data.1["view_at"].int64 ?? 0)]) } else if type == "pgc" { - histories.append(["Type": type, "Data": BangumiData(mediaId: data.1["bangumi"]["ep_id"].int64 ?? 0, seasonId: data.1["bangumi"]["season"]["season_id"].int64 ?? 0, title: data.1["bangumi"]["long_title"].string ?? "[加载失败]", originalTitle: data.1["bangumi"]["season"]["title"].string ?? "[加载失败]", cover: data.1["bangumi"]["cover"].string ?? "E")]) + histories.append(["Type": type, "Data": BangumiData(mediaId: data.1["bangumi"]["ep_id"].int64 ?? 0, seasonId: data.1["bangumi"]["season"]["season_id"].int64 ?? 0, title: data.1["bangumi"]["long_title"].string ?? "[加载失败]", originalTitle: data.1["bangumi"]["season"]["title"].string ?? "[加载失败]", cover: data.1["bangumi"]["cover"].string ?? "E"), "ViewTime": String(data.1["view_at"].int64 ?? 0)]) } } hasData = true @@ -136,6 +139,137 @@ struct HistoryView: View { } } } + .toolbar { + if #available(watchOS 10, *) { + ToolbarItem(placement: .topBarTrailing) { + Button(action: { + isEmptyHistoryPresented = true + }, label: { + Image(systemName: "arrow.up.trash.fill") + }) + .sheet(isPresented: $isEmptyHistoryPresented, onDismiss: { + + }, content: { + NavigationStack { + List { + Section { + Button(action: { + selectedEmptyAction = 0 + }, label: { + HStack { + Text("上一小时") + .foregroundStyle(Color.white) + Spacer() + if selectedEmptyAction == 0 { + Image(systemName: "checkmark") + .foregroundStyle(Color.blue) + } + } + }) + Button(action: { + selectedEmptyAction = 1 + }, label: { + HStack { + Text("今天") + .foregroundStyle(Color.white) + Spacer() + if selectedEmptyAction == 1 { + Image(systemName: "checkmark") + .foregroundStyle(Color.blue) + } + } + }) + Button(action: { + selectedEmptyAction = 2 + }, label: { + HStack { + Text("昨天和今天") + .foregroundStyle(Color.white) + Spacer() + if selectedEmptyAction == 2 { + Image(systemName: "checkmark") + .foregroundStyle(Color.blue) + } + } + }) + Button(action: { + selectedEmptyAction = 3 + }, label: { + HStack { + Text("所有历史记录") + .foregroundStyle(Color.white) + Spacer() + if selectedEmptyAction == 3 { + Image(systemName: "checkmark") + .foregroundStyle(Color.blue) + } + } + }) + } header: { + Text("清除时间段") + } + Section { + Button(role: .destructive, action: { + isDoingEmpty = true + if selectedEmptyAction == 3 { + let headers: HTTPHeaders = [ + "cookie": "SESSDATA=\(sessdata);", + "User-Agent": "Mozilla/5.0 (X11; CrOS x86_64 14541.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" + ] + AF.request("https://api.bilibili.com/x/v2/history/clear", method: .post, parameters: ["csrf": biliJct], headers: headers).response { _ in + isEmptyHistoryPresented = false + } + } else { + let clearSec: Int + if selectedEmptyAction == 0 { + clearSec = 3600 + } else if selectedEmptyAction == 1 { + clearSec = 86400 + } else if selectedEmptyAction == 2 { + clearSec = 172800 + } else { + clearSec = 0 + } + let headers: HTTPHeaders = [ + "cookie": "SESSDATA=\(sessdata);", + "User-Agent": "Mozilla/5.0 (X11; CrOS x86_64 14541.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" + ] + for history in histories { + let vt = Int64((history as! [String: Any])["ViewTime"]! as! String)! + let ct = Int64(Date.now.timeStamp) + if ct - vt < clearSec { + if (history as! [String: Any])["Type"]! as! String == "archive" { + AF.request("https://api.bilibili.com/x/v2/history/delete?kid=archive_\(bv2av(bvid: (history as! [String: String])["BV"]!))&csrf=\(biliJct)", method: .post, headers: headers).response { response in + debugPrint(response) + } + } else if (history as! [String: Any])["Type"]! as! String == "pgc" { + AF.request("https://api.bilibili.com/x/v2/history/delete?kid=pgc_\(((history as! [String: Any])["Data"] as! BangumiData).seasonId)&csrf=\(biliJct)", method: .post, headers: headers).response { response in + debugPrint(response) + } + } + } else { + break + } + } + isEmptyHistoryPresented = false + } + }, label: { + if !isDoingEmpty { + Text("清除历史记录") + .bold() + } else { + ProgressView() + } + }) + .disabled(isDoingEmpty) + } + } + .navigationTitle("清除历史记录") + } + }) + } + } + } } } diff --git a/MeowBili/PersonalCenter/PersonAccountView.swift b/MeowBili/PersonalCenter/PersonAccountView.swift index 70689f3ed..06987e5c3 100644 --- a/MeowBili/PersonalCenter/PersonAccountView.swift +++ b/MeowBili/PersonalCenter/PersonAccountView.swift @@ -224,7 +224,7 @@ struct PersonAccountView: View { #if !os(watchOS) .font(.system(size: 20)) #else - .font(.system(size: 15)) + .font(.system(size: 13)) #endif .redacted(reason: .placeholder) } diff --git a/MeowBili/Video/VideoDetailView.swift b/MeowBili/Video/VideoDetailView.swift index f671c6e87..7e800d508 100644 --- a/MeowBili/Video/VideoDetailView.swift +++ b/MeowBili/Video/VideoDetailView.swift @@ -1593,26 +1593,18 @@ struct VideoDetailView: View { }) .swipeActions { Button(action: { - if videoGetterSource == "official" { - let headers: HTTPHeaders = [ - "cookie": "SESSDATA=\(sessdata)", - "User-Agent": "Mozilla/5.0 (X11; CrOS x86_64 14541.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" - ] - let cid = videoPages[i]["CID"]! - videoCID = Int64(cid)! - DarockKit.Network.shared.requestJSON("https://api.bilibili.com/x/player/playurl?platform=html5&bvid=\(videoDetails["BV"]!)&cid=\(cid)", headers: headers) { respJson, isSuccess in - if isSuccess { - if !CheckBApiError(from: respJson) { return } - VideoDownloadView.downloadLink = respJson["data"]["durl"][0]["url"].string!.replacingOccurrences(of: "\\u0026", with: "&") - isDownloadPresented = true - } - } - } else if videoGetterSource == "injahow" { - DarockKit.Network.shared.requestString("https://api.injahow.cn/bparse/?bv=\(videoDetails["BV"]!.dropFirst().dropFirst())&p=\(i + 1)&type=video&q=32&format=mp4&otype=url") { respStr, isSuccess in - if isSuccess { - VideoDownloadView.downloadLink = respStr - isDownloadPresented = true - } + let headers: HTTPHeaders = [ + "cookie": "SESSDATA=\(sessdata)", + "User-Agent": "Mozilla/5.0 (X11; CrOS x86_64 14541.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" + ] + let cid = videoPages[i]["CID"]! + videoCID = Int64(cid)! + DarockKit.Network.shared.requestJSON("https://api.bilibili.com/x/player/playurl?platform=html5&bvid=\(videoDetails["BV"]!)&cid=\(cid)", headers: headers) { respJson, isSuccess in + if isSuccess { + if !CheckBApiError(from: respJson) { return } + VideoDownloadView.downloadLink = respJson["data"]["durl"][0]["url"].string!.replacingOccurrences(of: "\\u0026", with: "&") + VideoDownloadView.downloadCID = videoCID + isDownloadPresented = true } } }, label: { @@ -1622,7 +1614,7 @@ struct VideoDetailView: View { } } } - .sheet(isPresented: $isDownloadPresented, content: { VideoDownloadView(bvid: videoDetails["BV"]!, videoDetails: videoDetails) }) + .sheet(isPresented: $isDownloadPresented, content: { VideoDownloadView(bvid: videoDetails["BV"]!, videoDetails: videoDetails, isPaged: true) }) .sheet(isPresented: $isVideoPlayerPresented, content: { VideoPlayerView(videoDetails: $videoDetails, videoLink: $videoLink, videoBvid: $videoBvid, videoCID: $videoCID) .navigationBarHidden(true) diff --git a/MeowBili/Video/VideoDownloadView.swift b/MeowBili/Video/VideoDownloadView.swift index 03e7ac70d..fe0d6af3d 100644 --- a/MeowBili/Video/VideoDownloadView.swift +++ b/MeowBili/Video/VideoDownloadView.swift @@ -27,7 +27,9 @@ var videoDownloadRequests = [DownloadRequest]() struct VideoDownloadView: View { var bvid: String var videoDetails: [String: String] + var isPaged = false public static var downloadLink: String? + public static var downloadCID: Int64? @Environment(\.dismiss) var dismiss @AppStorage("DedeUserID") var dedeUserID = "" @AppStorage("DedeUserID__ckMd5") var dedeUserID__ckMd5 = "" @@ -86,7 +88,7 @@ struct VideoDownloadView: View { ] let destination: DownloadRequest.Destination = { _, _ in let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] - let fileURL = documentsURL.appendingPathComponent("dlds/\(bvid).mp4") + let fileURL = documentsURL.appendingPathComponent("dlds/\(bvid)\(isPaged ? String(VideoDownloadView.downloadCID!) : "").mp4") return (fileURL, [.removePreviousFile, .createIntermediateDirectories]) } diff --git a/ci_scripts/ci_post_xcodebuild.sh b/ci_scripts/ci_post_xcodebuild.sh index 18a0dc3d7..733da08f4 100755 --- a/ci_scripts/ci_post_xcodebuild.sh +++ b/ci_scripts/ci_post_xcodebuild.sh @@ -5,5 +5,5 @@ if [[ "$CI_WORKFLOW" == "Canary Deploy" ]]; then TESTFLIGHT_DIR_PATH=../TestFlight mkdir $TESTFLIGHT_DIR_PATH echo "CI 自动生成信息,24小时内的main分支的提交:\n" > $TESTFLIGHT_DIR_PATH/WhatToTest.zh-Hans.txt - git fetch && git log --since="24 hours ago" main --pretty=format:"%s" >> $TESTFLIGHT_DIR_PATH/WhatToTest.zh-Hans.txt + git fetch -a && git log --since="24 hours ago" main --pretty=format:"%s" >> $TESTFLIGHT_DIR_PATH/WhatToTest.zh-Hans.txt fi