diff --git a/DarockBili.xcodeproj/project.pbxproj b/DarockBili.xcodeproj/project.pbxproj index 0774c6601..14e8dc69d 100644 --- a/DarockBili.xcodeproj/project.pbxproj +++ b/DarockBili.xcodeproj/project.pbxproj @@ -379,7 +379,6 @@ /* Begin PBXFileReference section */ 8C0557E02B7A0480009D9CD0 /* MeowBili.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MeowBili.entitlements; sourceTree = ""; }; - 8C617F5B2B924C5B000A3687 /* ci_post_clone.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ci_post_clone.sh; sourceTree = ""; }; 8C617F3E2B92334B000A3687 /* SafariExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SafariExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 8C617F402B92334B000A3687 /* SafariWebExtensionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariWebExtensionHandler.swift; sourceTree = ""; }; 8C617F432B92334B000A3687 /* _locales */ = {isa = PBXFileReference; lastKnownFileType = folder; path = _locales; sourceTree = ""; }; @@ -391,6 +390,7 @@ 8C617F4F2B92334B000A3687 /* popup.css */ = {isa = PBXFileReference; lastKnownFileType = text.css; path = popup.css; sourceTree = ""; }; 8C617F512B92334B000A3687 /* popup.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = popup.js; sourceTree = ""; }; 8C617F532B92334B000A3687 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8C617F5B2B924C5B000A3687 /* ci_post_clone.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ci_post_clone.sh; sourceTree = ""; }; 8C72E32A2B6605B80087486E /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 8CA370D92B82724400CE0E9E /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 8CA370E82B83BB4F00CE0E9E /* MeowBili Vision App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "MeowBili Vision App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1581,7 +1581,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 881; + CURRENT_PROJECT_VERSION = 885; DEVELOPMENT_TEAM = B57D8PP775; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = SafariExtension/Info.plist; @@ -1593,7 +1593,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 1.0.0; OTHER_LDFLAGS = ( "-framework", SafariServices, @@ -1612,7 +1612,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 881; + CURRENT_PROJECT_VERSION = 885; DEVELOPMENT_TEAM = B57D8PP775; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = SafariExtension/Info.plist; @@ -1624,7 +1624,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 1.0.0; OTHER_LDFLAGS = ( "-framework", SafariServices, @@ -1648,7 +1648,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CODE_SIGN_ENTITLEMENTS = "MeowBili/MeowBili Vision App.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 881; + CURRENT_PROJECT_VERSION = 885; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1683,7 +1683,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CODE_SIGN_ENTITLEMENTS = "MeowBili/MeowBili Vision App.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 881; + CURRENT_PROJECT_VERSION = 885; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1720,7 +1720,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = MeowBili/MeowBili.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 881; + CURRENT_PROJECT_VERSION = 885; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1767,7 +1767,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = MeowBili/MeowBili.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 881; + CURRENT_PROJECT_VERSION = 885; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1811,7 +1811,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIconWatch; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 881; + CURRENT_PROJECT_VERSION = 885; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview\\ Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1847,7 +1847,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIconWatch; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 881; + CURRENT_PROJECT_VERSION = 885; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview\\ Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_PREVIEWS = YES; @@ -1886,7 +1886,7 @@ CODE_SIGN_ENTITLEMENTS = "MeowBili/MeowBili Mac App.entitlements"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 881; + CURRENT_PROJECT_VERSION = 885; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_HARDENED_RUNTIME = YES; @@ -1919,7 +1919,7 @@ CODE_SIGN_ENTITLEMENTS = "MeowBili/MeowBili Mac App.entitlements"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 881; + CURRENT_PROJECT_VERSION = 885; DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\""; DEVELOPMENT_TEAM = B57D8PP775; ENABLE_HARDENED_RUNTIME = YES; @@ -1948,7 +1948,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 881; + CURRENT_PROJECT_VERSION = 885; DEVELOPMENT_TEAM = B57D8PP775; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 16.0; @@ -1971,7 +1971,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 881; + CURRENT_PROJECT_VERSION = 885; DEVELOPMENT_TEAM = B57D8PP775; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 16.0; diff --git a/Localizable.xcstrings b/Localizable.xcstrings index 43097d02a..de76fd004 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -375,6 +375,9 @@ } } } + }, + "%@粉丝" : { + }, "%lld" : { "extractionState" : "stale", diff --git a/MeowBili/Bangumi/BangumiDetailView.swift b/MeowBili/Bangumi/BangumiDetailView.swift index 1fec278d2..b96e88187 100644 --- a/MeowBili/Bangumi/BangumiDetailView.swift +++ b/MeowBili/Bangumi/BangumiDetailView.swift @@ -27,14 +27,13 @@ import SDWebImageSwiftUI #endif struct BangumiDetailView: View { - public static var willPlayBangumiLink = "" - public static var willPlayBangumiData: BangumiData? @State var bangumiData: BangumiData @AppStorage("DedeUserID") var dedeUserID = "" @AppStorage("DedeUserID__ckMd5") var dedeUserID__ckMd5 = "" @AppStorage("SESSDATA") var sessdata = "" @AppStorage("bili_jct") var biliJct = "" @AppStorage("RecordHistoryTime") var recordHistoryTime = "into" + @AppStorage("IsDanmakuEnabled") var isDanmakuEnabled = true @State var paymentData: BangumiPayment? @State var epDatas = [BangumiEp]() @State var isLoading = false @@ -43,15 +42,37 @@ struct BangumiDetailView: View { @State var isMoreMenuPresented = false @State var backgroundPicOpacity = 0.0 @State var navigationSelectedEpdata: BangumiEp? + @State var bangumiLink = "" + @State var isDecoded = false + @State var isShouldPause = false + @State var currentPlayTime = 0.0 var body: some View { TabView { ZStack { Group { + #if os(watchOS) ScrollView { DetailViewFirstPageBase(bangumiData: $bangumiData, isBangumiPlayerPresented: $isBangumiPlayerPresented, isLoading: $isLoading) DetailViewSecondPageBase(bangumiData: $bangumiData, paymentData: $paymentData) - EpisodeListView(bangumiData: $bangumiData, epDatas: $epDatas, isBangumiPlayerPresented: $isBangumiPlayerPresented, isLoading: $isLoading) + EpisodeListView(bangumiData: $bangumiData, epDatas: $epDatas, isBangumiPlayerPresented: $isBangumiPlayerPresented, isLoading: $isLoading, bangumiLink: $bangumiLink) } + #else + VStack { + if isDecoded { + BangumiPlayerView(bangumiData: $bangumiData, isDanmakuEnabled: $isDanmakuEnabled, bangumiLink: $bangumiLink, shouldPause: $isShouldPause, currentPlayTime: $currentPlayTime) + .frame(height: 240) + } else { + Rectangle() + .frame(height: 240) + .redacted(reason: .placeholder) + .accessibilityIdentifier("BangumiNotLoadPlaceholder") + } + ScrollView { + EpisodeListView(bangumiData: $bangumiData, epDatas: $epDatas, isBangumiPlayerPresented: $isBangumiPlayerPresented, isLoading: $isLoading, bangumiLink: $bangumiLink) + DetailViewSecondPageBase(bangumiData: $bangumiData, paymentData: $paymentData) + } + } + #endif } .blur(radius: isLoading ? 14 : 0) if isLoading { @@ -102,6 +123,15 @@ struct BangumiDetailView: View { for ep in respJson["result"]["main_section"]["episodes"] { epDatas.append(BangumiEp(aid: ep.1["aid"].int64 ?? 0, epid: ep.1["id"].int64 ?? 0, cid: ep.1["cid"].int64 ?? 0, cover: ep.1["cover"].string ?? "E", title: ep.1["title"].string ?? "[加载失败]", longTitle: ep.1["long_title"].string ?? "[加载失败]")) } + #if !os(watchOS) + DarockKit.Network.shared.requestJSON("https://api.bilibili.com/pgc/player/web/playurl?ep_id=\(epDatas[0].epid)&qn=16&fnval=1", headers: headers) { respJson, isSuccess in + if isSuccess { + if !CheckBApiError(from: respJson) { return } + bangumiLink = respJson["result"]["durl"][0]["url"].string!.replacingOccurrences(of: "\\u0026", with: "&") + isDecoded = true + } + } + #endif } } } @@ -116,7 +146,6 @@ struct BangumiDetailView: View { @AppStorage("SESSDATA") var sessdata = "" @AppStorage("bili_jct") var biliJct = "" @State var isCoverImageViewPresented = false - var body: some View { VStack { Spacer() @@ -229,20 +258,63 @@ struct BangumiDetailView: View { @Binding var epDatas: [BangumiEp] @Binding var isBangumiPlayerPresented: Bool @Binding var isLoading: Bool + @Binding var bangumiLink: String + @Environment(\.colorScheme) var colorScheme @AppStorage("DedeUserID") var dedeUserID = "" @AppStorage("DedeUserID__ckMd5") var dedeUserID__ckMd5 = "" @AppStorage("SESSDATA") var sessdata = "" @AppStorage("bili_jct") var biliJct = "" + @State var playingPageIndex = 0 var body: some View { + #if os(watchOS) if #available(watchOS 10, *) { List { - DetailCore(bangumiData: $bangumiData, epDatas: $epDatas, isBangumiPlayerPresented: $isBangumiPlayerPresented, isLoading: $isLoading) + DetailCore(bangumiData: $bangumiData, epDatas: $epDatas, isBangumiPlayerPresented: $isBangumiPlayerPresented, isLoading: $isLoading, bangumiLink: $bangumiLink) } } else { VStack { - DetailCore(bangumiData: $bangumiData, epDatas: $epDatas, isBangumiPlayerPresented: $isBangumiPlayerPresented, isLoading: $isLoading) + DetailCore(bangumiData: $bangumiData, epDatas: $epDatas, isBangumiPlayerPresented: $isBangumiPlayerPresented, isLoading: $isLoading, bangumiLink: $bangumiLink) + } + } + #else + if epDatas.count != 0 { + ScrollView(.horizontal) { + HStack { + ForEach(0.. 0 { - playerRotate -= 90 - } else { - playerRotate = 270 - } + isFullScreen.toggle() + tabviewChoseTab = 1 }, label: { - Image(systemName: "rotate.left") - }) - Button(action: { - if playerRotate + 90 < 360 { - playerRotate += 90 + if isFullScreen { + Label("恢复", systemImage: "arrow.down.forward.and.arrow.up.backward") } else { - playerRotate = 0 + Label("全屏", systemImage: "arrow.down.backward.and.arrow.up.forward") } - }, label: { - Image(systemName: "rotate.right") }) + } header: { + Text("画面") + } + Section { + Toggle(isOn: $isDanmakuEnabled) { Text("启用") } + } header: { + Text("弹幕") } } + .tag(2) } - .tag(2) + .tabViewStyle(.page) } - .tabViewStyle(.page) + .ignoresSafeArea() + #else + AZVideoPlayer(player: player, willBeginFullScreenPresentationWithAnimationCoordinator: willBeginFullScreen, willEndFullScreenPresentationWithAnimationCoordinator: willEndFullScreen) + #endif } - .ignoresSafeArea() .onAppear { - let asset = AVURLAsset(url: URL(string: BangumiDetailView.willPlayBangumiLink)!, options: ["AVURLAssetHTTPHeaderFieldsKey": ["User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15", "Referer": "https://www.bilibili.com"]]) + let asset = AVURLAsset(url: URL(string: bangumiLink)!, options: ["AVURLAssetHTTPHeaderFieldsKey": ["User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15", "Referer": "https://www.bilibili.com"]]) let item = AVPlayerItem(asset: asset) player = AVPlayer(playerItem: item) + player.play() + - debugPrint(URL(string: BangumiDetailView.willPlayBangumiLink)!) -// let headers: HTTPHeaders = [ -// "cookie": "SESSDATA=\(sessdata)" -// ] -// if recordHistoryTime == "play" { -// AF.request("https://api.bilibili.com/x/click-interface/web/heartbeat", method: .post, parameters: ["bvid": VideoDetailView.willPlayVideoBV, "mid": dedeUserID, "type": 3, "dt": 2, "play_type": 2, "csrf": biliJct], headers: headers).response { response in -// debugPrint(response) -// } -// } } .onDisappear { playerTimer?.invalidate() } + .onChange(of: bangumiLink) { value in + let asset = AVURLAsset(url: URL(string: value)!, options: ["AVURLAssetHTTPHeaderFieldsKey": ["User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15", "Referer": "https://www.bilibili.com"]]) + let item = AVPlayerItem(asset: asset) + player?.pause() + player = nil + player = AVPlayer(playerItem: item) + player.play() + } + } + + #if !os(watchOS) + func willBeginFullScreen(_ playerViewController: AVPlayerViewController, _ coordinator: UIViewControllerTransitionCoordinator) { + willBeginFullScreenPresentation = true } + func willEndFullScreen(_ playerViewController: AVPlayerViewController, _ coordinator: UIViewControllerTransitionCoordinator) { + // This is a static helper method provided by AZVideoPlayer to keep + // the video playing if it was playing when full screen presentation ended + AZVideoPlayer.continuePlayingIfPlaying(player, coordinator) + } + #endif } -#Preview { - BangumiPlayerView() -} diff --git a/MeowBili/GlobalView/CommentsView.swift b/MeowBili/GlobalView/CommentsView.swift index 40c04d849..058b2dca8 100644 --- a/MeowBili/GlobalView/CommentsView.swift +++ b/MeowBili/GlobalView/CommentsView.swift @@ -229,7 +229,9 @@ struct CommentsView: View { Text("Home.more") .bold() }) + #if !os(watchOS) .buttonStyle(.borderedProminent) + #endif } } else { if isNoMore { @@ -239,7 +241,9 @@ struct CommentsView: View { } } } + #if !os(watchOS) .padding(.horizontal) + #endif .sheet(isPresented: $isCommentRepliesPresented, content: { CommentRepliesView(avid: id, type: type, goto: $presentRepliesGoto, rootData: $presentRepliesRootData) }) } .onAppear { diff --git a/MeowBili/UserDynamic/UserDynamicMainView.swift b/MeowBili/UserDynamic/UserDynamicMainView.swift index 2d65a61c3..6578acbc1 100644 --- a/MeowBili/UserDynamic/UserDynamicMainView.swift +++ b/MeowBili/UserDynamic/UserDynamicMainView.swift @@ -428,7 +428,9 @@ struct UserDynamicMainView: View { ProgressView() } } + #if !os(watchOS) .padding() + #endif } .navigationTitle("Moments") .navigationBarTitleDisplayMode(.large) diff --git a/MeowBili/Video/VideoDetailView.swift b/MeowBili/Video/VideoDetailView.swift index d5d08adac..69b660ab7 100644 --- a/MeowBili/Video/VideoDetailView.swift +++ b/MeowBili/Video/VideoDetailView.swift @@ -1335,7 +1335,7 @@ struct VideoDetailView: View { Spacer() } HStack { - Text("Video.fans.\(Int(String(ownerFansCount).shorter()) ?? 0)") + Text("\(String(ownerFansCount).shorter())粉丝") .font(.system(size: 11)) .lineLimit(1) .opacity(0.6) diff --git a/ci_scripts/ci_post_xcodebuild.sh b/ci_scripts/ci_post_xcodebuild.sh index 83fa36597..aa21ff58f 100755 --- a/ci_scripts/ci_post_xcodebuild.sh +++ b/ci_scripts/ci_post_xcodebuild.sh @@ -3,12 +3,12 @@ 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 + echo -e "CI 自动生成信息,24小时内的main分支的提交:\n" > $TESTFLIGHT_DIR_PATH/WhatToTest.zh-Hans.txt git fetch -a --deepen 40 && git log --since="24 hours ago" main --pretty=format:"%s" >> $TESTFLIGHT_DIR_PATH/WhatToTest.zh-Hans.txt elif [[ "$CI_WORKFLOW" == "Public Release" ]]; then TESTFLIGHT_DIR_PATH=../TestFlight mkdir $TESTFLIGHT_DIR_PATH - echo "当前语义化版本:$CI_TAG\n\nRelease Notes: https://github.com/Darock-Studio/Darock-Bili/releases/tag/$CI_TAG\n\n若要使用watchOS App,请打开“在Apple Watch上显示App”开关" > $TESTFLIGHT_DIR_PATH/WhatToTest.zh-Hans.txt + echo -e "当前语义化版本:$CI_TAG\n\nRelease Notes: https://github.com/Darock-Studio/Darock-Bili/releases/tag/$CI_TAG\n\n若要使用watchOS App,请打开“在Apple Watch上显示App”开关" > $TESTFLIGHT_DIR_PATH/WhatToTest.zh-Hans.txt fi if [[ -n $CI_PULL_REQUEST_NUMBER ]]; then