Init commit

This commit is contained in:
世界
2023-07-15 15:03:45 +08:00
commit f441b89efb
122 changed files with 7355 additions and 0 deletions
@@ -0,0 +1,89 @@
import Foundation
import Library
import SwiftUI
import UniformTypeIdentifiers
public struct ServiceLogView: View {
#if os(macOS)
public static let windowID = "service-log"
#endif
@State private var isLoading = true
@State private var content = ""
@State private var fileExporterPresented = false
private let logFont = Font.system(.caption, design: .monospaced)
public init() {}
public var body: some View {
viewBuilder {
if isLoading {
ProgressView().onAppear {
Task.detached {
loadContent()
}
}
} else {
if content.isEmpty {
Text("Empty content")
} else {
ScrollView {
Text(content).font(logFont)
}
.padding()
}
}
}
.toolbar {
Button("Export") {
fileExporterPresented = true
}
.disabled(content.isEmpty)
}
.fileExporter(
isPresented: $fileExporterPresented,
document: LogDocument(content),
contentType: .text,
defaultFilename: "service-log.txt",
onCompletion: { _ in }
)
.navigationTitle("Service Log")
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
#endif
}
private func loadContent() {
do {
content = try String(contentsOf: FilePath.cacheDirectory.appendingPathComponent("stderr.log"))
} catch {}
if content.isEmpty {
do {
content = try String(contentsOf: FilePath.cacheDirectory.appendingPathComponent("stderr.log.old"))
} catch {}
}
isLoading = false
}
private struct LogDocument: FileDocument {
static var readableContentTypes = [UTType.text]
let content: String
init(_ content: String) {
self.content = content
}
init(configuration: ReadConfiguration) throws {
if let data = configuration.file.regularFileContents {
content = String(decoding: data, as: UTF8.self)
} else {
content = ""
}
}
func fileWrapper(configuration _: WriteConfiguration) throws -> FileWrapper {
FileWrapper(regularFileWithContents: Data(content.utf8))
}
}
}
@@ -0,0 +1,147 @@
import Foundation
import Libbox
import Library
import SwiftUI
#if os(macOS)
import ServiceManagement
#endif
public struct SettingView: View {
#if os(macOS)
@Environment(\.openWindow) private var openWindow
#endif
@State private var isLoading = true
#if os(macOS)
@State private var startAtLogin = false
@Environment(\.showMenuBarExtra) private var showMenuBarExtra
#endif
@State private var disableMemoryLimit = false
@State private var version = ""
@State private var dataSize = ""
@State private var errorPresented = false
@State private var errorMessage = ""
public init() {}
public var body: some View {
viewBuilder {
if isLoading {
ProgressView().onAppear {
Task.detached {
await loadSettings()
}
}
} else {
FormView {
#if os(macOS)
Section("MacOS") {
Toggle("Start At Login", isOn: $startAtLogin)
.onChange(of: startAtLogin) { newValue in
Task.detached {
updateLoginItems(newValue)
}
}
Toggle("Show in Menu Bar", isOn: showMenuBarExtra)
.onChange(of: showMenuBarExtra.wrappedValue) { newValue in
Task.detached {
SharedPreferences.showMenuBarExtra = newValue
}
}
}
#endif
Section("Packet Tunnel") {
Toggle("Disable Memory Limit", isOn: $disableMemoryLimit)
.onChange(of: disableMemoryLimit) { newValue in
Task.detached {
SharedPreferences.disableMemoryLimit = newValue
}
}
}
Section("Core") {
FormTextItem("Version", version)
FormTextItem("Data Size", dataSize)
#if os(iOS)
NavigationLink(destination: ServiceLogView()) {
Text("View Service Log")
}
#elseif os(macOS)
Button("View Service Log") {
openWindow(id: ServiceLogView.windowID)
}
#endif
Button("Clear Working Directory") {
Task.detached {
clearWorkingDirectory()
}
}
.foregroundColor(.red)
}
}
}
}
.navigationTitle("Settings")
.alert(isPresented: $errorPresented) {
Alert(
title: Text("Error"),
message: Text(errorMessage),
dismissButton: .default(Text("Ok"))
)
}
}
#if os(macOS)
private func updateLoginItems(_ startAtLogin: Bool) {
do {
if startAtLogin {
if SMAppService.mainApp.status == .enabled {
try? SMAppService.mainApp.unregister()
}
try SMAppService.mainApp.register()
} else {
try SMAppService.mainApp.unregister()
}
} catch {
errorMessage = error.localizedDescription
errorPresented = true
}
}
#endif
private func loadSettings() async {
#if os(macOS)
startAtLogin = SMAppService.mainApp.status == .enabled
#endif
disableMemoryLimit = SharedPreferences.disableMemoryLimit
version = LibboxVersion()
dataSize = "Loading..."
isLoading = false
dataSize = (try? FilePath.workingDirectory.formattedSize()) ?? "Unknown"
}
private func clearWorkingDirectory() {
try? FileManager.default.removeItem(at: FilePath.workingDirectory)
isLoading = true
}
}
private extension URL {
func formattedSize() throws -> String? {
guard let urls = FileManager.default.enumerator(at: self, includingPropertiesForKeys: nil)?.allObjects as? [URL] else {
return nil
}
let size = try urls.lazy.reduce(0) {
try ($1.resourceValues(forKeys: [.totalFileAllocatedSizeKey]).totalFileAllocatedSize ?? 0) + $0
}
let formatter = ByteCountFormatter()
formatter.countStyle = .file
guard let byteCount = formatter.string(for: size) else {
return nil
}
return byteCount
}
}