diff --git a/DarockBili.xcodeproj/project.pbxproj b/DarockBili.xcodeproj/project.pbxproj index 326a7cfdd..0e6662f6b 100644 --- a/DarockBili.xcodeproj/project.pbxproj +++ b/DarockBili.xcodeproj/project.pbxproj @@ -1146,7 +1146,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CODE_SIGN_ENTITLEMENTS = "MeowBili/MeowBili Vision App.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 755; + CURRENT_PROJECT_VERSION = 773; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1181,7 +1181,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CODE_SIGN_ENTITLEMENTS = "MeowBili/MeowBili Vision App.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 755; + CURRENT_PROJECT_VERSION = 773; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1218,7 +1218,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = MeowBili/MeowBili.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 755; + CURRENT_PROJECT_VERSION = 773; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1265,7 +1265,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = MeowBili/MeowBili.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 755; + CURRENT_PROJECT_VERSION = 773; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1309,7 +1309,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIconWatch; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 755; + CURRENT_PROJECT_VERSION = 773; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview\\ Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1345,7 +1345,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIconWatch; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 755; + CURRENT_PROJECT_VERSION = 773; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview\\ Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; diff --git a/MeowBili/Assets.xcassets/AppIconFrontImage.imageset/Contents.json b/MeowBili/Assets.xcassets/AppIconFrontImage.imageset/Contents.json new file mode 100644 index 000000000..8deeb19fd --- /dev/null +++ b/MeowBili/Assets.xcassets/AppIconFrontImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "VisionAppIco-Front.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "VisionAppIco-Front 1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "VisionAppIco-Front 2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MeowBili/Assets.xcassets/AppIconFrontImage.imageset/VisionAppIco-Front 1.png b/MeowBili/Assets.xcassets/AppIconFrontImage.imageset/VisionAppIco-Front 1.png new file mode 100644 index 000000000..cc048cf0c Binary files /dev/null and b/MeowBili/Assets.xcassets/AppIconFrontImage.imageset/VisionAppIco-Front 1.png differ diff --git a/MeowBili/Assets.xcassets/AppIconFrontImage.imageset/VisionAppIco-Front 2.png b/MeowBili/Assets.xcassets/AppIconFrontImage.imageset/VisionAppIco-Front 2.png new file mode 100644 index 000000000..cc048cf0c Binary files /dev/null and b/MeowBili/Assets.xcassets/AppIconFrontImage.imageset/VisionAppIco-Front 2.png differ diff --git a/MeowBili/Assets.xcassets/AppIconFrontImage.imageset/VisionAppIco-Front.png b/MeowBili/Assets.xcassets/AppIconFrontImage.imageset/VisionAppIco-Front.png new file mode 100644 index 000000000..cc048cf0c Binary files /dev/null and b/MeowBili/Assets.xcassets/AppIconFrontImage.imageset/VisionAppIco-Front.png differ diff --git a/MeowBili/MeowBiliApp.swift b/MeowBili/MeowBiliApp.swift index f8a1c6bd3..615e6bc5d 100644 --- a/MeowBili/MeowBiliApp.swift +++ b/MeowBili/MeowBiliApp.swift @@ -206,14 +206,16 @@ struct DarockBili_Watch_AppApp: App { if shouldShowAppName { VStack { Spacer() - .frame(height: 5) + .frame(height: 12) ZStack { Capsule() .fill(Color.accentColor) - .frame(width: 100, height: 25) - Text("喵哩喵哩") - .foregroundStyle(Color.white) - .font(.system(size: 16, weight: .semibold)) + .frame(width: 60, height: 20) + HStack { + Text("喵哩喵哩") + .foregroundStyle(Color.white) + .font(.system(size: 12, weight: .medium)) + } } Spacer() } @@ -367,7 +369,7 @@ struct DarockBili_Watch_AppApp: App { case .background: break case .inactive: - #if !os(watchOS) && !os(visionOS) + #if os(iOS) shouldShowAppName = false #endif case .active: diff --git a/MeowBili/PersonalCenter/UserDetailView.swift b/MeowBili/PersonalCenter/UserDetailView.swift index 0a1496ee2..12e393358 100644 --- a/MeowBili/PersonalCenter/UserDetailView.swift +++ b/MeowBili/PersonalCenter/UserDetailView.swift @@ -327,27 +327,25 @@ struct UserDetailView: View { .navigationTitle(username) .sheet(isPresented: $isInfoSheetPresented, content: { ScrollView { - SecondPageBase(officialType: $officialType, officialTitle: $officialTitle, userSign: $userSign, userLevel: $userLevel, vipLabel: $vipLabel) + SecondPageBase(uid: uid, officialType: $officialType, officialTitle: $officialTitle, userSign: $userSign, userLevel: $userLevel, vipLabel: $vipLabel) } }) - ScrollView { - VideosListBase(uid: uid, username: $username, videos: $videos, articles: $articles, viewSelector: $viewSelector, videoCount: $videoCount, articalCount: $articalCount) - .tag(2) - .navigationTitle(viewSelector == .video ? "Account.videos.\(videoCount)" : "Account.articals.\(articalCount)") - .toolbar { - ToolbarItem(placement: .topBarTrailing) { - Button(action: { - if viewSelector == .video { - viewSelector = .article - } else if viewSelector == .article { - viewSelector = .video - } - }, label: { - Image(systemName: viewSelector == .video ? "play.circle" : "doc.text.image") - }) - } + VideosListBase(uid: uid, username: $username, videos: $videos, articles: $articles, viewSelector: $viewSelector, videoCount: $videoCount, articalCount: $articalCount) + .tag(2) + .navigationTitle(viewSelector == .video ? "Account.videos.\(videoCount)" : "Account.articals.\(articalCount)") + .toolbar { + ToolbarItem(placement: .topBarTrailing) { + Button(action: { + if viewSelector == .video { + viewSelector = .article + } else if viewSelector == .article { + viewSelector = .video + } + }, label: { + Image(systemName: viewSelector == .video ? "play.circle" : "doc.text.image") + }) } - } + } } .tabViewStyle(.verticalPage) .containerBackground(Color.accentColor.gradient, for: .navigation) @@ -358,7 +356,7 @@ struct UserDetailView: View { .offset(y: -10) .navigationTitle(username) .tag(1) - SecondPageBase(officialType: $officialType, officialTitle: $officialTitle, userSign: $userSign, userLevel: $userLevel, vipLabel: $vipLabel) + SecondPageBase(uid: uid, officialType: $officialType, officialTitle: $officialTitle, userSign: $userSign, userLevel: $userLevel, vipLabel: $vipLabel) .tag(2) } VideosListBase(uid: uid, username: $username, videos: $videos, articles: $articles, viewSelector: $viewSelector, videoCount: $videoCount, articalCount: $articalCount) @@ -789,6 +787,7 @@ struct UserDetailView: View { } } struct SecondPageBase: View { + var uid: String @Binding var officialType: Int @Binding var officialTitle: String @Binding var userSign: String @@ -803,6 +802,14 @@ struct UserDetailView: View { Color(red: 234/255, green: 51/255, blue: 35/255)] //6 var body: some View { VStack { + HStack { + Image(systemName: "person.text.rectangle") + .foregroundColor(.secondary) + .frame(width: 20, height: 20) + Text(uid) + .font(.system(size: 15)) + Spacer() + } if officialType != -1 { HStack { Image(systemName: "bolt.circle") @@ -851,314 +858,314 @@ struct UserDetailView: View { } } struct VideosListBase: View { - var uid: String - @Binding var username: String - @Binding var videos: [[String: String]] - @Binding var articles: [[String: String]] - @Binding var viewSelector: UserDetailViewPubsType - @Binding var videoCount: Int - @Binding var articalCount: Int - @AppStorage("DedeUserID") var dedeUserID = "" - @AppStorage("DedeUserID__ckMd5") var dedeUserID__ckMd5 = "" - @AppStorage("SESSDATA") var sessdata = "" - @AppStorage("bili_jct") var biliJct = "" - @State var isNoVideo = false - @State var isNoArticle = false - @State var isVideosLoaded = false - @State var isArticlesLoaded = false - @State var videoTotalPage = 1 - @State var videoNowPage = 1 - @State var articleTotalPage = 1 - @State var articleNowPage = 1 - @State var isVideoPageJumpPresented = false - @State var videoTargetJumpPageCache = "" - @State var isArticalPageJumpPresented = false - @State var articleTargetJumpPageCache = "" - var body: some View { + var uid: String + @Binding var username: String + @Binding var videos: [[String: String]] + @Binding var articles: [[String: String]] + @Binding var viewSelector: UserDetailViewPubsType + @Binding var videoCount: Int + @Binding var articalCount: Int + @AppStorage("DedeUserID") var dedeUserID = "" + @AppStorage("DedeUserID__ckMd5") var dedeUserID__ckMd5 = "" + @AppStorage("SESSDATA") var sessdata = "" + @AppStorage("bili_jct") var biliJct = "" + @State var isNoVideo = false + @State var isNoArticle = false + @State var isVideosLoaded = false + @State var isArticlesLoaded = false + @State var videoTotalPage = 1 + @State var videoNowPage = 1 + @State var articleTotalPage = 1 + @State var articleNowPage = 1 + @State var isVideoPageJumpPresented = false + @State var videoTargetJumpPageCache = "" + @State var isArticalPageJumpPresented = false + @State var articleTargetJumpPageCache = "" + var body: some View { + ScrollView { VStack { - Group { - if #unavailable(watchOS 10) { - Button(action: { - if viewSelector == .video { - viewSelector = .article - } else if viewSelector == .article { - viewSelector = .video - } - }, label: { - HStack { - Image(systemName: viewSelector == .video ? "play.circle" : "doc.text.image") - Text(viewSelector == .video ? String(localized: "Account.check-videos") : String(localized: "Account.check-articles")) - } - }) - Spacer() - .frame(height: 20) - } - if viewSelector == .video { - VStack { - if videos.count != 0 { - ForEach(0...videos.count - 1, id: \.self) { i in - VideoCard(["Pic": videos[i]["PicUrl"]!, "Title": videos[i]["Title"]!, "BV": videos[i]["BV"]!, "UP": username, "View": videos[i]["PlayCount"]!, "Danmaku": videos[i]["DanmakuCount"]!]) - } - Spacer() - .frame(height: 20) - VStack { - if videoNowPage != 1 { - Button(action: { - videoNowPage -= 1 - RefreshVideos() - }, label: { - Text("Account.list.last-page") - .bold() - }) - } - Text("\(videoNowPage) / \(videoTotalPage)") - .font(.system(size: 18, weight: .bold)) - .sheet(isPresented: $isVideoPageJumpPresented, content: { - VStack { - Text("Account.list.goto") - .font(.system(size: 20, weight: .bold)) - HStack { - TextField("Account.list.destination", text: $videoTargetJumpPageCache) - .onSubmit { - if let cInt = Int(videoTargetJumpPageCache) { - if cInt <= 0 { - videoTargetJumpPageCache = "1" - } - if cInt > videoTotalPage { - videoTargetJumpPageCache = String(videoTotalPage) - } - } else { - videoTargetJumpPageCache = String(videoNowPage) - } - } - Text(" / \(videoTotalPage)") - } - Button(action: { - if let cInt = Int(videoTargetJumpPageCache) { - videoNowPage = cInt - RefreshVideos() - } - isVideoPageJumpPresented = false - }, label: { - Text("Account.list.go") - }) - } - }) - .onTapGesture { - videoTargetJumpPageCache = String(videoNowPage) - isVideoPageJumpPresented = true - } - if videoNowPage != videoTotalPage { - Button(action: { - videoNowPage += 1 - RefreshVideos() - }, label: { - Text("Account.list.next-page") - .bold() - }) - } - } - } else { - if isNoVideo { - Text("Account.list.no-video") - } else { - ProgressView() - } - } + if #unavailable(watchOS 10) { + Button(action: { + if viewSelector == .video { + viewSelector = .article + } else if viewSelector == .article { + viewSelector = .video } - } else if viewSelector == .article { - VStack { - if articles.count != 0 { - ForEach(0...articles.count - 1, id: \.self) { i in - Button(action: { - let session = ASWebAuthenticationSession(url: URL(string: "https://www.bilibili.com/read/cv\(articles[i]["CV"]!)")!, callbackURLScheme: nil) { _, _ in - return - } - session.prefersEphemeralWebBrowserSession = true - session.start() - }, label: { - VStack { - Text(articles[i]["Title"]!) - .font(.system(size: 16, weight: .bold)) - .lineLimit(3) - HStack { - VStack { - Text(articles[i]["Summary"]!) - .font(.system(size: 10, weight: .bold)) - .lineLimit(3) - .foregroundColor(.gray) - HStack { - Text(articles[i]["Type"]!) - .font(.system(size: 10)) - .lineLimit(1) - .foregroundColor(.gray) - Label(articles[i]["View"]!, systemImage: "eye.fill") - .font(.system(size: 10)) - .lineLimit(1) - .foregroundColor(.gray) - Label(articles[i]["Like"]!, systemImage: "hand.thumbsup.fill") - .font(.system(size: 10)) - .lineLimit(1) - .foregroundColor(.gray) - } - } - WebImage(url: URL(string: articles[i]["Pic"]! + "@60w"), options: [.progressiveLoad]) - .cornerRadius(5) - } - } - }) - .buttonBorderShape(.roundedRectangle(radius: 14)) - } - - if articleNowPage != 1 { + }, label: { + HStack { + Image(systemName: viewSelector == .video ? "play.circle" : "doc.text.image") + Text(viewSelector == .video ? String(localized: "Account.check-videos") : String(localized: "Account.check-articles")) + } + }) + Spacer() + .frame(height: 20) + } + if viewSelector == .video { + VStack { + if videos.count != 0 { + ForEach(0...videos.count - 1, id: \.self) { i in + VideoCard(["Pic": videos[i]["PicUrl"]!, "Title": videos[i]["Title"]!, "BV": videos[i]["BV"]!, "UP": username, "View": videos[i]["PlayCount"]!, "Danmaku": videos[i]["DanmakuCount"]!]) + } + Spacer() + .frame(height: 20) + VStack { + if videoNowPage != 1 { Button(action: { - articleNowPage -= 1 - RefreshArticles() + videoNowPage -= 1 + RefreshVideos() }, label: { Text("Account.list.last-page") .bold() }) } - Text("\(articleNowPage) / \(articleTotalPage)") + Text("\(videoNowPage) / \(videoTotalPage)") .font(.system(size: 18, weight: .bold)) - .sheet(isPresented: $isArticalPageJumpPresented, content: { + .sheet(isPresented: $isVideoPageJumpPresented, content: { VStack { Text("Account.list.goto") .font(.system(size: 20, weight: .bold)) HStack { - TextField("Account.list.destination", text: $articleTargetJumpPageCache) + TextField("Account.list.destination", text: $videoTargetJumpPageCache) .onSubmit { - if let cInt = Int(articleTargetJumpPageCache) { + if let cInt = Int(videoTargetJumpPageCache) { if cInt <= 0 { - articleTargetJumpPageCache = "1" + videoTargetJumpPageCache = "1" } - if cInt > articleTotalPage { - articleTargetJumpPageCache = String(articleTotalPage) + if cInt > videoTotalPage { + videoTargetJumpPageCache = String(videoTotalPage) } } else { - articleTargetJumpPageCache = String(articleNowPage) + videoTargetJumpPageCache = String(videoNowPage) } } - Text(" / \(articleTotalPage)") + Text(" / \(videoTotalPage)") } Button(action: { - if let cInt = Int(articleTargetJumpPageCache) { - articleNowPage = cInt - RefreshArticles() + if let cInt = Int(videoTargetJumpPageCache) { + videoNowPage = cInt + RefreshVideos() } - isArticalPageJumpPresented = false + isVideoPageJumpPresented = false }, label: { Text("Account.list.go") }) } }) .onTapGesture { - articleTargetJumpPageCache = String(articleNowPage) - isArticalPageJumpPresented = true + videoTargetJumpPageCache = String(videoNowPage) + isVideoPageJumpPresented = true } - if articleNowPage != articleTotalPage { + if videoNowPage != videoTotalPage { Button(action: { - articleNowPage += 1 - RefreshArticles() + videoNowPage += 1 + RefreshVideos() }, label: { Text("Account.list.next-page") .bold() }) } + } + } else { + if isNoVideo { + Text("Account.list.no-video") } else { - if isNoArticle { - Text("Account.list.no-article") - } else { - ProgressView() - } + ProgressView() } } - .onAppear { - RefreshArticles() - } - .onDisappear { - articles = [[String: String]]() + } + } else if viewSelector == .article { + VStack { + if articles.count != 0 { + ForEach(0...articles.count - 1, id: \.self) { i in + Button(action: { + let session = ASWebAuthenticationSession(url: URL(string: "https://www.bilibili.com/read/cv\(articles[i]["CV"]!)")!, callbackURLScheme: nil) { _, _ in + return + } + session.prefersEphemeralWebBrowserSession = true + session.start() + }, label: { + VStack { + Text(articles[i]["Title"]!) + .font(.system(size: 16, weight: .bold)) + .lineLimit(3) + HStack { + VStack { + Text(articles[i]["Summary"]!) + .font(.system(size: 10, weight: .bold)) + .lineLimit(3) + .foregroundColor(.gray) + HStack { + Text(articles[i]["Type"]!) + .font(.system(size: 10)) + .lineLimit(1) + .foregroundColor(.gray) + Label(articles[i]["View"]!, systemImage: "eye.fill") + .font(.system(size: 10)) + .lineLimit(1) + .foregroundColor(.gray) + Label(articles[i]["Like"]!, systemImage: "hand.thumbsup.fill") + .font(.system(size: 10)) + .lineLimit(1) + .foregroundColor(.gray) + } + } + WebImage(url: URL(string: articles[i]["Pic"]! + "@60w"), options: [.progressiveLoad]) + .cornerRadius(5) + } + } + }) + .buttonBorderShape(.roundedRectangle(radius: 14)) + } + + if articleNowPage != 1 { + Button(action: { + articleNowPage -= 1 + RefreshArticles() + }, label: { + Text("Account.list.last-page") + .bold() + }) + } + Text("\(articleNowPage) / \(articleTotalPage)") + .font(.system(size: 18, weight: .bold)) + .sheet(isPresented: $isArticalPageJumpPresented, content: { + VStack { + Text("Account.list.goto") + .font(.system(size: 20, weight: .bold)) + HStack { + TextField("Account.list.destination", text: $articleTargetJumpPageCache) + .onSubmit { + if let cInt = Int(articleTargetJumpPageCache) { + if cInt <= 0 { + articleTargetJumpPageCache = "1" + } + if cInt > articleTotalPage { + articleTargetJumpPageCache = String(articleTotalPage) + } + } else { + articleTargetJumpPageCache = String(articleNowPage) + } + } + Text(" / \(articleTotalPage)") + } + Button(action: { + if let cInt = Int(articleTargetJumpPageCache) { + articleNowPage = cInt + RefreshArticles() + } + isArticalPageJumpPresented = false + }, label: { + Text("Account.list.go") + }) + } + }) + .onTapGesture { + articleTargetJumpPageCache = String(articleNowPage) + isArticalPageJumpPresented = true + } + if articleNowPage != articleTotalPage { + Button(action: { + articleNowPage += 1 + RefreshArticles() + }, label: { + Text("Account.list.next-page") + .bold() + }) + } + } else { + if isNoArticle { + Text("Account.list.no-article") + } else { + ProgressView() + } } } + .onAppear { + RefreshArticles() + } + .onDisappear { + articles = [[String: String]]() + } } } - .onAppear { - if !isVideosLoaded { - RefreshVideos() - } + } + .onAppear { + if !isVideosLoaded { + RefreshVideos() } } - - func RefreshVideos() { - videos = [[String: String]]() - let headers: HTTPHeaders = [ - //"accept": "*/*", - //"accept-encoding": "gzip, deflate, br", - //"accept-language": "zh-CN,zh;q=0.9", - //"cookie": "\(sessdata == "" ? "" : "SESSDATA=\(sessdata); ")buvid3=\(globalBuvid3); b_nut=\(Date.now.timeStamp); buvid4=\(globalBuvid4);", - "cookie": "SESSDATA=\(sessdata); buvid_fp=e651c1a382430ea93631e09474e0b395; buvid3=\(UuidInfoc.gen()); buvid4=buvid4-failed-1", - //"origin": "https://space.bilibili.com", - //"referer": "https://space.bilibili.com/\(uid)/video", - //"User-Agent": "Mozilla/5.0" // Bypass? drdar://gh/SocialSisterYi/bilibili-API-collect/issues/868/1859065874 - "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" - ] - biliWbiSign(paramEncoded: "mid=\(uid)&ps=50&pn=\(videoNowPage)&dm_img_list=[]&dm_img_str=V2ViR0wgMS4wIChPcGVuR0wgRVMgMi4wIENocm9taXVtKQ&dm_cover_img_str=VjNEIDQuMkJyb2FkY2".base64Encoded()) { signed in - if let signed { - debugPrint(signed) - autoRetryRequestApi("https://api.bilibili.com/x/space/wbi/arc/search?\(signed)", headers: headers) { respJson, isSuccess in - if isSuccess { - debugPrint(respJson) - if !CheckBApiError(from: respJson) { return } - let vlist = respJson["data"]["list"]["vlist"] - for video in vlist { - videos.append(["Title": video.1["title"].string ?? "[加载失败]", "Length": video.1["length"].string ?? "E", "PlayCount": String(video.1["play"].int ?? -1), "PicUrl": video.1["pic"].string ?? "E", "BV": video.1["bvid"].string ?? "E", "Timestamp": String(video.1["created"].int ?? 0), "DanmakuCount": String(video.1["video_review"].int ?? -1)]) - } - debugPrint(respJson["data"]["page"]["count"].int ?? 0) - videoTotalPage = Int((respJson["data"]["page"]["count"].int ?? 0) / 50) + 1 - videoCount = respJson["data"]["page"]["count"].int ?? 0 - if !isVideosLoaded { - if videos.count == 0 { - isNoVideo = true - } - isVideosLoaded = true + } + + func RefreshVideos() { + videos = [[String: String]]() + let headers: HTTPHeaders = [ + //"accept": "*/*", + //"accept-encoding": "gzip, deflate, br", + //"accept-language": "zh-CN,zh;q=0.9", + //"cookie": "\(sessdata == "" ? "" : "SESSDATA=\(sessdata); ")buvid3=\(globalBuvid3); b_nut=\(Date.now.timeStamp); buvid4=\(globalBuvid4);", + "cookie": "SESSDATA=\(sessdata); buvid_fp=e651c1a382430ea93631e09474e0b395; buvid3=\(UuidInfoc.gen()); buvid4=buvid4-failed-1", + //"origin": "https://space.bilibili.com", + //"referer": "https://space.bilibili.com/\(uid)/video", + //"User-Agent": "Mozilla/5.0" // Bypass? rdar://gh/SocialSisterYi/bilibili-API-collect/issues/868#1859065874 + "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" + ] + biliWbiSign(paramEncoded: "mid=\(uid)&ps=50&pn=\(videoNowPage)&dm_img_list=[]&dm_img_str=V2ViR0wgMS4wIChPcGVuR0wgRVMgMi4wIENocm9taXVtKQ&dm_cover_img_str=VjNEIDQuMkJyb2FkY2".base64Encoded()) { signed in + if let signed { + debugPrint(signed) + DarockKit.Network.shared.requestJSON("https://api.bilibili.com/x/space/wbi/arc/search?\(signed)", headers: headers) { respJson, isSuccess in + if isSuccess { + debugPrint(respJson) + if !CheckBApiError(from: respJson) { return } + let vlist = respJson["data"]["list"]["vlist"] + for video in vlist { + videos.append(["Title": video.1["title"].string ?? "[加载失败]", "Length": video.1["length"].string ?? "E", "PlayCount": String(video.1["play"].int ?? -1), "PicUrl": video.1["pic"].string ?? "E", "BV": video.1["bvid"].string ?? "E", "Timestamp": String(video.1["created"].int ?? 0), "DanmakuCount": String(video.1["video_review"].int ?? -1)]) + } + debugPrint(respJson["data"]["page"]["count"].int ?? 0) + videoTotalPage = Int((respJson["data"]["page"]["count"].int ?? 0) / 50) + 1 + videoCount = respJson["data"]["page"]["count"].int ?? 0 + if !isVideosLoaded { + if videos.count == 0 { + isNoVideo = true } + isVideosLoaded = true } } } } } - func RefreshArticles() { - articles = [[String: String]]() - let headers: HTTPHeaders = [ - "accept-language": "en,zh-CN;q=0.9,zh;q=0.8", - "cookie": "SESSDATA=\(sessdata);buvid3=\(globalBuvid3); buvid4=\(globalBuvid4);", - "User-Agent": "Mozilla/5.0" // Bypass? drdar://gh/SocialSisterYi/bilibili-API-collect/issues/868/1859065874 - ] - biliWbiSign(paramEncoded: "mid=\(uid)&ps=30&pn=\(articleNowPage)&sort=publish_time&platform=web".base64Encoded()) { signed in - if let signed { - debugPrint(signed) - DarockKit.Network.shared.requestJSON("https://api.bilibili.com/x/space/wbi/article?\(signed)", headers: headers) { respJson, isSuccess in - if isSuccess { - debugPrint(respJson) - if !CheckBApiError(from: respJson) { return } - let articlesJson = respJson["data"]["articles"] - for article in articlesJson { - articles.append(["Title": article.1["title"].string ?? "[加载失败]", "Summary": article.1["summary"].string ?? "[加载失败]", "Type": article.1["categories"][0]["name"].string ?? "[加载失败]", "View": String(article.1["stats"]["view"].int ?? -1), "Like": String(article.1["stats"]["like"].int ?? -1), "Pic": article.1["image_urls"][0].string ?? "E", "CV": String(article.1["id"].int ?? 0)]) - } - articleTotalPage = Int((respJson["data"]["count"].int ?? 0) / 30) + 1 - articalCount = respJson["data"]["count"].int ?? 0 - if !isArticlesLoaded { - if articles.count == 0 { - isNoArticle = true - } - isArticlesLoaded = true + } + func RefreshArticles() { + articles = [[String: String]]() + let headers: HTTPHeaders = [ + "accept-language": "en,zh-CN;q=0.9,zh;q=0.8", + "cookie": "SESSDATA=\(sessdata);buvid3=\(globalBuvid3); buvid4=\(globalBuvid4);", + "User-Agent": "Mozilla/5.0" // Bypass? rdar://gh/SocialSisterYi/bilibili-API-collect/issues/868#1859065874 + ] + biliWbiSign(paramEncoded: "mid=\(uid)&ps=30&pn=\(articleNowPage)&sort=publish_time&platform=web".base64Encoded()) { signed in + if let signed { + debugPrint(signed) + DarockKit.Network.shared.requestJSON("https://api.bilibili.com/x/space/wbi/article?\(signed)", headers: headers) { respJson, isSuccess in + if isSuccess { + debugPrint(respJson) + if !CheckBApiError(from: respJson) { return } + let articlesJson = respJson["data"]["articles"] + for article in articlesJson { + articles.append(["Title": article.1["title"].string ?? "[加载失败]", "Summary": article.1["summary"].string ?? "[加载失败]", "Type": article.1["categories"][0]["name"].string ?? "[加载失败]", "View": String(article.1["stats"]["view"].int ?? -1), "Like": String(article.1["stats"]["like"].int ?? -1), "Pic": article.1["image_urls"][0].string ?? "E", "CV": String(article.1["id"].int ?? 0)]) + } + articleTotalPage = Int((respJson["data"]["count"].int ?? 0) / 30) + 1 + articalCount = respJson["data"]["count"].int ?? 0 + if !isArticlesLoaded { + if articles.count == 0 { + isNoArticle = true } + isArticlesLoaded = true } } } } } } + } #endif } diff --git a/MeowBili/Video/VideoDetailView.swift b/MeowBili/Video/VideoDetailView.swift index 86313a898..6f8748af5 100644 --- a/MeowBili/Video/VideoDetailView.swift +++ b/MeowBili/Video/VideoDetailView.swift @@ -66,8 +66,6 @@ struct VideoDetailView: View { @State var nowPlayingCount = "0" @State var publishTime = "" @State var videoDesc = "" - @State var isMoreMenuPresented = false - @State var isDownloadPresented = false @State var isAudioPlayerPresented = false @State var backgroundPicOpacity = 0.0 @State var mainVerticalTabViewSelection = 1 @@ -83,6 +81,8 @@ struct VideoDetailView: View { @State var videoCID: Int64 = 0 @State var isDescSelectPresented = false #if !os(watchOS) + @State var isMoreMenuPresented = false + @State var isDownloadPresented = false @State var shouldPausePlayer = false @State var danmakuSendCache = "" @State var danmakuSendColor = Color(hex: 0xFFFFFF) @@ -523,24 +523,20 @@ struct VideoDetailView: View { .offset(y: 16) .toolbar { ToolbarItem(placement: .topBarTrailing) { - Button(action: { - isMoreMenuPresented = true - }, label: { - Image(systemName: "ellipsis") - }) - .sheet(isPresented: $isMoreMenuPresented, content: { + NavigationLink(destination: { List { - Button(action: { - if videoPages.count <= 1 { - isDownloadPresented = true - } else { + if videoPages.count <= 1 { + NavigationLink(destination: { VideoDownloadView(bvid: videoDetails["BV"]!, videoDetails: videoDetails) }, label: { + Label("Video.download", systemImage: "arrow.down.doc") + }) + } else { + Button(action: { videoPartShouldShowDownloadTip = true mainVerticalTabViewSelection = 3 - isMoreMenuPresented = false - } - }, label: { - Label("Video.download", systemImage: "arrow.down.doc") - }) + }, label: { + Label("Video.download", systemImage: "arrow.down.doc") + }) + } Button(action: { let headers: HTTPHeaders = [ "cookie": "SESSDATA=\(sessdata)", @@ -566,6 +562,8 @@ struct VideoDetailView: View { Label("Video.watch-later", systemImage: "memories.badge.plus") }) } + }, label: { + Image(systemName: "ellipsis") }) } ToolbarItemGroup(placement: .bottomBar) { @@ -611,7 +609,6 @@ struct VideoDetailView: View { .bold() } } - .sheet(isPresented: $isDownloadPresented, content: { VideoDownloadView(bvid: videoDetails["BV"]!, videoDetails: videoDetails) }) .sheet(isPresented: $isVideoPlayerPresented, content: { VideoPlayerView(videoDetails: $videoDetails, videoLink: $videoLink, videoBvid: $videoBvid, videoCID: $videoCID) .navigationBarHidden(true)