diff --git a/DarockBili.xcodeproj/project.pbxproj b/DarockBili.xcodeproj/project.pbxproj
index 7b1c73936..8e7cca04f 100644
--- a/DarockBili.xcodeproj/project.pbxproj
+++ b/DarockBili.xcodeproj/project.pbxproj
@@ -1371,7 +1371,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = MeowBili/MeowBili.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 489;
+ CURRENT_PROJECT_VERSION = 500;
DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\"";
DEVELOPMENT_TEAM = B57D8PP775;
ENABLE_PREVIEWS = YES;
@@ -1416,7 +1416,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = MeowBili/MeowBili.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 489;
+ CURRENT_PROJECT_VERSION = 500;
DEVELOPMENT_ASSET_PATHS = "\"MeowBili/Preview Content\"";
DEVELOPMENT_TEAM = B57D8PP775;
ENABLE_PREVIEWS = YES;
@@ -1458,7 +1458,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 489;
+ CURRENT_PROJECT_VERSION = 500;
DEVELOPMENT_ASSET_PATHS = "\"DarockBili Watch App/Preview Content\"";
DEVELOPMENT_TEAM = B57D8PP775;
ENABLE_PREVIEWS = YES;
@@ -1490,7 +1490,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 489;
+ CURRENT_PROJECT_VERSION = 500;
DEVELOPMENT_ASSET_PATHS = "\"DarockBili Watch App/Preview Content\"";
DEVELOPMENT_TEAM = B57D8PP775;
ENABLE_PREVIEWS = YES;
@@ -1643,7 +1643,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 489;
+ CURRENT_PROJECT_VERSION = 500;
DEVELOPMENT_ASSET_PATHS = "\"DarockBili Watch App/Preview Content\"";
DEVELOPMENT_TEAM = B57D8PP775;
ENABLE_PREVIEWS = YES;
@@ -1675,7 +1675,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 489;
+ CURRENT_PROJECT_VERSION = 500;
DEVELOPMENT_ASSET_PATHS = "\"DarockBili Watch App/Preview Content\"";
DEVELOPMENT_TEAM = B57D8PP775;
ENABLE_PREVIEWS = YES;
@@ -1707,7 +1707,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 489;
+ CURRENT_PROJECT_VERSION = 500;
DEVELOPMENT_TEAM = B57D8PP775;
INFOPLIST_KEY_CFBundleDisplayName = DarockBili;
MARKETING_VERSION = 1.0.0;
@@ -1723,7 +1723,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 489;
+ CURRENT_PROJECT_VERSION = 500;
DEVELOPMENT_TEAM = B57D8PP775;
INFOPLIST_KEY_CFBundleDisplayName = DarockBili;
MARKETING_VERSION = 1.0.0;
diff --git a/Localizable.xcstrings b/Localizable.xcstrings
index 368bd7d66..14f62361a 100644
--- a/Localizable.xcstrings
+++ b/Localizable.xcstrings
@@ -4857,6 +4857,9 @@
},
"第二步: 人机验证" : {
+ },
+ "经验" : {
+
},
"获取验证码" : {
diff --git a/MeowBili/Extension/UIExt.swift b/MeowBili/Extension/UIExt.swift
index cbd8552e3..d54dc27cc 100644
--- a/MeowBili/Extension/UIExt.swift
+++ b/MeowBili/Extension/UIExt.swift
@@ -17,6 +17,7 @@
//===----------------------------------------------------------------------===//
import UIKit
+import WebKit
import SwiftUI
import Foundation
import SDWebImageSwiftUI
@@ -146,6 +147,43 @@ import AuthenticationServices
.buttonBorderShape(.roundedRectangle(radius: 14))
}
+@ViewBuilder func ArticleCard(_ article: [String: String]) -> some View {
+ NavigationLink(destination: {ArticleView(cvid: article["CV"]!)}, label: {
+ VStack {
+ HStack {
+ Text(article["Title"]!)
+ .font(.system(size: 16, weight: .bold))
+ .lineLimit(3)
+ Spacer()
+ }
+ HStack {
+ VStack {
+ Text(article["Summary"]!)
+ .font(.system(size: 14, weight: .bold))
+ .lineLimit(3)
+ .foregroundColor(.gray)
+ HStack {
+ Text(article["Type"]!)
+ .font(.system(size: 12))
+ .lineLimit(1)
+ .foregroundColor(.gray)
+ Label(article["View"]!, systemImage: "eye.fill")
+ .font(.system(size: 12))
+ .lineLimit(1)
+ .foregroundColor(.gray)
+ Label(article["Like"]!, systemImage: "hand.thumbsup.fill")
+ .font(.system(size: 12))
+ .lineLimit(1)
+ .foregroundColor(.gray)
+ }
+ }
+ WebImage(url: URL(string: article["Pic"]! + "@100w"), options: [.progressiveLoad])
+ .cornerRadius(4)
+ }
+ }
+ })
+}
+
//struct zoomable: ViewModifier {
// @AppStorage("MaxmiumScale") var maxmiumScale = 6.0
// @State var scale: CGFloat = 1.0
@@ -211,3 +249,14 @@ struct UIImageTransfer: Transferable {
}
}
+struct WebView: UIViewRepresentable {
+ let url: URL
+
+ func makeUIView(context: Context) -> WKWebView {
+ let webView = WKWebView()
+ webView.load(URLRequest(url: url))
+ return webView
+ }
+
+ func updateUIView(_ uiView: WKWebView, context: Context) {}
+}
diff --git a/MeowBili/InMain/MainView.swift b/MeowBili/InMain/MainView.swift
index bd526a41b..ac1730e09 100644
--- a/MeowBili/InMain/MainView.swift
+++ b/MeowBili/InMain/MainView.swift
@@ -53,10 +53,23 @@ struct MainView: View {
Button(action: {
mainTabSelection = 2
}, label: {
- CachedAsyncImage(url: URL(string: userFaceUrl + "@35w"))
- .frame(width: 35)
- .clipShape(Circle())
- .matchedGeometryEffect(id: "image", in: imageAnimation)
+ CachedAsyncImage(url: URL(string: userFaceUrl)) { phase in
+ switch phase {
+ case .empty:
+ Circle()
+ .frame(width: 35, height: 35)
+ .redacted(reason: .placeholder)
+ case .success(let image):
+ image.resizable()
+ case .failure(let error):
+ Circle()
+ .frame(width: 35, height: 35)
+ .redacted(reason: .placeholder)
+ }
+ }
+ .frame(width: 35, height: 35)
+ .clipShape(Circle())
+ .matchedGeometryEffect(id: "image", in: imageAnimation)
})
.buttonStyle(.borderless)
}
diff --git a/MeowBili/Info.plist b/MeowBili/Info.plist
index f6cbb89fa..46c43120b 100644
--- a/MeowBili/Info.plist
+++ b/MeowBili/Info.plist
@@ -31,6 +31,7 @@
UIBackgroundModes
audio
+ fetch
diff --git a/MeowBili/PersonalCenter/ArticleView.swift b/MeowBili/PersonalCenter/ArticleView.swift
index bb30dcf8d..05358109c 100644
--- a/MeowBili/PersonalCenter/ArticleView.swift
+++ b/MeowBili/PersonalCenter/ArticleView.swift
@@ -16,6 +16,7 @@
//
//===----------------------------------------------------------------------===//
+import WebKit
import SwiftUI
import DarockKit
import SwiftSoup
@@ -23,17 +24,7 @@ import SwiftSoup
struct ArticleView: View {
var cvid: String
var body: some View {
- ScrollView {
-
- }
- .onAppear {
- DarockKit.Network.shared.requestString("https://www.bilibili.com/read/cv\(cvid)") { respStr, isSuccess in
- if isSuccess {
- let doc: Document = try! SwiftSoup.parse(respStr)
- debugPrint(try! doc.text())
- }
- }
- }
+ WebView(url: URL(string: "https://www.bilibili.com/read/cv\(cvid)")!)
}
}
diff --git a/MeowBili/PersonalCenter/PersonAccountView.swift b/MeowBili/PersonalCenter/PersonAccountView.swift
index 37608f548..d438f058f 100644
--- a/MeowBili/PersonalCenter/PersonAccountView.swift
+++ b/MeowBili/PersonalCenter/PersonAccountView.swift
@@ -192,10 +192,23 @@ struct PersonAccountView: View {
NavigationLink(destination: {UserDetailView(uid: dedeUserID)}, label: {
HStack {
if userFaceUrl != "" {
- CachedAsyncImage(url: URL(string: userFaceUrl + "@60w"))
- .frame(width: 60)
- .clipShape(Circle())
- .matchedGeometryEffect(id: "image", in: imageAnimation)
+ CachedAsyncImage(url: URL(string: userFaceUrl)) { phase in
+ switch phase {
+ case .empty:
+ Circle()
+ .frame(width: 60, height: 60)
+ .redacted(reason: .placeholder)
+ case .success(let image):
+ image.resizable()
+ case .failure(let error):
+ Circle()
+ .frame(width: 60, height: 60)
+ .redacted(reason: .placeholder)
+ }
+ }
+ .frame(width: 60, height: 60)
+ .clipShape(Circle())
+ .matchedGeometryEffect(id: "image", in: imageAnimation)
} else {
Image("Placeholder")
.resizable()
diff --git a/MeowBili/PersonalCenter/UserDetailView.swift b/MeowBili/PersonalCenter/UserDetailView.swift
index 117083d3f..3b4aa33db 100644
--- a/MeowBili/PersonalCenter/UserDetailView.swift
+++ b/MeowBili/PersonalCenter/UserDetailView.swift
@@ -47,14 +47,179 @@ struct UserDetailView: View {
@State var coinCount = -1
@State var isFollowed = false
@State var isInfoSheetPresented = false
+ @State var currentExp = 0
+ @State var nextExp = 0
+ @State var minExp = 0
+ let levelColors = [Color(red: 192/255, green: 192/255, blue: 192/255), //0
+ Color(red: 192/255, green: 192/255, blue: 192/255), //1
+ Color(red: 155/255, green: 208/255, blue: 160/255), //2
+ Color(red: 142/255, green: 203/255, blue: 235/255), //3
+ Color(red: 244/255, green: 190/255, blue: 146/255), //4
+ Color(red: 222/255, green: 111/255, blue: 60/255), //5
+ Color(red: 234/255, green: 51/255, blue: 35/255)] //6
var body: some View {
Group {
TabView {
ScrollView {
- FirstPageBase(uid: uid, userFaceUrl: $userFaceUrl, username: $username, followCount: $followCount, fansCount: $fansCount, coinCount: $coinCount, isFollowed: $isFollowed)
- .offset(y: -10)
- .navigationTitle(username)
- SecondPageBase(uid: uid, officialType: $officialType, officialTitle: $officialTitle, userSign: $userSign, userLevel: $userLevel, vipLabel: $vipLabel)
+ VStack {
+ Spacer()
+ .frame(height: 20)
+ HStack {
+ Spacer()
+ CachedAsyncImage(url: URL(string: userFaceUrl)) { phase in
+ if let image = phase.image {
+ image
+ .resizable()
+ } else {
+ Circle()
+ .redacted(reason: .placeholder)
+ }
+ }
+ .clipShape(Circle())
+ .frame(width: 150, height: 150)
+ Spacer()
+ }
+ HStack {
+ Spacer()
+ VStack {
+ if followCount != -1 {
+ Text(String(followCount))
+ .font(.system(size: 18))
+ } else {
+ Text("114")
+ .font(.system(size: 18))
+ .redacted(reason: .placeholder)
+ }
+ Text("Account.subscribed")
+ .font(.system(size: 16))
+ .opacity(0.6)
+ .lineLimit(1)
+ }
+ Spacer()
+ VStack {
+ if fansCount != -1 {
+ Text(String(fansCount).shorter())
+ .font(.system(size: 18))
+ } else {
+ Text("114")
+ .font(.system(size: 18))
+ .redacted(reason: .placeholder)
+ }
+ Text("Account.followers")
+ .font(.system(size: 16))
+ .opacity(0.6)
+ .lineLimit(1)
+ }
+ Spacer()
+ }
+ if dedeUserID == uid {
+ HStack {
+ Text("")
+ .font(.custom("bilibili", size: 20))
+ .opacity(0.55)
+ .offset(y: 1)
+ Text(String(coinCount))
+ .font(.system(size: 20))
+ }
+ }
+ HStack {
+ if dedeUserID != uid {
+ Button(action: {
+ 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/relation/modify", method: .post, parameters: ModifyUserRelation(fid: Int64(uid)!, act: isFollowed ? 2 : 1, csrf: biliJct), headers: headers).response { response in
+ debugPrint(response)
+ let json = try! JSON(data: response.data!)
+ let code = json["code"].int!
+ if code == 0 {
+ AlertKitAPI.present(title: isFollowed ? String(localized: "Account.tips.unfollowed") : String(localized: "Account.tips.followed"), icon: .done, style: .iOS17AppleMusic, haptic: .success)
+ isFollowed.toggle()
+ } else {
+ AlertKitAPI.present(title: json["message"].string!, icon: .error, style: .iOS17AppleMusic, haptic: .error)
+ }
+ }
+ }, label: {
+ HStack {
+ Image(systemName: isFollowed ? "person.badge.minus" : "person.badge.plus")
+ Text(isFollowed ? String(localized: "Account.unfollow") : String(localized: "Account.follow"))
+ }
+ })
+ .buttonStyle(.borderedProminent)
+ }
+ NavigationLink(destination: {bMessageSendView(uid: Int64(uid)!, username: username)}, label: {
+ HStack {
+ Image(systemName: "ellipsis.bubble")
+ Text("Account.direct-message")
+ }
+ })
+ .buttonStyle(.borderedProminent)
+ }
+ if uid == dedeUserID {
+ if userLevel > 0 {
+ Gauge(value: Double(currentExp), in: Double(minExp)...Double(nextExp), label: {
+ Text("经验")
+ }, currentValueLabel: {
+ Text(String(currentExp))
+ }, minimumValueLabel: {
+ Text(String(minExp))
+ }, maximumValueLabel: {
+ Text(String(nextExp))
+ })
+ .gaugeStyle(.accessoryLinear)
+ .tint(Gradient(colors: [levelColors[userLevel - 1], levelColors[userLevel]]))
+ }
+ }
+ 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")
+ .foregroundColor(officialType == 0 ? Color(hex: 0xFDD663) : Color(hex: 0xA0C0F4))
+ .frame(width: 20, height: 20)
+ Text("\(Text(String(localized: "Account.certification")).bold())\n\(officialTitle)")
+ .font(.system(size: 15))
+ Spacer()
+ }
+ }
+ if !vipLabel.isEmpty {
+ HStack {
+ WebImage(url: URL(string: "https://s1.hdslb.com/bfs/seed/jinkela/short/user-avatar/big-vip.svg"))
+ .resizable()
+ .frame(width: 20, height: 20)
+ Text(vipLabel)
+ .font(.system(size: 15))
+ .bold()
+ Spacer()
+ }
+ }
+ HStack {
+ Image(systemName: "graduationcap.circle")
+ .foregroundColor(levelColors[userLevel])
+ .frame(width: 20, height: 20)
+ Text("Lv\(userLevel)")
+ .font(.system(size: 15))
+ .bold()
+ Spacer()
+ }
+ HStack {
+ Image(systemName: "info.circle")
+ .foregroundColor(.secondary)
+ .frame(width: 20, height: 20)
+ Text(userSign)
+ .font(.system(size: 14))
+ .foregroundColor(.secondary)
+ Spacer()
+ }
+ }
+ .padding()
}
.tag(1)
.tabItem {
@@ -78,14 +243,8 @@ struct UserDetailView: View {
debugPrint(signed)
autoRetryRequestApi("https://api.bilibili.com/x/space/wbi/acc/info?\(signed)", headers: headers) { respJson, isSuccess in
if isSuccess {
- //debugPrint(respJson)
if !CheckBApiError(from: respJson) { return }
userFaceUrl = respJson["data"]["face"].string ?? "E"
-// AF.request(respJson["data"]["face"].string ?? "E").response { response in
-// let data = response.data!
-// let mColor = ColorThief.getColor(from: UIImage(data: data)!)!.makeUIColor()
-// debugPrint(mColor)
-// }
username = respJson["data"]["name"].string ?? "[加载失败]"
userLevel = respJson["data"]["level"].int ?? 0
officialType = respJson["data"]["official"]["type"].int ?? -1
@@ -111,192 +270,19 @@ struct UserDetailView: View {
}
}
}
- }
- }
-
- struct FirstPageBase: View {
- var uid: String
- @Binding var userFaceUrl: String
- @Binding var username: String
- @Binding var followCount: Int
- @Binding var fansCount: Int
- @Binding var coinCount: Int
- @Binding var isFollowed: Bool
- @AppStorage("DedeUserID") var dedeUserID = ""
- @AppStorage("DedeUserID__ckMd5") var dedeUserID__ckMd5 = ""
- @AppStorage("SESSDATA") var sessdata = ""
- @AppStorage("bili_jct") var biliJct = ""
- var body: some View {
- VStack {
- Spacer()
- .frame(height: 20)
- HStack {
- Spacer()
- CachedAsyncImage(url: URL(string: userFaceUrl)) { phase in
- if let image = phase.image {
- image
- .resizable()
- } else {
- Circle()
- .redacted(reason: .placeholder)
- }
- }
- .clipShape(Circle())
- .frame(width: 150, height: 150)
- Spacer()
- }
- HStack {
- Spacer()
- VStack {
- if followCount != -1 {
- Text(String(followCount))
- .font(.system(size: 18))
- } else {
- Text("114")
- .font(.system(size: 18))
- .redacted(reason: .placeholder)
- }
- Text("Account.subscribed")
- .font(.system(size: 16))
- .opacity(0.6)
- .lineLimit(1)
- }
- Spacer()
- VStack {
- if fansCount != -1 {
- Text(String(fansCount).shorter())
- .font(.system(size: 18))
- } else {
- Text("114")
- .font(.system(size: 18))
- .redacted(reason: .placeholder)
- }
- Text("Account.followers")
- .font(.system(size: 16))
- .opacity(0.6)
- .lineLimit(1)
- }
- Spacer()
- }
- if dedeUserID == uid {
- HStack {
- Text("")
- .font(.custom("bilibili", size: 20))
- .opacity(0.55)
- .offset(y: 1)
- Text(String(coinCount))
- .font(.system(size: 20))
- }
- }
- HStack {
- if dedeUserID != uid {
- Button(action: {
- 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/relation/modify", method: .post, parameters: ModifyUserRelation(fid: Int64(uid)!, act: isFollowed ? 2 : 1, csrf: biliJct), headers: headers).response { response in
- debugPrint(response)
- let json = try! JSON(data: response.data!)
- let code = json["code"].int!
- if code == 0 {
- AlertKitAPI.present(title: isFollowed ? String(localized: "Account.tips.unfollowed") : String(localized: "Account.tips.followed"), icon: .done, style: .iOS17AppleMusic, haptic: .success)
- isFollowed.toggle()
- } else {
- AlertKitAPI.present(title: json["message"].string!, icon: .error, style: .iOS17AppleMusic, haptic: .error)
- }
- }
- }, label: {
- HStack {
- Image(systemName: isFollowed ? "person.badge.minus" : "person.badge.plus")
- Text(isFollowed ? String(localized: "Account.unfollow") : String(localized: "Account.follow"))
- }
- })
- .buttonStyle(.borderedProminent)
- }
- NavigationLink(destination: {bMessageSendView(uid: Int64(uid)!, username: username)}, label: {
- HStack {
- Image(systemName: "ellipsis.bubble")
- Text("Account.direct-message")
- }
- })
- .buttonStyle(.borderedProminent)
- }
- .padding()
- }
- }
- }
- struct SecondPageBase: View {
- var uid: String
- @Binding var officialType: Int
- @Binding var officialTitle: String
- @Binding var userSign: String
- @Binding var userLevel: Int
- @Binding var vipLabel: String
- let levelColors = [Color(red: 192/255, green: 192/255, blue: 192/255), //0
- Color(red: 192/255, green: 192/255, blue: 192/255), //1
- Color(red: 155/255, green: 208/255, blue: 160/255), //2
- Color(red: 142/255, green: 203/255, blue: 235/255), //3
- Color(red: 244/255, green: 190/255, blue: 146/255), //4
- Color(red: 222/255, green: 111/255, blue: 60/255), //5
- 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")
- .foregroundColor(officialType == 0 ? Color(hex: 0xFDD663) : Color(hex: 0xA0C0F4))
- .frame(width: 20, height: 20)
- Text("\(Text(String(localized: "Account.certification")).bold())\n\(officialTitle)")
- .font(.system(size: 15))
- Spacer()
- }
- }
- if !vipLabel.isEmpty {
- HStack {
- WebImage(url: URL(string: "https://s1.hdslb.com/bfs/seed/jinkela/short/user-avatar/big-vip.svg"))
- .resizable()
- .frame(width: 20, height: 20)
- Text(vipLabel)
- .font(.system(size: 15))
- .bold()
- Spacer()
- }
- }
- HStack {
- Image(systemName: "graduationcap.circle")
- .foregroundColor(levelColors[userLevel])
- .frame(width: 20, height: 20)
- Text("Lv\(userLevel)")
- .font(.system(size: 15))
- .bold()
- Spacer()
- }
- HStack {
- VStack {
- Image(systemName: "info.circle")
- .foregroundColor(.secondary)
- .frame(width: 20, height: 20)
- Spacer()
+ if uid == dedeUserID {
+ DarockKit.Network.shared.requestJSON("https://api.bilibili.com/x/web-interface/nav", headers: headers) { respJson, isSuccess in
+ if isSuccess {
+ if !CheckBApiError(from: respJson) { return }
+ currentExp = respJson["data"]["level_info"]["current_exp"].int ?? 0
+ nextExp = respJson["data"]["level_info"]["next_exp"].int ?? 0
+ minExp = respJson["data"]["level_info"]["current_min"].int ?? 0
}
- Text(userSign)
- .font(.system(size: 14))
- .foregroundColor(.secondary)
-// .opacity(0.6)
- Spacer()
}
}
- .padding()
}
}
+
struct VideosListBase: View {
var uid: String
@Binding var username: String
@@ -414,44 +400,7 @@ struct UserDetailView: View {
if articles.count != 0 {
Section {
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))
+ ArticleCard(articles[i])
}
}
Section {