mirror of
https://github.com/neon443/ShhShell.git
synced 2026-03-11 13:26:16 +00:00
!!!!!!!!!!
fixed selecting themes - it now actually remembers!! fix all themes having no names fix remembering selected themes added toTheme to return a theme from a themecodable removed themeNames - its not needed as the names are saved in the ThemeCodable itself extracted colorcodable and themecodable into their own files removed all the debug prints
This commit is contained in:
@@ -2,6 +2,10 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>0x96f</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>0x96f</string>
|
||||||
<key>Ansi 0 Color</key>
|
<key>Ansi 0 Color</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Alpha Component</key>
|
<key>Alpha Component</key>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>catppuccinFrappe</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>catppuccinFrappe</string>
|
||||||
<key>Ansi 0 Color</key>
|
<key>Ansi 0 Color</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Alpha Component</key>
|
<key>Alpha Component</key>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>catppuccinMocha</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>catppuccinMocha</string>
|
||||||
<key>Ansi 0 Color</key>
|
<key>Ansi 0 Color</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Alpha Component</key>
|
<key>Alpha Component</key>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>defaultTheme</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>defaultTheme</string>
|
||||||
<key>Ansi 0 Color</key>
|
<key>Ansi 0 Color</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Red Component</key>
|
<key>Red Component</key>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>dracula</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>dracula</string>
|
||||||
<key>Ansi 0 Color</key>
|
<key>Ansi 0 Color</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Alpha Component</key>
|
<key>Alpha Component</key>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>gruvboxDark</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>gruvboxDark</string>
|
||||||
<key>Ansi 0 Color</key>
|
<key>Ansi 0 Color</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Alpha Component</key>
|
<key>Alpha Component</key>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>iTerm2SolarizedDark</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>iTerm2SolarizedDark</string>
|
||||||
<key>Ansi 0 Color</key>
|
<key>Ansi 0 Color</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Alpha Component</key>
|
<key>Alpha Component</key>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>iTerm2SolarizedLight</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>iTerm2SolarizedLight</string>
|
||||||
<key>Ansi 0 Color</key>
|
<key>Ansi 0 Color</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Alpha Component</key>
|
<key>Alpha Component</key>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>tomorrowNight</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>tomorrowNight</string>
|
||||||
<key>Ansi 0 Color</key>
|
<key>Ansi 0 Color</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Blue Component</key>
|
<key>Blue Component</key>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>ubuntu</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>ubuntu</string>
|
||||||
<key>Ansi 0 Color</key>
|
<key>Ansi 0 Color</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Blue Component</key>
|
<key>Blue Component</key>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>xcodedark</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>xcodedark</string>
|
||||||
<key>Ansi 0 Color</key>
|
<key>Ansi 0 Color</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Alpha Component</key>
|
<key>Alpha Component</key>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>xcodedarkhc</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>xcodedarkhc</string>
|
||||||
<key>Ansi 0 Color</key>
|
<key>Ansi 0 Color</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Alpha Component</key>
|
<key>Alpha Component</key>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>xcodewwdc</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>xcodewwdc</string>
|
||||||
<key>Ansi 0 Color</key>
|
<key>Ansi 0 Color</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Alpha Component</key>
|
<key>Alpha Component</key>
|
||||||
|
|||||||
@@ -38,6 +38,8 @@
|
|||||||
A96BE6A02E10846B00C0FEE9 /* dracula.plist in Resources */ = {isa = PBXBuildFile; fileRef = A96BE68E2E10846B00C0FEE9 /* dracula.plist */; };
|
A96BE6A02E10846B00C0FEE9 /* dracula.plist in Resources */ = {isa = PBXBuildFile; fileRef = A96BE68E2E10846B00C0FEE9 /* dracula.plist */; };
|
||||||
A96BE6A12E10846B00C0FEE9 /* catppuccinFrappe.plist in Resources */ = {isa = PBXBuildFile; fileRef = A96BE68C2E10846B00C0FEE9 /* catppuccinFrappe.plist */; };
|
A96BE6A12E10846B00C0FEE9 /* catppuccinFrappe.plist in Resources */ = {isa = PBXBuildFile; fileRef = A96BE68C2E10846B00C0FEE9 /* catppuccinFrappe.plist */; };
|
||||||
A96BE6A22E10846B00C0FEE9 /* xcodewwdc.plist in Resources */ = {isa = PBXBuildFile; fileRef = A96BE6962E10846B00C0FEE9 /* xcodewwdc.plist */; };
|
A96BE6A22E10846B00C0FEE9 /* xcodewwdc.plist in Resources */ = {isa = PBXBuildFile; fileRef = A96BE6962E10846B00C0FEE9 /* xcodewwdc.plist */; };
|
||||||
|
A96BE6A42E113D9400C0FEE9 /* ThemeCodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96BE6A32E113D9400C0FEE9 /* ThemeCodable.swift */; };
|
||||||
|
A96BE6A62E113DB000C0FEE9 /* ColorCodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96BE6A52E113DB000C0FEE9 /* ColorCodable.swift */; };
|
||||||
A96C6A8A2E0C0B1100F377FE /* SSHState.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96C6A892E0C0B1100F377FE /* SSHState.swift */; };
|
A96C6A8A2E0C0B1100F377FE /* SSHState.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96C6A892E0C0B1100F377FE /* SSHState.swift */; };
|
||||||
A96C6AFE2E0C43B600F377FE /* Keypair.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96C6AFD2E0C43B600F377FE /* Keypair.swift */; };
|
A96C6AFE2E0C43B600F377FE /* Keypair.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96C6AFD2E0C43B600F377FE /* Keypair.swift */; };
|
||||||
A96C6B002E0C45FE00F377FE /* KeyDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96C6AFF2E0C45FE00F377FE /* KeyDetailView.swift */; };
|
A96C6B002E0C45FE00F377FE /* KeyDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96C6AFF2E0C45FE00F377FE /* KeyDetailView.swift */; };
|
||||||
@@ -129,6 +131,8 @@
|
|||||||
A96BE6942E10846B00C0FEE9 /* xcodedark.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = xcodedark.plist; sourceTree = "<group>"; };
|
A96BE6942E10846B00C0FEE9 /* xcodedark.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = xcodedark.plist; sourceTree = "<group>"; };
|
||||||
A96BE6952E10846B00C0FEE9 /* xcodedarkhc.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = xcodedarkhc.plist; sourceTree = "<group>"; };
|
A96BE6952E10846B00C0FEE9 /* xcodedarkhc.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = xcodedarkhc.plist; sourceTree = "<group>"; };
|
||||||
A96BE6962E10846B00C0FEE9 /* xcodewwdc.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = xcodewwdc.plist; sourceTree = "<group>"; };
|
A96BE6962E10846B00C0FEE9 /* xcodewwdc.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = xcodewwdc.plist; sourceTree = "<group>"; };
|
||||||
|
A96BE6A32E113D9400C0FEE9 /* ThemeCodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeCodable.swift; sourceTree = "<group>"; };
|
||||||
|
A96BE6A52E113DB000C0FEE9 /* ColorCodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorCodable.swift; sourceTree = "<group>"; };
|
||||||
A96C6A892E0C0B1100F377FE /* SSHState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSHState.swift; sourceTree = "<group>"; };
|
A96C6A892E0C0B1100F377FE /* SSHState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSHState.swift; sourceTree = "<group>"; };
|
||||||
A96C6AFD2E0C43B600F377FE /* Keypair.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Keypair.swift; sourceTree = "<group>"; };
|
A96C6AFD2E0C43B600F377FE /* Keypair.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Keypair.swift; sourceTree = "<group>"; };
|
||||||
A96C6AFF2E0C45FE00F377FE /* KeyDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyDetailView.swift; sourceTree = "<group>"; };
|
A96C6AFF2E0C45FE00F377FE /* KeyDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyDetailView.swift; sourceTree = "<group>"; };
|
||||||
@@ -372,6 +376,8 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
A9D819282E0E904200442D38 /* Theme.swift */,
|
A9D819282E0E904200442D38 /* Theme.swift */,
|
||||||
|
A96BE6A32E113D9400C0FEE9 /* ThemeCodable.swift */,
|
||||||
|
A96BE6A52E113DB000C0FEE9 /* ColorCodable.swift */,
|
||||||
);
|
);
|
||||||
path = Themes;
|
path = Themes;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -550,7 +556,9 @@
|
|||||||
A98554632E0587DF009051BD /* HostsView.swift in Sources */,
|
A98554632E0587DF009051BD /* HostsView.swift in Sources */,
|
||||||
A96C6A8A2E0C0B1100F377FE /* SSHState.swift in Sources */,
|
A96C6A8A2E0C0B1100F377FE /* SSHState.swift in Sources */,
|
||||||
A9DA97732E0D40C100142DDC /* SymbolPreview.swift in Sources */,
|
A9DA97732E0D40C100142DDC /* SymbolPreview.swift in Sources */,
|
||||||
|
A96BE6A62E113DB000C0FEE9 /* ColorCodable.swift in Sources */,
|
||||||
A92538C82DEE0742007E0A18 /* ContentView.swift in Sources */,
|
A92538C82DEE0742007E0A18 /* ContentView.swift in Sources */,
|
||||||
|
A96BE6A42E113D9400C0FEE9 /* ThemeCodable.swift in Sources */,
|
||||||
A93143C02DF61B3200FCD5DB /* Host.swift in Sources */,
|
A93143C02DF61B3200FCD5DB /* Host.swift in Sources */,
|
||||||
A9B15A9A2E0ABA0400F66E02 /* DialogView.swift in Sources */,
|
A9B15A9A2E0ABA0400F66E02 /* DialogView.swift in Sources */,
|
||||||
A92538C92DEE0742007E0A18 /* ShhShellApp.swift in Sources */,
|
A92538C92DEE0742007E0A18 /* ShhShellApp.swift in Sources */,
|
||||||
|
|||||||
@@ -19,25 +19,22 @@ class HostsManager: ObservableObject, @unchecked Sendable {
|
|||||||
init() {
|
init() {
|
||||||
loadHosts()
|
loadHosts()
|
||||||
loadThemes()
|
loadThemes()
|
||||||
print(selectedTheme == Theme.defaultTheme)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadThemes() {
|
func loadThemes() {
|
||||||
guard let dataTheme = userDefaults.data(forKey: "themes") else { return }
|
guard let dataTheme = userDefaults.data(forKey: "themes") else { return }
|
||||||
guard let dataThemeNames = userDefaults.data(forKey: "themeNames") else { return }
|
|
||||||
|
|
||||||
guard let decodedThemes = try? JSONDecoder().decode([ThemeCodable].self, from: dataTheme) else { return }
|
guard let decodedThemes = try? JSONDecoder().decode([ThemeCodable].self, from: dataTheme) else { return }
|
||||||
guard let decodedThemeNames = try? JSONDecoder().decode([String].self, from: dataThemeNames) else { return }
|
|
||||||
|
|
||||||
for index in 0..<decodedThemes.count {
|
for index in 0..<decodedThemes.count {
|
||||||
guard let encoded = try? JSONEncoder().encode(decodedThemes[index]) else { return }
|
guard let encoded = try? JSONEncoder().encode(decodedThemes[index]) else { return }
|
||||||
guard let synthedTheme = Theme.decodeTheme(name: decodedThemeNames[index], data: encoded) else { return }
|
guard let synthedTheme = Theme.decodeTheme(data: encoded) else { return }
|
||||||
self.themes.append(synthedTheme)
|
self.themes.append(synthedTheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
guard let dataSelTheme = userDefaults.data(forKey: "selectedTheme") else { return }
|
guard let dataSelTheme = userDefaults.data(forKey: "selectedTheme") else { return }
|
||||||
guard let decodedSelTheme = Theme.decodeTheme(name: "", data: dataSelTheme) else { return }
|
guard let decodedSelTheme = Theme.decodeTheme(data: dataSelTheme) else { return }
|
||||||
//name doesnt matter
|
//name doesnt matter
|
||||||
self.selectedTheme = decodedSelTheme
|
self.selectedTheme = decodedSelTheme
|
||||||
}
|
}
|
||||||
@@ -46,9 +43,8 @@ class HostsManager: ObservableObject, @unchecked Sendable {
|
|||||||
guard let fromUrl else { return }
|
guard let fromUrl else { return }
|
||||||
let task = URLSession.shared.dataTask(with: fromUrl) { data, response, error in
|
let task = URLSession.shared.dataTask(with: fromUrl) { data, response, error in
|
||||||
guard let data else { return }
|
guard let data else { return }
|
||||||
let name = fromUrl.lastPathComponent.replacingOccurrences(of: ".itermcolors", with: "")
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.importTheme(name: name, data: data)
|
self.importTheme(data: data, fromUrl: fromUrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +53,6 @@ class HostsManager: ObservableObject, @unchecked Sendable {
|
|||||||
|
|
||||||
func selectTheme(_ selectedTheme: Theme) {
|
func selectTheme(_ selectedTheme: Theme) {
|
||||||
withAnimation { self.selectedTheme = selectedTheme }
|
withAnimation { self.selectedTheme = selectedTheme }
|
||||||
print("selected: \(selectedTheme.name) \(selectedTheme.id)")
|
|
||||||
saveThemes()
|
saveThemes()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +60,7 @@ class HostsManager: ObservableObject, @unchecked Sendable {
|
|||||||
var themeInQWithSameID = themeInQuestion
|
var themeInQWithSameID = themeInQuestion
|
||||||
themeInQWithSameID.id = selectedTheme.id
|
themeInQWithSameID.id = selectedTheme.id
|
||||||
|
|
||||||
return themeInQuestion.id == self.selectedTheme.id
|
return themeInQWithSameID == self.selectedTheme
|
||||||
}
|
}
|
||||||
|
|
||||||
func renameTheme(_ theme: Theme?, to newName: String) {
|
func renameTheme(_ theme: Theme?, to newName: String) {
|
||||||
@@ -86,9 +81,10 @@ class HostsManager: ObservableObject, @unchecked Sendable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
func importTheme(name: String, data: Data?) {
|
func importTheme(data: Data?, fromUrl: URL? = nil) {
|
||||||
guard let data else { return }
|
guard let data else { return }
|
||||||
guard let theme = Theme.decodeTheme(name: name, data: data) else { return }
|
guard var theme = Theme.decodeTheme(data: data) else { return }
|
||||||
|
theme.name = fromUrl?.lastPathComponent.replacingOccurrences(of: ".itermcolors", with: "") ?? ""
|
||||||
self.themes.append(theme)
|
self.themes.append(theme)
|
||||||
saveThemes()
|
saveThemes()
|
||||||
}
|
}
|
||||||
@@ -97,17 +93,11 @@ class HostsManager: ObservableObject, @unchecked Sendable {
|
|||||||
let encoder = JSONEncoder()
|
let encoder = JSONEncoder()
|
||||||
// map the theme to themecodable
|
// map the theme to themecodable
|
||||||
guard let encodedThemes = try? encoder.encode(themes.map({$0.themeCodable})) else { return }
|
guard let encodedThemes = try? encoder.encode(themes.map({$0.themeCodable})) else { return }
|
||||||
//map the themes to get their names
|
|
||||||
guard let encodedThemeNames = try? encoder.encode(themes.map{$0.name}) else { return }
|
|
||||||
|
|
||||||
userDefaults.set(encodedThemes, forKey: "themes")
|
userDefaults.set(encodedThemes, forKey: "themes")
|
||||||
userDefaults.set(encodedThemeNames, forKey: "themeNames")
|
|
||||||
|
|
||||||
guard let encodedSelectedTheme = try? encoder.encode(selectedTheme.themeCodable) else { return }
|
guard let encodedSelectedTheme = try? encoder.encode(selectedTheme.themeCodable) else { return }
|
||||||
userDefaults.set(encodedSelectedTheme, forKey: "selectedTheme")
|
userDefaults.set(encodedSelectedTheme, forKey: "selectedTheme")
|
||||||
userDefaults.synchronize()
|
userDefaults.synchronize()
|
||||||
print(Theme.decodeTheme(name: "", data: userDefaults.data(forKey: "selectedTheme")))
|
|
||||||
print("saved themes")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getHostIndexMatching(_ hostSearchingFor: Host) -> Int? {
|
func getHostIndexMatching(_ hostSearchingFor: Host) -> Int? {
|
||||||
|
|||||||
57
ShhShell/Themes/ColorCodable.swift
Normal file
57
ShhShell/Themes/ColorCodable.swift
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
//
|
||||||
|
// ColorCodable.swift
|
||||||
|
// ShhShell
|
||||||
|
//
|
||||||
|
// Created by neon443 on 29/06/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import SwiftTerm
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ColorCodable: Codable {
|
||||||
|
var red: Double
|
||||||
|
var green: Double
|
||||||
|
var blue: Double
|
||||||
|
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case red = "Red Component"
|
||||||
|
case green = "Green Component"
|
||||||
|
case blue = "Blue Component"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ColorCodable {
|
||||||
|
var stColor: SwiftTerm.Color {
|
||||||
|
return SwiftTerm.Color(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SwiftTerm.Color {
|
||||||
|
convenience init(_ colorCodable: ColorCodable) {
|
||||||
|
let red = UInt16(colorCodable.red * 65535)
|
||||||
|
let green = UInt16(colorCodable.green * 65535)
|
||||||
|
let blue = UInt16(colorCodable.blue * 65535)
|
||||||
|
self.init(red: red, green: green, blue: blue)
|
||||||
|
}
|
||||||
|
|
||||||
|
var colorCodable: ColorCodable {
|
||||||
|
let red = Double(self.red)/65535
|
||||||
|
let green = Double(self.green)/65535
|
||||||
|
let blue = Double(self.blue)/65535
|
||||||
|
return ColorCodable(red: red, green: green, blue: blue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SwiftTerm.Color {
|
||||||
|
var suiColor: SwiftUI.Color {
|
||||||
|
return Color(uiColor: self.uiColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
var uiColor: UIColor {
|
||||||
|
let red = CGFloat(self.red)/65535
|
||||||
|
let green = CGFloat(self.green)/65535
|
||||||
|
let blue = CGFloat(self.blue)/65535
|
||||||
|
return UIColor(red: red, green: green, blue: blue, alpha: 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ import SwiftTerm
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct Theme: Hashable, Equatable, Identifiable {
|
struct Theme: Hashable, Equatable, Identifiable {
|
||||||
var id: String = UUID().uuidString
|
var id: String
|
||||||
var name: String
|
var name: String
|
||||||
var ansi: [SwiftTerm.Color]
|
var ansi: [SwiftTerm.Color]
|
||||||
var foreground: SwiftTerm.Color
|
var foreground: SwiftTerm.Color
|
||||||
@@ -23,6 +23,7 @@ struct Theme: Hashable, Equatable, Identifiable {
|
|||||||
|
|
||||||
var themeCodable: ThemeCodable {
|
var themeCodable: ThemeCodable {
|
||||||
return ThemeCodable(
|
return ThemeCodable(
|
||||||
|
id: id,
|
||||||
name: name,
|
name: name,
|
||||||
ansi0: ansi[0].colorCodable,
|
ansi0: ansi[0].colorCodable,
|
||||||
ansi1: ansi[1].colorCodable,
|
ansi1: ansi[1].colorCodable,
|
||||||
@@ -50,7 +51,7 @@ struct Theme: Hashable, Equatable, Identifiable {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func decodeTheme(name: String, data: Data?) -> Theme? {
|
static func decodeTheme( data: Data?) -> Theme? {
|
||||||
guard let data else { fatalError() }
|
guard let data else { fatalError() }
|
||||||
|
|
||||||
let plistDecoder = PropertyListDecoder()
|
let plistDecoder = PropertyListDecoder()
|
||||||
@@ -60,18 +61,7 @@ struct Theme: Hashable, Equatable, Identifiable {
|
|||||||
(try? plistDecoder.decode(ThemeCodable.self, from: data)) ??
|
(try? plistDecoder.decode(ThemeCodable.self, from: data)) ??
|
||||||
(try? jsonDecoder.decode(ThemeCodable.self, from: data))
|
(try? jsonDecoder.decode(ThemeCodable.self, from: data))
|
||||||
else { fatalError() }
|
else { fatalError() }
|
||||||
var theme = Theme(
|
return decoded.toTheme()
|
||||||
name: decoded.name ?? name,
|
|
||||||
ansi: decoded.ansi,
|
|
||||||
foreground: Color(decoded.foreground),
|
|
||||||
background: Color(decoded.background),
|
|
||||||
cursor: Color(decoded.cursor),
|
|
||||||
cursorText: Color(decoded.cursorText),
|
|
||||||
bold: Color(decoded.bold),
|
|
||||||
selectedText: Color(decoded.selectedText),
|
|
||||||
selection: Color(decoded.selection)
|
|
||||||
)
|
|
||||||
return theme
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static func decodeLocalTheme(fileName: String) -> Theme? {
|
static func decodeLocalTheme(fileName: String) -> Theme? {
|
||||||
@@ -80,10 +70,7 @@ struct Theme: Hashable, Equatable, Identifiable {
|
|||||||
|
|
||||||
guard let fileContents = try? Data(contentsOf: path) else { return nil }
|
guard let fileContents = try? Data(contentsOf: path) else { return nil }
|
||||||
|
|
||||||
guard var theme = Theme.decodeTheme(name: themeName, data: fileContents) else { return nil }
|
return Theme.decodeTheme(data: fileContents)
|
||||||
theme.name = themeName
|
|
||||||
theme.id = themeName
|
|
||||||
return theme
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static var defaultTheme: Theme {
|
static var defaultTheme: Theme {
|
||||||
@@ -93,6 +80,17 @@ struct Theme: Hashable, Equatable, Identifiable {
|
|||||||
static var builtinThemes: [Theme] {
|
static var builtinThemes: [Theme] {
|
||||||
return ThemesBuiltin.allCases.map({ decodeLocalTheme(fileName: $0.rawValue)! })
|
return ThemesBuiltin.allCases.map({ decodeLocalTheme(fileName: $0.rawValue)! })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static func ==(lhs: Theme, rhs: Theme) -> Bool {
|
||||||
|
// return lhs.ansi == rhs.ansi &&
|
||||||
|
// lhs.foreground == rhs.foreground &&
|
||||||
|
// lhs.background == rhs.background &&
|
||||||
|
// lhs.cursor == rhs.cursor &&
|
||||||
|
// lhs.cursorText == rhs.cursorText &&
|
||||||
|
// lhs.bold == rhs.bold &&
|
||||||
|
// lhs.selectedText == rhs.selectedText &&
|
||||||
|
// lhs.selection == rhs.selection
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ThemesBuiltin: String, CaseIterable, Hashable, Equatable {
|
enum ThemesBuiltin: String, CaseIterable, Hashable, Equatable {
|
||||||
@@ -110,105 +108,3 @@ enum ThemesBuiltin: String, CaseIterable, Hashable, Equatable {
|
|||||||
case gruvboxDark = "gruvboxDark"
|
case gruvboxDark = "gruvboxDark"
|
||||||
case ubuntu = "ubuntu"
|
case ubuntu = "ubuntu"
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ThemeCodable: Codable {
|
|
||||||
var name: String?
|
|
||||||
var ansi0: ColorCodable
|
|
||||||
var ansi1: ColorCodable
|
|
||||||
var ansi2: ColorCodable
|
|
||||||
var ansi3: ColorCodable
|
|
||||||
var ansi4: ColorCodable
|
|
||||||
var ansi5: ColorCodable
|
|
||||||
var ansi6: ColorCodable
|
|
||||||
var ansi7: ColorCodable
|
|
||||||
var ansi8: ColorCodable
|
|
||||||
var ansi9: ColorCodable
|
|
||||||
var ansi10: ColorCodable
|
|
||||||
var ansi11: ColorCodable
|
|
||||||
var ansi12: ColorCodable
|
|
||||||
var ansi13: ColorCodable
|
|
||||||
var ansi14: ColorCodable
|
|
||||||
var ansi15: ColorCodable
|
|
||||||
var foreground: ColorCodable
|
|
||||||
var background: ColorCodable
|
|
||||||
var cursor: ColorCodable
|
|
||||||
var cursorText: ColorCodable
|
|
||||||
var bold: ColorCodable
|
|
||||||
var selectedText: ColorCodable
|
|
||||||
var selection: ColorCodable
|
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
|
||||||
case ansi0 = "Ansi 0 Color"
|
|
||||||
case ansi1 = "Ansi 1 Color"
|
|
||||||
case ansi2 = "Ansi 2 Color"
|
|
||||||
case ansi3 = "Ansi 3 Color"
|
|
||||||
case ansi4 = "Ansi 4 Color"
|
|
||||||
case ansi5 = "Ansi 5 Color"
|
|
||||||
case ansi6 = "Ansi 6 Color"
|
|
||||||
case ansi7 = "Ansi 7 Color"
|
|
||||||
case ansi8 = "Ansi 8 Color"
|
|
||||||
case ansi9 = "Ansi 9 Color"
|
|
||||||
case ansi10 = "Ansi 10 Color"
|
|
||||||
case ansi11 = "Ansi 11 Color"
|
|
||||||
case ansi12 = "Ansi 12 Color"
|
|
||||||
case ansi13 = "Ansi 13 Color"
|
|
||||||
case ansi14 = "Ansi 14 Color"
|
|
||||||
case ansi15 = "Ansi 15 Color"
|
|
||||||
case foreground = "Foreground Color"
|
|
||||||
case background = "Background Color"
|
|
||||||
case cursor = "Cursor Color"
|
|
||||||
case cursorText = "Cursor Text Color"
|
|
||||||
case bold = "Bold Color"
|
|
||||||
case selectedText = "Selected Text Color"
|
|
||||||
case selection = "Selection Color"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension ThemeCodable {
|
|
||||||
var ansi: [SwiftTerm.Color] {
|
|
||||||
let arr = [ansi0, ansi1, ansi2, ansi3, ansi4, ansi5, ansi6, ansi7, ansi8, ansi9, ansi10, ansi11, ansi12, ansi13, ansi14, ansi15]
|
|
||||||
return arr.map(SwiftTerm.Color.init)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ColorCodable: Codable {
|
|
||||||
var red: Double
|
|
||||||
var green: Double
|
|
||||||
var blue: Double
|
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
|
||||||
case red = "Red Component"
|
|
||||||
case green = "Green Component"
|
|
||||||
case blue = "Blue Component"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extension SwiftTerm.Color {
|
|
||||||
convenience init(_ colorCodable: ColorCodable) {
|
|
||||||
let red = UInt16(colorCodable.red * 65535)
|
|
||||||
let green = UInt16(colorCodable.green * 65535)
|
|
||||||
let blue = UInt16(colorCodable.blue * 65535)
|
|
||||||
self.init(red: red, green: green, blue: blue)
|
|
||||||
}
|
|
||||||
|
|
||||||
var colorCodable: ColorCodable {
|
|
||||||
let red = Double(self.red)/65535
|
|
||||||
let green = Double(self.green)/65535
|
|
||||||
let blue = Double(self.blue)/65535
|
|
||||||
return ColorCodable(red: red, green: green, blue: blue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SwiftTerm.Color {
|
|
||||||
var suiColor: SwiftUI.Color {
|
|
||||||
return Color(uiColor: self.uiColor)
|
|
||||||
}
|
|
||||||
|
|
||||||
var uiColor: UIColor {
|
|
||||||
let red = CGFloat(self.red)/65535
|
|
||||||
let green = CGFloat(self.green)/65535
|
|
||||||
let blue = CGFloat(self.blue)/65535
|
|
||||||
return UIColor(red: red, green: green, blue: blue, alpha: 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
89
ShhShell/Themes/ThemeCodable.swift
Normal file
89
ShhShell/Themes/ThemeCodable.swift
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
//
|
||||||
|
// ThemeCodable.swift
|
||||||
|
// ShhShell
|
||||||
|
//
|
||||||
|
// Created by neon443 on 29/06/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import SwiftTerm
|
||||||
|
|
||||||
|
struct ThemeCodable: Codable {
|
||||||
|
var id: String?
|
||||||
|
var name: String?
|
||||||
|
var ansi0: ColorCodable
|
||||||
|
var ansi1: ColorCodable
|
||||||
|
var ansi2: ColorCodable
|
||||||
|
var ansi3: ColorCodable
|
||||||
|
var ansi4: ColorCodable
|
||||||
|
var ansi5: ColorCodable
|
||||||
|
var ansi6: ColorCodable
|
||||||
|
var ansi7: ColorCodable
|
||||||
|
var ansi8: ColorCodable
|
||||||
|
var ansi9: ColorCodable
|
||||||
|
var ansi10: ColorCodable
|
||||||
|
var ansi11: ColorCodable
|
||||||
|
var ansi12: ColorCodable
|
||||||
|
var ansi13: ColorCodable
|
||||||
|
var ansi14: ColorCodable
|
||||||
|
var ansi15: ColorCodable
|
||||||
|
var foreground: ColorCodable
|
||||||
|
var background: ColorCodable
|
||||||
|
var cursor: ColorCodable
|
||||||
|
var cursorText: ColorCodable
|
||||||
|
var bold: ColorCodable
|
||||||
|
var selectedText: ColorCodable
|
||||||
|
var selection: ColorCodable
|
||||||
|
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case id = "id"
|
||||||
|
case name = "name"
|
||||||
|
case ansi0 = "Ansi 0 Color"
|
||||||
|
case ansi1 = "Ansi 1 Color"
|
||||||
|
case ansi2 = "Ansi 2 Color"
|
||||||
|
case ansi3 = "Ansi 3 Color"
|
||||||
|
case ansi4 = "Ansi 4 Color"
|
||||||
|
case ansi5 = "Ansi 5 Color"
|
||||||
|
case ansi6 = "Ansi 6 Color"
|
||||||
|
case ansi7 = "Ansi 7 Color"
|
||||||
|
case ansi8 = "Ansi 8 Color"
|
||||||
|
case ansi9 = "Ansi 9 Color"
|
||||||
|
case ansi10 = "Ansi 10 Color"
|
||||||
|
case ansi11 = "Ansi 11 Color"
|
||||||
|
case ansi12 = "Ansi 12 Color"
|
||||||
|
case ansi13 = "Ansi 13 Color"
|
||||||
|
case ansi14 = "Ansi 14 Color"
|
||||||
|
case ansi15 = "Ansi 15 Color"
|
||||||
|
case foreground = "Foreground Color"
|
||||||
|
case background = "Background Color"
|
||||||
|
case cursor = "Cursor Color"
|
||||||
|
case cursorText = "Cursor Text Color"
|
||||||
|
case bold = "Bold Color"
|
||||||
|
case selectedText = "Selected Text Color"
|
||||||
|
case selection = "Selection Color"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ThemeCodable {
|
||||||
|
var ansi: [SwiftTerm.Color] {
|
||||||
|
let arr = [ansi0, ansi1, ansi2, ansi3, ansi4, ansi5, ansi6, ansi7, ansi8, ansi9, ansi10, ansi11, ansi12, ansi13, ansi14, ansi15]
|
||||||
|
return arr.map(SwiftTerm.Color.init)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ThemeCodable {
|
||||||
|
func toTheme() -> Theme {
|
||||||
|
return Theme(
|
||||||
|
id: id ?? UUID().uuidString,
|
||||||
|
name: self.name ?? "",
|
||||||
|
ansi: self.ansi,
|
||||||
|
foreground: self.foreground.stColor,
|
||||||
|
background: self.background.stColor,
|
||||||
|
cursor: self.cursor.stColor,
|
||||||
|
cursorText: self.cursorText.stColor,
|
||||||
|
bold: self.bold.stColor,
|
||||||
|
selectedText: self.selectedText.stColor,
|
||||||
|
selection: self.selection.stColor
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -83,6 +83,7 @@ struct ThemeManagerView: View {
|
|||||||
ThemePreview(hostsManager: hostsManager, theme: theme)
|
ThemePreview(hostsManager: hostsManager, theme: theme)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.animation(.default, value: hostsManager.themes)
|
||||||
}
|
}
|
||||||
.scrollIndicators(.hidden)
|
.scrollIndicators(.hidden)
|
||||||
.fixedSize(horizontal: false, vertical: true)
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
|
|||||||
@@ -63,6 +63,6 @@ struct ThemePreview: View {
|
|||||||
|
|
||||||
ThemePreview(
|
ThemePreview(
|
||||||
hostsManager: HostsManager(),
|
hostsManager: HostsManager(),
|
||||||
theme: Theme.decodeTheme(name: "theme", data: data)!
|
theme: Theme.decodeTheme(data: data)!
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user