pushdeer/ios/PushDeer-iOS/PushDeer/View/SettingsView.swift
hext 69ec4f3774 mac版本支持右键删除消息
应用内打开网页使用 BetterSafariView
修复markdown中图片出现相对路径时, 界面会卡死的问题
2022-03-30 01:45:02 +08:00

260 lines
9.2 KiB
Swift

//
// SettingsView.swift
// PushDeer
//
// Created by HEXT on 2021/12/25.
//
import SwiftUI
import AuthenticationServices
import BetterSafariView
//import StoreKit
///
struct SettingsView: View {
@EnvironmentObject private var store: AppState
@State private var showUrl: URL?
var body: some View {
BaseNavigationView(title: "设置") {
ScrollView {
VStack {
SettingsItemView(title: NSLocalizedString("登录为", comment: "") + " " + userName(), button: NSLocalizedString("退出", comment: "退出登录按钮上的文字")) {
store.token = ""
}
.padding(EdgeInsets(top: 18, leading: 20, bottom: 0, trailing: 20))
#if !targetEnvironment(macCatalyst) && !APPCLIP && !SELFHOSTED
if WXApi.isWXAppInstalled() {
LoginInfoView()
.zIndex(-1)
.padding(EdgeInsets(top: -30, leading: 20, bottom: 0, trailing: 20))
}
#endif
if Env.isSelfHosted {
SettingsItemView(title: NSLocalizedString("API endpoint", comment: ""), button: NSLocalizedString("重置", comment: "")) {
store.api_endpoint = ""
store.token = ""
}
.padding(EdgeInsets(top: 18, leading: 20, bottom: 0, trailing: 20))
}
SettingsItemView(title: NSLocalizedString("喜欢PushDeer?", comment: ""), button: NSLocalizedString("评分", comment: "")) {
let urlStr = "itms-apps://itunes.apple.com/app/id\(Env.appStoreId)?action=write-review"
UIApplication.shared.open(URL(string: urlStr)!, options: [:], completionHandler: nil)
// , 3,
// SKStoreReviewController.requestReview()
}
.padding(EdgeInsets(top: 18, leading: 20, bottom: 0, trailing: 20))
SettingsItemView(title: NSLocalizedString("PushDeer官网", comment: ""), button: NSLocalizedString("查看", comment: "")) {
if store.isUseBuiltInBrowser {
showUrl = URL(string: Env.officialWebsite)
} else {
UIApplication.shared.open(URL(string: Env.officialWebsite)!, options: [:], completionHandler: nil)
}
}
.padding(EdgeInsets(top: 18, leading: 20, bottom: 0, trailing: 20))
#if !targetEnvironment(macCatalyst)
CardView {
HStack{
Toggle(isOn: $store.isUseBuiltInBrowser) {
Text("使用内置浏览器打开链接")
.font(.system(size: 18))
.foregroundColor(Color("textColor"))
}
.padding(16)
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
}
.frame(height: 74)
}
.padding(EdgeInsets(top: 18, leading: 20, bottom: 0, trailing: 20))
#endif
CardView {
VStack(alignment: .leading, spacing: 5){
Text("MarkDown BaseURL: (Image/Link)")
.font(.system(size: 18))
.foregroundColor(Color("textColor"))
EditableText(placeholder: "https://example.com/", value: store.markDownBaseURL ?? "") { value in
if value.isEmpty {
store.markDownBaseURL = nil;
HToast.showSuccess(NSLocalizedString("保存成功", comment: ""))
return
}
if URL(string: value) == nil {
HToast.showError(NSLocalizedString("URL 格式不正确", comment: ""))
return
}
if !value.lowercased().hasPrefix("http") {
HToast.showError(NSLocalizedString("请输入协议前缀: http:// 或 https://", comment: ""))
return
}
store.markDownBaseURL = value
HToast.showSuccess(NSLocalizedString("保存成功", comment: ""))
}
}
.padding(16)
.frame(height: 74)
}
.padding(EdgeInsets(top: 18, leading: 20, bottom: 0, trailing: 20))
Spacer()
}
}
}
.onAppear {
if store.userInfo != nil {
return
}
Task {
store.userInfo = try await HttpRequest.getUserInfo()
}
}
.safariView(item: $showUrl, content: { url in
SafariView(url: url)
})
// .fullScreenCover(item: $showUrl) {
//
// } content: { url in
// HSafariView(url: url)
// }
}
func userName() -> String {
if let name = store.userInfo?.name {
if name.isEmpty {
return NSLocalizedString("苹果用户", comment: "")
} else {
return name
}
} else {
return "--"
}
}
}
struct LoginInfoView: View {
enum AlertType : Identifiable {
var id: Self { self }
case apple
case wechat
}
@EnvironmentObject private var store: AppState
@State private var alertType: AlertType? = nil
static private var coordinator: AppleSignInCoordinator? = nil
var body: some View {
CardView {
HStack(spacing: 16) {
Spacer()
Circle()
.frame(width: 10, height: 10, alignment: .center)
.foregroundColor(store.userInfo?.apple_id?.isEmpty ?? true ? .gray : .green)
Button {
if store.userInfo?.apple_id?.isEmpty ?? true {
alertType = .apple
} else {
HToast.showText(NSLocalizedString("当前已经绑定苹果账号", comment: ""))
}
} label: {
Image(systemName: "applelogo")
.resizable()
.scaledToFit()
.frame( height: 40, alignment: .center)
}
Spacer()
Circle()
.frame(width: 10, height: 10, alignment: .center)
.foregroundColor(store.userInfo?.wechat_id?.isEmpty ?? true ? .gray : .green)
Button {
if store.userInfo?.wechat_id?.isEmpty ?? true {
alertType = .wechat
} else {
HToast.showText(NSLocalizedString("当前已经绑定微信账号", comment: ""))
}
} label: {
Image("weixin-login")
.resizable()
.renderingMode(.template)
.scaledToFit()
.frame(height: 37, alignment: .center)
}
Spacer()
}
.padding(EdgeInsets(top: 32, leading: 0, bottom: 12, trailing: 0))
}
.alert(item: $alertType) { alertType in
var message = ""
switch alertType {
case .apple:
message = NSLocalizedString("准备绑定苹果账号, 如果你绑定的账号之前已经存在, 则会合并到当前账号. (之前的Key可能会被删除)", comment: "")
case .wechat:
message = NSLocalizedString("准备绑定微信账号, 如果你绑定的账号之前已经存在, 则会合并到当前账号. (之前的Key可能会被删除)", comment: "")
}
return Alert(
title: Text("温馨提示"),
message: Text(message),
primaryButton: .default(
Text("绑定"),
action: {
switch alertType {
case .apple:
LoginInfoView.coordinator = AppleSignInCoordinator(
onRequest: { request in
request.requestedScopes = [.fullName, .email]
},
onCompletion: { result in
do {
switch result {
case let .success(authorization):
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
let idToken = String(data:appleIDCredential.identityToken!, encoding: .utf8)
print(idToken as Any)
//
let result = try await HttpRequest.mergeUser(type: "apple", tokenorcode: idToken!)
print(result)
// ,
store.userInfo = try await HttpRequest.getUserInfo()
}
case let .failure(error):
if (error as NSError).code == 1001 {
HToast.showWarning(NSLocalizedString("你已取消授权", comment: ""))
} else {
HToast.showError(error.localizedDescription)
}
}
} catch {
HToast.showError(error.localizedDescription)
}
}
)
LoginInfoView.coordinator?.performRequests()
case .wechat:
#if !targetEnvironment(macCatalyst) && !APPCLIP && !SELFHOSTED
let req = SendAuthReq()
req.scope = "snsapi_userinfo";
req.state = "bind";
WXApi.send(req) { b in
print("WXApi.send:", b)
}
// AppDelegate onResp
#endif
}
}
),
secondaryButton: .cancel(Text("稍后"))
)
}
}
}
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView().environmentObject(AppState.shared)
}
}