mirror of
https://github.com/cranci1/Sora.git
synced 2026-04-05 00:59:55 +00:00
145 lines
4.8 KiB
Swift
145 lines
4.8 KiB
Swift
//
|
|
// SettingsViewLogger.swift
|
|
// Sora
|
|
//
|
|
// Created by seiike on 16/01/2025.
|
|
//
|
|
|
|
import SwiftUI
|
|
import Kingfisher
|
|
|
|
fileprivate struct SettingsSection<Content: View>: View {
|
|
let title: String
|
|
let footer: String?
|
|
let content: Content
|
|
|
|
init(title: String, footer: String? = nil, @ViewBuilder content: () -> Content) {
|
|
self.title = title
|
|
self.footer = footer
|
|
self.content = content()
|
|
}
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading, spacing: 4) {
|
|
Text(title.uppercased())
|
|
.font(.footnote)
|
|
.foregroundStyle(.gray)
|
|
.padding(.horizontal, 20)
|
|
|
|
VStack(spacing: 0) {
|
|
content
|
|
}
|
|
.background(.ultraThinMaterial)
|
|
.clipShape(RoundedRectangle(cornerRadius: 12))
|
|
.overlay(
|
|
RoundedRectangle(cornerRadius: 12)
|
|
.strokeBorder(
|
|
LinearGradient(
|
|
gradient: Gradient(stops: [
|
|
.init(color: Color.accentColor.opacity(0.3), location: 0),
|
|
.init(color: Color.accentColor.opacity(0), location: 1)
|
|
]),
|
|
startPoint: .top,
|
|
endPoint: .bottom
|
|
),
|
|
lineWidth: 0.5
|
|
)
|
|
)
|
|
.padding(.horizontal, 20)
|
|
|
|
if let footer = footer {
|
|
Text(footer)
|
|
.font(.footnote)
|
|
.foregroundStyle(.gray)
|
|
.padding(.horizontal, 20)
|
|
.padding(.top, 4)
|
|
}
|
|
}
|
|
.scrollViewBottomPadding()
|
|
}
|
|
}
|
|
|
|
struct SettingsViewLogger: View {
|
|
@State private var logs: String = ""
|
|
@State private var isLoading: Bool = true
|
|
@StateObject private var filterViewModel = LogFilterViewModel.shared
|
|
|
|
var body: some View {
|
|
ScrollView {
|
|
VStack(spacing: 24) {
|
|
SettingsSection(title: "Logs") {
|
|
if isLoading {
|
|
HStack {
|
|
ProgressView()
|
|
.scaleEffect(0.8)
|
|
Text("Loading logs...")
|
|
.font(.footnote)
|
|
.foregroundColor(.secondary)
|
|
}
|
|
.frame(maxWidth: .infinity, alignment: .center)
|
|
.padding(.vertical, 20)
|
|
} else {
|
|
Text(logs)
|
|
.font(.footnote)
|
|
.foregroundColor(.secondary)
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
.padding(.horizontal, 16)
|
|
.padding(.vertical, 12)
|
|
.textSelection(.enabled)
|
|
}
|
|
}
|
|
}
|
|
.padding(.vertical, 20)
|
|
}
|
|
.navigationTitle("Logs")
|
|
.onAppear {
|
|
loadLogsAsync()
|
|
}
|
|
.toolbar {
|
|
ToolbarItem(placement: .navigationBarTrailing) {
|
|
HStack {
|
|
Menu {
|
|
Button(action: {
|
|
UIPasteboard.general.string = logs
|
|
DropManager.shared.showDrop(title: "Copied to Clipboard", subtitle: "", duration: 1.0, icon: UIImage(systemName: "doc.on.clipboard.fill"))
|
|
}) {
|
|
Label("Copy to Clipboard", systemImage: "doc.on.doc")
|
|
}
|
|
Button(role: .destructive, action: {
|
|
clearLogsAsync()
|
|
}) {
|
|
Label("Clear Logs", systemImage: "trash")
|
|
}
|
|
} label: {
|
|
Image(systemName: "ellipsis.circle")
|
|
.resizable()
|
|
.frame(width: 20, height: 20)
|
|
}
|
|
|
|
NavigationLink(destination: SettingsViewLoggerFilter(viewModel: filterViewModel)) {
|
|
Image(systemName: "slider.horizontal.3")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private func loadLogsAsync() {
|
|
Task {
|
|
let loadedLogs = await Logger.shared.getLogsAsync()
|
|
await MainActor.run {
|
|
self.logs = loadedLogs
|
|
self.isLoading = false
|
|
}
|
|
}
|
|
}
|
|
|
|
private func clearLogsAsync() {
|
|
Task {
|
|
await Logger.shared.clearLogsAsync()
|
|
await MainActor.run {
|
|
self.logs = ""
|
|
}
|
|
}
|
|
}
|
|
}
|