diff --git a/V2er/General/Extentions.swift b/V2er/General/Extentions.swift index 7ed5d4d..feaae38 100644 --- a/V2er/General/Extentions.swift +++ b/V2er/General/Extentions.swift @@ -8,6 +8,7 @@ import Foundation import SwiftUI +import SafariServices extension String { static let `default`: String = "" @@ -271,3 +272,16 @@ extension URL { } } } + + +// MARK: - Safari View +struct SafariView: UIViewControllerRepresentable { + let url: URL + + func makeUIViewController(context: UIViewControllerRepresentableContext) -> SFSafariViewController { + return SFSafariViewController(url: url) + } + + func updateUIViewController(_ uiViewController: SFSafariViewController, context: UIViewControllerRepresentableContext) { + } +} diff --git a/V2er/View/FeedDetail/FeedDetailPage.swift b/V2er/View/FeedDetail/FeedDetailPage.swift index a378bb1..1d78933 100644 --- a/V2er/View/FeedDetail/FeedDetailPage.swift +++ b/V2er/View/FeedDetail/FeedDetailPage.swift @@ -7,12 +7,15 @@ // import SwiftUI +import SafariServices struct FeedDetailPage: StateView, KeyboardReadable, InstanceIdentifiable { @Environment(\.isPresented) private var isPresented @Environment(\.dismiss) var dismiss @EnvironmentObject private var store: Store @State var rendered: Bool = false + @State private var showingSafari = false + @State private var safariURL: URL? var bindingState: Binding { if store.appState.feedDetailStates[instanceId] == nil { @@ -57,6 +60,11 @@ struct FeedDetailPage: StateView, KeyboardReadable, InstanceIdentifiable { var body: some View { contentView .navigatable() + .sheet(isPresented: $showingSafari) { + if let url = safariURL { + SafariView(url: url) + } + } } @ViewBuilder @@ -134,7 +142,7 @@ struct FeedDetailPage: StateView, KeyboardReadable, InstanceIdentifiable { } label: { Image(systemName: "arrow.up.circle.fill") .font(.title.weight(.regular)) - .foregroundColor(Color.bodyText.opacity(hasReplyContent ? 1.0 : 0.6)) + .foregroundColor(Color.tintColor.opacity(hasReplyContent ? 1.0 : 0.6)) .padding(.trailing, 6) .padding(.vertical, 3) } @@ -231,6 +239,17 @@ struct FeedDetailPage: StateView, KeyboardReadable, InstanceIdentifiable { Label(reported ? "已举报" : "举报", systemImage: "person.crop.circle.badge.exclamationmark") } .disabled(reported) + + Divider() + + Button { + if let url = URL(string: APIService.baseUrlString + "/t/\(id)") { + safariURL = url + showingSafari = true + } + } label: { + Label("使用浏览器打开", systemImage: "safari") + } } label: { Image(systemName: "ellipsis") .padding(8) diff --git a/V2er/View/FeedDetail/ReplyItemView.swift b/V2er/View/FeedDetail/ReplyItemView.swift index 1736dc1..83dc911 100644 --- a/V2er/View/FeedDetail/ReplyItemView.swift +++ b/V2er/View/FeedDetail/ReplyItemView.swift @@ -30,8 +30,10 @@ struct ReplyItemView: View { HStack { VStack (alignment: .leading, spacing: 4) { Text(info.userName) + .foregroundColor(.primaryText) Text(info.time) .font(.caption2) + .foregroundColor(.secondaryText) } Spacer() // Image(systemName: "heart") diff --git a/V2er/View/Me/UserDetailPage.swift b/V2er/View/Me/UserDetailPage.swift index 536df15..bc7f1e5 100644 --- a/V2er/View/Me/UserDetailPage.swift +++ b/V2er/View/Me/UserDetailPage.swift @@ -248,12 +248,13 @@ struct UserDetailPage: StateView { struct ReplyItemView: View { var data: UserDetailInfo.ReplyInfo.Item let quoteFont = Style.font(UIFont.prfered(.footnote)) - .foregroundColor(Color.bodyText.uiColor) + .foregroundColor(Color.primaryText.uiColor) var body: some View { VStack(spacing: 0) { Text(data.title) .font(.footnote) + .foregroundColor(.primaryText) .greedyWidth(.leading) RichText { data.content @@ -272,6 +273,7 @@ struct UserDetailPage: StateView { .padding(.vertical, 6) Text(data.time) .font(.footnote) + .foregroundColor(.secondaryText) .greedyWidth(.trailing) } .padding(12) diff --git a/V2er/View/Me/UserFeedPage.swift b/V2er/View/Me/UserFeedPage.swift index cf57669..82ea3fd 100644 --- a/V2er/View/Me/UserFeedPage.swift +++ b/V2er/View/Me/UserFeedPage.swift @@ -56,6 +56,7 @@ struct UserFeedPage: StateView, InstanceIdentifiable { HStack(alignment: .top) { VStack(alignment: .leading, spacing: 5) { Text(data.userName) + .foregroundColor(.primaryText) .lineLimit(1) Text(data.replyUpdate) .lineLimit(1) @@ -67,7 +68,7 @@ struct UserFeedPage: StateView, InstanceIdentifiable { NavigationLink(destination: TagDetailPage()) { Text(data.tag) .font(.footnote) - .foregroundColor(.black) + .foregroundColor(.primaryText) .lineLimit(1) .padding(.horizontal, 14) .padding(.vertical, 8) @@ -75,11 +76,13 @@ struct UserFeedPage: StateView, InstanceIdentifiable { } } Text(data.title) + .foregroundColor(.primaryText) .greedyWidth(.leading) .lineLimit(2) Text("评论\(data.replyNum)") .lineLimit(1) .font(.footnote) + .foregroundColor(.secondaryText) .greedyWidth(.trailing) } .padding(12) diff --git a/V2er/View/Settings/OtherSettingsView.swift b/V2er/View/Settings/OtherSettingsView.swift index 5acf73d..c2b560d 100644 --- a/V2er/View/Settings/OtherSettingsView.swift +++ b/V2er/View/Settings/OtherSettingsView.swift @@ -45,7 +45,7 @@ struct OtherSettingsView: View { .foregroundColor(Color.tintColor) Image(systemName: "chevron.right") .font(.body.weight(.regular)) - .foregroundColor(.gray) + .foregroundColor(.secondaryText) .padding(.trailing, 16) } } diff --git a/V2er/View/Settings/SettingsPage.swift b/V2er/View/Settings/SettingsPage.swift index 932f293..e4cec28 100644 --- a/V2er/View/Settings/SettingsPage.swift +++ b/V2er/View/Settings/SettingsPage.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SafariServices struct SettingsPage: View { @Environment(\.dismiss) var dismiss @@ -29,8 +30,12 @@ struct SettingsPage: View { SectionItemView("通用设置") .to { OtherSettingsView() } - SectionItemView("帮助与反馈") + SectionItemView("问题反馈") .padding(.top, 8) + .to { + SafariWebView(url: "https://github.com/v2er-app/iOS/issues") + } + SectionItemView("V2EX帮助") .to { WebBrowserView(url: "https://www.v2ex.com/help") } @@ -103,6 +108,25 @@ struct SettingsPage: View { } } +struct SafariWebView: View { + let url: String + @State private var showingSafari = false + + var body: some View { + Color.clear + .onAppear { + if let url = URL(string: url) { + showingSafari = true + } + } + .sheet(isPresented: $showingSafari) { + if let url = URL(string: url) { + SafariView(url: url) + } + } + } +} + struct SettingsPage_Previews: PreviewProvider { static var previews: some View { SettingsPage() diff --git a/V2er/View/Widget/MultilineTextField.swift b/V2er/View/Widget/MultilineTextField.swift index 0dc237a..2dd4251 100644 --- a/V2er/View/Widget/MultilineTextField.swift +++ b/V2er/View/Widget/MultilineTextField.swift @@ -26,7 +26,7 @@ fileprivate struct UITextViewWrapper: UIViewRepresentable { textField.isUserInteractionEnabled = true textField.isScrollEnabled = false textField.backgroundColor = UIColor.clear - textField.textColor = Color.bodyText.uiColor + textField.textColor = Color.primaryText.uiColor // textField.textContainer.maximumNumberOfLines = 5 @@ -42,6 +42,11 @@ fileprivate struct UITextViewWrapper: UIViewRepresentable { if uiView.text != self.text { uiView.text = self.text } + // Update text color to ensure it responds to theme changes + let desiredColor = Color.primaryText.uiColor + if uiView.textColor != desiredColor { + uiView.textColor = desiredColor + } if uiView.window != nil, !uiView.isFirstResponder { // uiView.becomeFirstResponder() } @@ -127,7 +132,7 @@ struct MultilineTextField: View { Group { if showingPlaceholder { Text(placeholder) - .foregroundColor(.gray) + .foregroundColor(.secondaryText) .padding(.leading, 4) } } diff --git a/V2er/View/Widget/RichText/RichText.swift b/V2er/View/Widget/RichText/RichText.swift index 86206f9..043aee5 100644 --- a/V2er/View/Widget/RichText/RichText.swift +++ b/V2er/View/Widget/RichText/RichText.swift @@ -38,7 +38,7 @@ struct RichText: View { struct Styles { public static let base = Style.font(UIFont.prfered(.body)) - .foregroundColor(Color.bodyText.uiColor) + .foregroundColor(Color.primaryText.uiColor) public static let link = Style("a") .font(.boldSystemFont(ofSize: 16)) .foregroundColor(Color.url.uiColor, .normal)