added themes to hostsmanager

added loadthemes
added savethemes
theme is now identifieable
theme has a computed property themecodable to make it easier to convert
extended swiftterm.color to have a colorCodabel property
adding themes amanger ui
This commit is contained in:
neon443
2025-06-27 10:59:53 +01:00
parent f14492d3fe
commit 56289f0f6d
5 changed files with 109 additions and 5 deletions

View File

@@ -13,15 +13,39 @@ class HostsManager: ObservableObject, @unchecked Sendable {
private let userDefaults = NSUbiquitousKeyValueStore.default
@Published var savedHosts: [Host] = []
@Published var themes: [Theme] = []
init() {
loadSavedHosts()
}
/// get the index of a matching host in saved hosts
/// - Parameter host: input a host
/// - Returns: if an item in savedHosts has a matching uuid to the parameter, it returns the index
/// else returns nil
func loadThemes() {
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 decodedThemeNames = try? JSONDecoder().decode([String].self, from: dataThemeNames) else { return }
for index in 0..<decodedThemes.count {
if let encoded = try? JSONEncoder().encode(decodedThemes) {
if let synthedTheme = Theme.fromiTermColors(name: decodedThemeNames[index], data: encoded) {
self.themes.append(synthedTheme)
}
}
}
}
func saveThemes() {
let encoder = JSONEncoder()
guard let encodedThemes = try? encoder.encode(themes.map({$0.themeCodable})) else { return }
guard let encodedThemeNames = try? encoder.encode(themes.map{$0.name}) else { return }
userDefaults.set(encodedThemes, forKey: "themes")
userDefaults.set(encodedThemeNames, forKey: "themeNames")
userDefaults.synchronize()
}
func getHostIndexMatching(_ hostSearchingFor: Host) -> Int? {
if let index = savedHosts.firstIndex(where: { $0.id == hostSearchingFor.id }) {
return index

View File

@@ -9,7 +9,8 @@ import Foundation
import SwiftTerm
import SwiftUI
struct Theme: Hashable, Equatable {
struct Theme: Hashable, Equatable, Identifiable {
var id = UUID()
var name: String
var ansi: [SwiftTerm.Color]
var foreground: SwiftTerm.Color
@@ -20,6 +21,34 @@ struct Theme: Hashable, Equatable {
var selectedText: SwiftTerm.Color
var selection: SwiftTerm.Color
var themeCodable: ThemeCodable {
return ThemeCodable(
ansi0: ansi[0].colorCodable,
ansi1: ansi[1].colorCodable,
ansi2: ansi[2].colorCodable,
ansi3: ansi[3].colorCodable,
ansi4: ansi[4].colorCodable,
ansi5: ansi[5].colorCodable,
ansi6: ansi[6].colorCodable,
ansi7: ansi[7].colorCodable,
ansi8: ansi[8].colorCodable,
ansi9: ansi[9].colorCodable,
ansi10: ansi[10].colorCodable,
ansi11: ansi[11].colorCodable,
ansi12: ansi[12].colorCodable,
ansi13: ansi[13].colorCodable,
ansi14: ansi[14].colorCodable,
ansi15: ansi[15].colorCodable,
foreground: foreground.colorCodable,
background: background.colorCodable,
cursor: cursor.colorCodable,
cursorText: cursorText.colorCodable,
bold: bold.colorCodable,
selectedText: selectedText.colorCodable,
selection: selection.colorCodable
)
}
static func fromiTermColors(name: String, data: Data?) -> Theme? {
guard let data else { return nil }
@@ -122,6 +151,13 @@ extension SwiftTerm.Color {
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 {

View File

@@ -65,6 +65,14 @@ struct HostsView: View {
.onMove(perform: {
hostsManager.moveHost(from: $0, to: $1)
})
Section() {
NavigationLink {
ThemesView(hostsManager: HostsManager())
} label: {
Label("Themes", systemImage: "swatchpalette")
}
}
}
.transition(.opacity)
.toolbar {

View File

@@ -0,0 +1,24 @@
//
// ThemesView.swift
// ShhShell
//
// Created by neon443 on 27/06/2025.
//
import SwiftUI
struct ThemesView: View {
@ObservedObject var hostsManager: HostsManager
var body: some View {
ForEach(hostsManager.themes) { theme in
ZStack {
RoundedRectangle(cornerRadius: 10)
}
}
}
}
#Preview {
ThemesView(hostsManager: HostsManager())
}