mirror of
https://github.com/StikDebug/StikDebug.git
synced 2026-10-16 04:20:30 +00:00
commit
a8451e4df0
7 changed files with 213 additions and 103 deletions
|
|
@ -634,4 +634,4 @@
|
|||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = DC6F1D2F2D94EADD0071B2B6 /* Project object */;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,18 +19,25 @@ extension Color {
|
|||
}
|
||||
|
||||
init?(hex: String) {
|
||||
let r, g, b: CGFloat
|
||||
let start = hex.index(hex.startIndex, offsetBy: 1)
|
||||
let hexColor = String(hex[start...])
|
||||
|
||||
if hexColor.count == 6, let hexNumber = Int(hexColor, radix: 16) {
|
||||
r = CGFloat((hexNumber & 0xff0000) >> 16) / 255
|
||||
g = CGFloat((hexNumber & 0x00ff00) >> 8) / 255
|
||||
b = CGFloat(hexNumber & 0x0000ff) / 255
|
||||
self.init(red: r, green: g, blue: b)
|
||||
return
|
||||
if hex.isEmpty || hex.count < 2 {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
let r, g, b: CGFloat
|
||||
|
||||
if hex.hasPrefix("#") && hex.count >= 7 {
|
||||
let start = hex.index(hex.startIndex, offsetBy: 1)
|
||||
let hexColor = String(hex[start...])
|
||||
|
||||
if hexColor.count == 6, let hexNumber = Int(hexColor, radix: 16) {
|
||||
r = CGFloat((hexNumber & 0xff0000) >> 16) / 255
|
||||
g = CGFloat((hexNumber & 0x00ff00) >> 8) / 255
|
||||
b = CGFloat(hexNumber & 0x0000ff) / 255
|
||||
self.init(red: r, green: g, blue: b)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -441,39 +441,53 @@ func startHeartbeatInBackground() {
|
|||
|
||||
struct LoadingView: View {
|
||||
@State private var animate = false
|
||||
|
||||
@Environment(\.colorScheme) private var colorScheme
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
LinearGradient(gradient: Gradient(colors: [Color.black, Color.black]),
|
||||
startPoint: .topLeading,
|
||||
endPoint: .bottomTrailing)
|
||||
// Use system background color instead of fixed black
|
||||
Color(colorScheme == .dark ? .black : .white)
|
||||
.ignoresSafeArea()
|
||||
|
||||
|
||||
VStack {
|
||||
ZStack {
|
||||
// Background circle - slightly visible in both themes
|
||||
Circle()
|
||||
.stroke(lineWidth: 8)
|
||||
.foregroundColor(Color.white.opacity(0.3))
|
||||
.foregroundColor(colorScheme == .dark ?
|
||||
Color.white.opacity(0.3) :
|
||||
Color.black.opacity(0.1))
|
||||
.frame(width: 80, height: 80)
|
||||
|
||||
|
||||
// Animated circle - adapts to theme
|
||||
Circle()
|
||||
.trim(from: 0, to: 0.7)
|
||||
.stroke(AngularGradient(
|
||||
gradient: Gradient(colors: [Color.white.opacity(0.8), Color.white.opacity(0.3)]),
|
||||
gradient: Gradient(colors: [
|
||||
colorScheme == .dark ? Color.white.opacity(0.8) : Color.blue.opacity(0.8),
|
||||
colorScheme == .dark ? Color.white.opacity(0.3) : Color.blue.opacity(0.3)
|
||||
]),
|
||||
center: .center
|
||||
), style: StrokeStyle(lineWidth: 6, lineCap: .round))
|
||||
.rotationEffect(.degrees(animate ? 360 : 0))
|
||||
.frame(width: 80, height: 80)
|
||||
.animation(Animation.linear(duration: 1.2).repeatForever(autoreverses: false), value: animate)
|
||||
}
|
||||
.shadow(color: .white.opacity(0.5), radius: 10, x: 0, y: 0)
|
||||
// Shadow adapts to theme
|
||||
.shadow(color: colorScheme == .dark ?
|
||||
.white.opacity(0.5) :
|
||||
.blue.opacity(0.3),
|
||||
radius: 10, x: 0, y: 0)
|
||||
.onAppear {
|
||||
animate = true
|
||||
}
|
||||
|
||||
|
||||
// Text adapts to theme
|
||||
Text("Loading...")
|
||||
.font(.system(size: 20, weight: .medium, design: .rounded))
|
||||
.foregroundColor(.white.opacity(0.8))
|
||||
.foregroundColor(colorScheme == .dark ?
|
||||
.white.opacity(0.8) :
|
||||
.black.opacity(0.8))
|
||||
.padding(.top, 20)
|
||||
.opacity(animate ? 1.0 : 0.5)
|
||||
.animation(Animation.easeInOut(duration: 1.5).repeatForever(autoreverses: true), value: animate)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
//
|
||||
// AppStoreIconFetcher.swift
|
||||
// IconsFetcher.swift
|
||||
// Dont change the name of the actual file (it will break stuff)
|
||||
// StikJIT
|
||||
//
|
||||
// Created by neoarz on 3/28/25.
|
||||
|
|
@ -8,6 +9,7 @@
|
|||
import UIKit
|
||||
|
||||
// Not AppStore
|
||||
// Uses idevice
|
||||
class AppStoreIconFetcher {
|
||||
static private var iconCache: [String: UIImage] = [:]
|
||||
static private let iconFetchDispatchQueue = DispatchQueue(label: "com.stik.StikJIT.iconFetchQueue", attributes: .concurrent)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import UIKit
|
|||
|
||||
struct ConsoleLogsView: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@Environment(\.colorScheme) private var colorScheme
|
||||
@StateObject private var logManager = LogManager.shared
|
||||
@State private var autoScroll = true
|
||||
@State private var scrollView: ScrollViewProxy? = nil
|
||||
|
|
@ -23,22 +24,23 @@ struct ConsoleLogsView: View {
|
|||
var body: some View {
|
||||
NavigationView {
|
||||
ZStack {
|
||||
Color.black
|
||||
// Use system background color instead of fixed black
|
||||
Color(colorScheme == .dark ? .black : .white)
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
|
||||
VStack(spacing: 0) {
|
||||
// Terminal logs area (made it look somewhat like feathers implementation)
|
||||
// Terminal logs area with theme support
|
||||
ScrollViewReader { proxy in
|
||||
ScrollView {
|
||||
VStack(spacing: 0) {
|
||||
// Device Information (all thw way on top)
|
||||
// Device Information
|
||||
ForEach(["Version: \(UIDevice.current.systemVersion)",
|
||||
"Name: \(UIDevice.current.name)",
|
||||
"Model: \(UIDevice.current.model)",
|
||||
"StikJIT Version: App Version: 1.0"], id: \.self) { info in
|
||||
Text("[\(timeString())] ℹ️ \(info)")
|
||||
.font(.system(size: 11, design: .monospaced))
|
||||
.foregroundColor(.white)
|
||||
.foregroundColor(colorScheme == .dark ? .white : .black)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding(.vertical, 2)
|
||||
.padding(.horizontal, 4)
|
||||
|
|
@ -72,7 +74,7 @@ struct ConsoleLogsView: View {
|
|||
|
||||
Spacer()
|
||||
|
||||
|
||||
// Action buttons section - update to be theme aware
|
||||
VStack(spacing: 16) {
|
||||
// Error count with red theme
|
||||
HStack {
|
||||
|
|
@ -86,7 +88,7 @@ struct ConsoleLogsView: View {
|
|||
}
|
||||
.padding(.horizontal)
|
||||
|
||||
// Action buttons with dark background
|
||||
// Action buttons with theme-appropriate background
|
||||
VStack(spacing: 1) {
|
||||
// Export button
|
||||
Button(action: {
|
||||
|
|
@ -138,14 +140,18 @@ struct ConsoleLogsView: View {
|
|||
.padding(.horizontal, 20)
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
.background(Color(red: 0.1, green: 0.1, blue: 0.1))
|
||||
.background(colorScheme == .dark ?
|
||||
Color(red: 0.1, green: 0.1, blue: 0.1) :
|
||||
Color(UIColor.secondarySystemBackground))
|
||||
|
||||
Divider()
|
||||
.background(Color(red: 0.15, green: 0.15, blue: 0.15))
|
||||
.background(colorScheme == .dark ?
|
||||
Color(red: 0.15, green: 0.15, blue: 0.15) :
|
||||
Color(UIColor.separator))
|
||||
|
||||
// Copy button
|
||||
Button(action: {
|
||||
// Create logs content with device information
|
||||
// Existing code for copying logs
|
||||
var logsContent = "=== DEVICE INFORMATION ===\n"
|
||||
logsContent += "Version: \(UIDevice.current.systemVersion)\n"
|
||||
logsContent += "Name: \(UIDevice.current.name)\n"
|
||||
|
|
@ -153,15 +159,12 @@ struct ConsoleLogsView: View {
|
|||
logsContent += "StikJIT Version: App Version: 1.0\n\n"
|
||||
logsContent += "=== LOG ENTRIES ===\n"
|
||||
|
||||
// Add all log entries with proper formatting
|
||||
logsContent += logManager.logs.map {
|
||||
"[\(formatTime(date: $0.timestamp))] [\($0.type.rawValue)] \($0.message)"
|
||||
}.joined(separator: "\n")
|
||||
|
||||
// Copy to clipboard
|
||||
UIPasteboard.general.string = logsContent
|
||||
|
||||
// Show success alert using SwiftUI alert
|
||||
alertTitle = "Logs Copied"
|
||||
alertMessage = "Logs have been copied to clipboard."
|
||||
isError = false
|
||||
|
|
@ -178,67 +181,72 @@ struct ConsoleLogsView: View {
|
|||
.padding(.horizontal, 20)
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
.background(Color(red: 0.1, green: 0.1, blue: 0.1))
|
||||
.background(colorScheme == .dark ?
|
||||
Color(red: 0.1, green: 0.1, blue: 0.1) :
|
||||
Color(UIColor.secondarySystemBackground))
|
||||
}
|
||||
.cornerRadius(10)
|
||||
.padding(.horizontal)
|
||||
.padding(.bottom, 20)
|
||||
.padding(.bottom, 16)
|
||||
}
|
||||
.padding(.bottom, 8)
|
||||
}
|
||||
}
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .principal) {
|
||||
Text("Console Logs")
|
||||
.font(.headline)
|
||||
.foregroundColor(.white)
|
||||
}
|
||||
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button(action: {
|
||||
dismiss()
|
||||
}) {
|
||||
HStack(spacing: 2) {
|
||||
Image(systemName: "chevron.left")
|
||||
.font(.system(size: 16, weight: .semibold))
|
||||
Text("Settings")
|
||||
.fontWeight(.regular)
|
||||
}
|
||||
.foregroundColor(.blue)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .principal) {
|
||||
Text("Console Logs")
|
||||
.font(.headline)
|
||||
.foregroundColor(colorScheme == .dark ? .white : .black)
|
||||
}
|
||||
}
|
||||
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Button(action: {
|
||||
logManager.clearLogs()
|
||||
}) {
|
||||
Text("Clear")
|
||||
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button(action: {
|
||||
dismiss()
|
||||
}) {
|
||||
HStack(spacing: 2) {
|
||||
Image(systemName: "chevron.left")
|
||||
.font(.system(size: 16, weight: .semibold))
|
||||
Text("Settings")
|
||||
.fontWeight(.regular)
|
||||
}
|
||||
.foregroundColor(.blue)
|
||||
}
|
||||
}
|
||||
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Button(action: {
|
||||
logManager.clearLogs()
|
||||
}) {
|
||||
Text("Clear")
|
||||
.foregroundColor(.blue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
.overlay(
|
||||
ZStack {
|
||||
if showingCustomAlert {
|
||||
CustomErrorView(
|
||||
title: alertTitle,
|
||||
message: alertMessage,
|
||||
onDismiss: {
|
||||
showingCustomAlert = false
|
||||
},
|
||||
showButton: true,
|
||||
primaryButtonText: "OK",
|
||||
messageType: isError ? .error : .success
|
||||
)
|
||||
.overlay(
|
||||
Group {
|
||||
if showingCustomAlert {
|
||||
Color.black.opacity(0.4)
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
.overlay(
|
||||
CustomErrorView(
|
||||
title: alertTitle,
|
||||
message: alertMessage,
|
||||
onDismiss: {
|
||||
showingCustomAlert = false
|
||||
},
|
||||
showButton: true,
|
||||
primaryButtonText: "OK",
|
||||
messageType: isError ? .error : .success
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Creates an NSAttributedString that combines timestamp, type, and message
|
||||
// with proper styling for each component
|
||||
// Update to use theme-aware colors
|
||||
private func createLogAttributedString(_ logEntry: LogManager.LogEntry) -> NSAttributedString {
|
||||
let fullString = NSMutableAttributedString()
|
||||
|
||||
|
|
@ -246,7 +254,7 @@ struct ConsoleLogsView: View {
|
|||
let timestampString = "[\(formatTime(date: logEntry.timestamp))]"
|
||||
let timestampAttr = NSAttributedString(
|
||||
string: timestampString,
|
||||
attributes: [.foregroundColor: UIColor.gray]
|
||||
attributes: [.foregroundColor: colorScheme == .dark ? UIColor.gray : UIColor.darkGray]
|
||||
)
|
||||
fullString.append(timestampAttr)
|
||||
fullString.append(NSAttributedString(string: " "))
|
||||
|
|
@ -264,28 +272,25 @@ struct ConsoleLogsView: View {
|
|||
// Message part
|
||||
let messageAttr = NSAttributedString(
|
||||
string: logEntry.message,
|
||||
attributes: [.foregroundColor: UIColor.white]
|
||||
attributes: [.foregroundColor: colorScheme == .dark ? UIColor.white : UIColor.black]
|
||||
)
|
||||
fullString.append(messageAttr)
|
||||
|
||||
return fullString
|
||||
}
|
||||
|
||||
// Helper to display current time
|
||||
private func timeString() -> String {
|
||||
let formatter = DateFormatter()
|
||||
formatter.dateFormat = "HH:mm:ss"
|
||||
return formatter.string(from: Date())
|
||||
}
|
||||
|
||||
// Helper to format Date objects to time strings
|
||||
private func formatTime(date: Date) -> String {
|
||||
let formatter = DateFormatter()
|
||||
formatter.dateFormat = "HH:mm:ss"
|
||||
return formatter.string(from: date)
|
||||
}
|
||||
|
||||
// Return color based on log type
|
||||
private func colorForLogType(_ type: LogManager.LogEntry.LogType) -> Color {
|
||||
switch type {
|
||||
case .info:
|
||||
|
|
@ -300,7 +305,6 @@ struct ConsoleLogsView: View {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
struct ConsoleLogsView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ConsoleLogsView()
|
||||
|
|
|
|||
|
|
@ -17,9 +17,10 @@ extension UIDocumentPickerViewController {
|
|||
struct HomeView: View {
|
||||
|
||||
@AppStorage("username") private var username = "User"
|
||||
@AppStorage("customBackgroundColor") private var customBackgroundColorHex: String = Color.primaryBackground.toHex() ?? "#000000"
|
||||
@AppStorage("customBackgroundColor") private var customBackgroundColorHex: String = ""
|
||||
@AppStorage("autoQuitAfterEnablingJIT") private var doAutoQuitAfterEnablingJIT = false
|
||||
@State private var selectedBackgroundColor: Color = Color(hex: UserDefaults.standard.string(forKey: "customBackgroundColor") ?? "#000000") ?? Color.primaryBackground
|
||||
@State private var selectedBackgroundColor: Color = Color(hex: UserDefaults.standard.string(forKey: "customBackgroundColor") ?? "") ?? .clear
|
||||
@Environment(\.colorScheme) private var colorScheme
|
||||
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
|
||||
@AppStorage("bundleID") private var bundleID: String = ""
|
||||
@State private var isProcessing = false
|
||||
|
|
@ -38,7 +39,11 @@ struct HomeView: View {
|
|||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
selectedBackgroundColor.edgesIgnoringSafeArea(.all)
|
||||
// Use the background color or default to appearance-based color if not set
|
||||
(selectedBackgroundColor == .clear ?
|
||||
(colorScheme == .dark ? Color.black : Color.white) :
|
||||
selectedBackgroundColor)
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
|
||||
VStack(spacing: 25) {
|
||||
Spacer()
|
||||
|
|
@ -145,6 +150,11 @@ struct HomeView: View {
|
|||
}
|
||||
.onAppear {
|
||||
checkPairingFileExists()
|
||||
// Don't initialize specific color value when empty - empty means "use system theme"
|
||||
// This was causing the toggle to turn off when returning to settings
|
||||
|
||||
// Initialize background color
|
||||
refreshBackground()
|
||||
}
|
||||
.onReceive(timer) { _ in
|
||||
refreshBackground()
|
||||
|
|
@ -258,7 +268,11 @@ struct HomeView: View {
|
|||
}
|
||||
|
||||
private func refreshBackground() {
|
||||
selectedBackgroundColor = Color(hex: customBackgroundColorHex) ?? Color.primaryBackground
|
||||
if customBackgroundColorHex.isEmpty {
|
||||
selectedBackgroundColor = colorScheme == .dark ? Color.black : Color.white
|
||||
} else {
|
||||
selectedBackgroundColor = Color(hex: customBackgroundColorHex) ?? (colorScheme == .dark ? Color.black : Color.white)
|
||||
}
|
||||
}
|
||||
|
||||
private func startJITInBackground(with bundleID: String) {
|
||||
|
|
|
|||
|
|
@ -8,18 +8,20 @@ import UniformTypeIdentifiers
|
|||
|
||||
struct SettingsView: View {
|
||||
@AppStorage("username") private var username = "User"
|
||||
@AppStorage("customBackgroundColor") private var customBackgroundColorHex: String = Color.primaryBackground.toHex() ?? "#000000"
|
||||
@AppStorage("customBackgroundColor") private var customBackgroundColorHex: String = ""
|
||||
@AppStorage("selectedAppIcon") private var selectedAppIcon: String = "AppIcon"
|
||||
@AppStorage("autoQuitAfterEnablingJIT") private var doAutoQuitAfterEnablingJIT = false
|
||||
@State private var isShowingPairingFilePicker = false
|
||||
@Environment(\.colorScheme) private var colorScheme
|
||||
|
||||
@State private var selectedBackgroundColor: Color = Color.primaryBackground
|
||||
@State private var selectedBackgroundColor: Color = .clear
|
||||
@State private var showIconPopover = false
|
||||
@State private var showPairingFileMessage = false
|
||||
@State private var pairingFileIsValid = false
|
||||
@State private var isImportingFile = false
|
||||
@State private var importProgress: Float = 0.0
|
||||
@State private var is_lc = false
|
||||
@State private var showColorPickerPopup = false
|
||||
|
||||
@StateObject private var mountProg = MountingProgress.shared
|
||||
|
||||
|
|
@ -81,6 +83,11 @@ struct SettingsView: View {
|
|||
.padding(14)
|
||||
.background(Color(UIColor.tertiarySystemBackground))
|
||||
.cornerRadius(12)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.stroke(Color.gray.opacity(0.2), lineWidth: 1)
|
||||
)
|
||||
.shadow(color: Color.black.opacity(0.03), radius: 1, x: 0, y: 1)
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.bottom, 8)
|
||||
|
|
@ -98,15 +105,72 @@ struct SettingsView: View {
|
|||
.foregroundColor(.primary)
|
||||
.padding(.bottom, 4)
|
||||
|
||||
ColorPicker("Background Color", selection: $selectedBackgroundColor)
|
||||
.onChange(of: selectedBackgroundColor) { newColor in
|
||||
saveCustomBackgroundColor(newColor)
|
||||
// Theme selector with segmented control style
|
||||
VStack(alignment: .leading, spacing: 10) {
|
||||
Text("Background Color")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.secondary)
|
||||
|
||||
// Clean segmented style picker
|
||||
Picker("Theme Mode", selection: Binding(
|
||||
get: { customBackgroundColorHex.isEmpty },
|
||||
set: { newValue in
|
||||
if newValue {
|
||||
// System theme selected
|
||||
customBackgroundColorHex = ""
|
||||
selectedBackgroundColor = colorScheme == .dark ? Color.black : Color.white
|
||||
} else if customBackgroundColorHex.isEmpty {
|
||||
// Custom color selected - initialize with current theme color
|
||||
let initialColor = colorScheme == .dark ? Color.black : Color.white
|
||||
customBackgroundColorHex = initialColor.toHex() ?? "#000000"
|
||||
selectedBackgroundColor = initialColor
|
||||
|
||||
// Don't open color picker popup automatically anymore
|
||||
// User will need to press the "Change Color" button
|
||||
}
|
||||
}
|
||||
)) {
|
||||
Text("System").tag(true)
|
||||
Text("Custom").tag(false)
|
||||
}
|
||||
.foregroundColor(.primary)
|
||||
.padding(.vertical, 6)
|
||||
.pickerStyle(SegmentedPickerStyle())
|
||||
.padding(.vertical, 4)
|
||||
|
||||
// Show selection button and color picker inline when in custom mode
|
||||
if !customBackgroundColorHex.isEmpty {
|
||||
HStack {
|
||||
// Left side - just text, no color preview
|
||||
Text("Choose color")
|
||||
.font(.subheadline)
|
||||
.fontWeight(.medium)
|
||||
|
||||
Spacer()
|
||||
|
||||
// Right side - embedded color picker
|
||||
ColorPicker("", selection: $selectedBackgroundColor, supportsOpacity: false)
|
||||
.labelsHidden()
|
||||
.scaleEffect(0.8)
|
||||
.onChange(of: selectedBackgroundColor) { newColor in
|
||||
saveCustomBackgroundColor(newColor)
|
||||
}
|
||||
}
|
||||
.padding(.vertical, 8)
|
||||
.transition(.opacity)
|
||||
}
|
||||
|
||||
// Help text - only show for system mode
|
||||
if customBackgroundColorHex.isEmpty {
|
||||
Text("Uses light/dark mode system colors")
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
.padding(.top, 4)
|
||||
}
|
||||
}
|
||||
.padding(.vertical, 6)
|
||||
}
|
||||
.padding(.vertical, 20)
|
||||
.padding(.horizontal, 16)
|
||||
.animation(.easeInOut(duration: 0.2), value: customBackgroundColorHex.isEmpty)
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
|
|
@ -534,11 +598,16 @@ struct SettingsView: View {
|
|||
}
|
||||
|
||||
private func loadCustomBackgroundColor() {
|
||||
selectedBackgroundColor = Color(hex: customBackgroundColorHex) ?? Color.primaryBackground
|
||||
if customBackgroundColorHex.isEmpty {
|
||||
selectedBackgroundColor = colorScheme == .dark ? Color.black : Color.white
|
||||
} else {
|
||||
selectedBackgroundColor = Color(hex: customBackgroundColorHex) ?? (colorScheme == .dark ? Color.black : Color.white)
|
||||
}
|
||||
}
|
||||
|
||||
private func saveCustomBackgroundColor(_ color: Color) {
|
||||
customBackgroundColorHex = color.toHex() ?? "#000000"
|
||||
// Always save the custom color if we got here (since auto theme mode is disabled)
|
||||
customBackgroundColorHex = color.toHex() ?? ""
|
||||
}
|
||||
|
||||
private func changeAppIcon(to iconName: String) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue