This commit is contained in:
mrFq1
2023-06-05 23:39:23 +08:00
parent e5860ead2c
commit f488f41f8d
72 changed files with 247 additions and 45 deletions
@@ -0,0 +1,48 @@
//
// APIServerItem.swift
// ClashX Dashboard
//
//
import SwiftUI
struct APIServerItem: View {
@State var server: String
var action: () -> Void
var onDelete: () -> Void
@State private var mouseOver = false
var body: some View {
HStack {
Button("X") {
onDelete()
}
.buttonStyle(.bordered)
Button() {
action()
} label: {
Text(server)
.font(.title2)
}
.buttonStyle(.borderless)
Spacer()
}
.frame(height: 21)
.padding(EdgeInsets(top: 12, leading: 20, bottom: 12, trailing: 20))
.overlay(
RoundedRectangle(cornerRadius: 6)
.stroke(.secondary, lineWidth: 1)
.padding(1)
)
}
}
//struct APIServerItem_Previews: PreviewProvider {
// static var previews: some View {
// APIServerItem()
// }
//}
@@ -0,0 +1,81 @@
//
// APISettingView.swift
// ClashX Dashboard
//
//
import SwiftUI
import Introspect
struct APISettingView: View {
@State var baseURL: String = ""
@State var secret: String = ""
@State var connectInfo: String = ""
@AppStorage("savedServers") var savedServers = SavedServersAppStorage()
var body: some View {
VStack(alignment: .center) {
HStack {
VStack(alignment: .leading) {
Text("API Base URL")
TextField("http://127.0.0.1:9090", text: $baseURL)
}
.frame(width: 250)
VStack(alignment: .leading) {
Text("Secret(optional)")
TextField("", text: $secret)
}
.frame(width: 120)
}
HStack {
Text(connectInfo)
Spacer()
Button("Add") {
savedServers.append(.init(apiURL: baseURL, secret: secret))
print(savedServers)
}
}
List(savedServers, id: \.id) { server in
APIServerItem(server: server.apiURL) {
ConfigManager.shared.overrideApiURL = .init(string: server.apiURL)
ConfigManager.shared.overrideSecret = server.secret
ApiRequest.requestVersion { version in
if let version {
connectInfo = ""
print(version)
ConfigManager.shared.isRunning = true
} else {
connectInfo = "Failed to connect"
}
}
} onDelete: {
savedServers.removeAll {
$0.id == server.id
}
}
}
.introspectTableView {
$0.backgroundColor = NSColor.clear
$0.enclosingScrollView?.drawsBackground = false
}
}
.padding(.top)
.fixedSize(horizontal: true, vertical: false)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
struct APISettingView_Previews: PreviewProvider {
static var previews: some View {
APISettingView()
}
}
@@ -0,0 +1,36 @@
//
// ClashServerAppStorage.swift
// ClashX Dashboard
//
//
import Foundation
import SwiftUI
typealias SavedServersAppStorage = [ClashServerAppStorage]
struct ClashServerAppStorage: Codable, Identifiable {
var id = UUID().uuidString
let apiURL: String
let secret: String
}
extension SavedServersAppStorage: RawRepresentable {
public init?(rawValue: String) {
guard let data = rawValue.data(using: .utf8),
let result = try? JSONDecoder().decode(SavedServersAppStorage.self, from: data)
else {
return nil
}
self = result
}
public var rawValue: String {
guard let data = try? JSONEncoder().encode(self),
let result = String(data: data, encoding: .utf8)
else {
return "[]"
}
return result
}
}
@@ -0,0 +1,70 @@
//
// ProgressButton.swift
// ClashX Dashboard
//
//
import SwiftUI
import AppKit
struct ProgressButton: View {
@State var title: String
@State var title2: String
@State var iconName: String
@Binding var inProgress: Bool
@State var autoWidth = true
@State var action: () -> Void
var body: some View {
Button() {
action()
} label: {
HStack {
VStack {
if inProgress {
ProgressView()
.controlSize(.small)
} else {
Image(systemName: iconName)
}
}
.frame(width: 12)
if title != "" {
Spacer()
Text(inProgress ? title2 : title)
.font(.system(size: 13))
Spacer()
}
}
.animation(.default, value: inProgress)
.foregroundColor(inProgress ? .gray : .blue)
}
.disabled(inProgress)
.frame(width: autoWidth ? ProgressButton.width([title, title2]) : nil)
}
static func width(_ titles: [String]) -> CGFloat {
let str = titles.max {
$0.count < $1.count
} ?? ""
if str == "" {
return 12 + 8
}
let w = str.size(withAttributes: [.font: NSFont.systemFont(ofSize: 13)]).width
return w + 12 + 45
}
}
//struct ProgressButton_Previews: PreviewProvider {
// static var previews: some View {
// ProgressButton()
// }
//}