From 3698232a5173076c267e9e159e59fa9331f16dd3 Mon Sep 17 00:00:00 2001 From: neon443 <69979447+neon443@users.noreply.github.com> Date: Fri, 27 Jun 2025 20:48:41 +0100 Subject: [PATCH] added thememanager view and thempreviw it uses a lazyhgrid --- ShhShell.xcodeproj/project.pbxproj | 12 ++- ShhShell/Views/Hosts/HostsView.swift | 2 +- ShhShell/Views/Themes/ThemeManagerView.swift | 79 +++++++++++++++++ ShhShell/Views/Themes/ThemePreview.swift | 50 +++++++++++ ShhShell/Views/Themes/ThemesView.swift | 91 -------------------- 5 files changed, 138 insertions(+), 96 deletions(-) create mode 100644 ShhShell/Views/Themes/ThemeManagerView.swift create mode 100644 ShhShell/Views/Themes/ThemePreview.swift delete mode 100644 ShhShell/Views/Themes/ThemesView.swift diff --git a/ShhShell.xcodeproj/project.pbxproj b/ShhShell.xcodeproj/project.pbxproj index 0c30221..b064134 100644 --- a/ShhShell.xcodeproj/project.pbxproj +++ b/ShhShell.xcodeproj/project.pbxproj @@ -40,7 +40,8 @@ A9C4140C2E096DB7005E3047 /* SSHError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C4140B2E096DB7005E3047 /* SSHError.swift */; }; A9C897EF2DF1A9A400EF9A5F /* SSHHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C897EE2DF1A9A400EF9A5F /* SSHHandler.swift */; }; A9D819292E0E904200442D38 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D819282E0E904200442D38 /* Theme.swift */; }; - A9D8192D2E0E9EB500442D38 /* ThemesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D8192C2E0E9EB500442D38 /* ThemesView.swift */; }; + A9D8192D2E0E9EB500442D38 /* ThemeManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D8192C2E0E9EB500442D38 /* ThemeManagerView.swift */; }; + A9D8192F2E0F1BEE00442D38 /* ThemePreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D8192E2E0F1BEE00442D38 /* ThemePreview.swift */; }; A9DA97712E0D30ED00142DDC /* HostSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9DA97702E0D30ED00142DDC /* HostSymbol.swift */; }; A9DA97732E0D40C100142DDC /* SymbolPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9DA97722E0D40C100142DDC /* SymbolPreview.swift */; }; /* End PBXBuildFile section */ @@ -115,7 +116,8 @@ A9C4140B2E096DB7005E3047 /* SSHError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSHError.swift; sourceTree = ""; }; A9C897EE2DF1A9A400EF9A5F /* SSHHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSHHandler.swift; sourceTree = ""; }; A9D819282E0E904200442D38 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; }; - A9D8192C2E0E9EB500442D38 /* ThemesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemesView.swift; sourceTree = ""; }; + A9D8192C2E0E9EB500442D38 /* ThemeManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeManagerView.swift; sourceTree = ""; }; + A9D8192E2E0F1BEE00442D38 /* ThemePreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemePreview.swift; sourceTree = ""; }; A9DA97702E0D30ED00142DDC /* HostSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HostSymbol.swift; sourceTree = ""; }; A9DA97722E0D40C100142DDC /* SymbolPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SymbolPreview.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -327,7 +329,8 @@ A9D8192B2E0E9EA400442D38 /* Themes */ = { isa = PBXGroup; children = ( - A9D8192C2E0E9EB500442D38 /* ThemesView.swift */, + A9D8192C2E0E9EB500442D38 /* ThemeManagerView.swift */, + A9D8192E2E0F1BEE00442D38 /* ThemePreview.swift */, ); path = Themes; sourceTree = ""; @@ -474,11 +477,12 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + A9D8192F2E0F1BEE00442D38 /* ThemePreview.swift in Sources */, A96C6B022E0C49E800F377FE /* CenteredLabel.swift in Sources */, A923172F2E08851200ECE1E6 /* ShellView.swift in Sources */, A985545F2E056EDD009051BD /* KeychainLayer.swift in Sources */, A9D819292E0E904200442D38 /* Theme.swift in Sources */, - A9D8192D2E0E9EB500442D38 /* ThemesView.swift in Sources */, + A9D8192D2E0E9EB500442D38 /* ThemeManagerView.swift in Sources */, A93143C62DF61FE300FCD5DB /* ViewModifiers.swift in Sources */, A98554632E0587DF009051BD /* HostsView.swift in Sources */, A96C6A8A2E0C0B1100F377FE /* SSHState.swift in Sources */, diff --git a/ShhShell/Views/Hosts/HostsView.swift b/ShhShell/Views/Hosts/HostsView.swift index 9c3069b..a53113c 100644 --- a/ShhShell/Views/Hosts/HostsView.swift +++ b/ShhShell/Views/Hosts/HostsView.swift @@ -68,7 +68,7 @@ struct HostsView: View { Section() { NavigationLink { - ThemesView(hostsManager: hostsManager) + ThemeManagerView(hostsManager: hostsManager) } label: { Label("Themes", systemImage: "swatchpalette") } diff --git a/ShhShell/Views/Themes/ThemeManagerView.swift b/ShhShell/Views/Themes/ThemeManagerView.swift new file mode 100644 index 0000000..040e4d3 --- /dev/null +++ b/ShhShell/Views/Themes/ThemeManagerView.swift @@ -0,0 +1,79 @@ +// +// ThemesView.swift +// ShhShell +// +// Created by neon443 on 27/06/2025. +// + +import SwiftUI + +struct ThemeManagerView: View { + @ObservedObject var hostsManager: HostsManager + + @State var showAlert: Bool = false + @State var importURL: String = "" + @State var toImportName: String = "" + + let grid = GridItem( + .adaptive(minimum: 80, maximum: 150), + spacing: 0, + alignment: .center + ) + + var body: some View { + GeometryReader { geo in + NavigationStack { + let columns = Int(geo.size.width/150) + ScrollView(.horizontal) { + LazyHGrid(rows: Array(repeating: grid, count: columns), alignment: .center, spacing: 0) { + ForEach(hostsManager.themes) { theme in + ThemePreview(theme: theme) + } + } + } + .scrollIndicators(.hidden) + .alert("Enter URL", isPresented: $showAlert) { + TextField("", text: $importURL, prompt: Text("URL")) + Button() { + hostsManager.downloadTheme(fromUrl: URL(string: importURL)) + importURL = "" + } label: { + Label("Import", systemImage: "square.and.arrow.down") + } + } + .toolbar { + ToolbarItem(placement: .confirmationAction) { + Button() { + if let pasteboard = UIPasteboard().string { + hostsManager.importTheme(name: toImportName, data: pasteboard.data(using: .utf8)) + } + } label: { + Label("Import", systemImage: "plus") + } + } + ToolbarItem() { + Button() { + UIApplication.shared.open(URL(string: "https://iterm2colorschemes.com")!) + } label: { + Label("Open themes site", systemImage: "safari") + } + } + ToolbarItem() { + Button() { + showAlert.toggle() + } label: { + Label("From URL", systemImage: "link") + } + } + } + } + } + } +} + +#Preview { + ThemeManagerView( + hostsManager: HostsManager(), + importURL: "https://raw.githubusercontent.com/mbadolato/iTerm2-Color-Schemes/master/schemes/catppuccin-frappe.itermcolors" + ) +} diff --git a/ShhShell/Views/Themes/ThemePreview.swift b/ShhShell/Views/Themes/ThemePreview.swift new file mode 100644 index 0000000..94d4737 --- /dev/null +++ b/ShhShell/Views/Themes/ThemePreview.swift @@ -0,0 +1,50 @@ +// +// ThemePreview.swift +// ShhShell +// +// Created by neon443 on 27/06/2025. +// + +import SwiftUI + +struct ThemePreview: View { + @State var theme: Theme + + var body: some View { + ZStack(alignment: .center) { + RoundedRectangle(cornerRadius: 5) + .fill(theme.background.suiColor) + VStack(alignment: .leading) { + Text(theme.name) + .foregroundStyle(theme.foreground.suiColor) + .font(.headline) + HStack { + ForEach(0..<8, id: \.self) { index in + Rectangle() + .frame(width: 15, height: 15) + .foregroundStyle(theme.ansi[index].suiColor) + } + } + HStack { + ForEach(8..<16, id: \.self) { index in + Rectangle() + .frame(width: 15, height: 15) + .foregroundStyle(theme.ansi[index].suiColor) + } + } + } + .padding(5) + } + .fixedSize() + .frame(maxWidth: 150, maxHeight: 80) + } +} + +#Preview { + let url = URL(string: "https://raw.githubusercontent.com/mbadolato/iTerm2-Color-Schemes/master/schemes/catppuccin-frappe.itermcolors")! + let data = try! Data(contentsOf: url) + + ThemePreview( + theme: Theme.decodeTheme(name: "theme", data: data)! + ) +} diff --git a/ShhShell/Views/Themes/ThemesView.swift b/ShhShell/Views/Themes/ThemesView.swift deleted file mode 100644 index fc0a591..0000000 --- a/ShhShell/Views/Themes/ThemesView.swift +++ /dev/null @@ -1,91 +0,0 @@ -// -// ThemesView.swift -// ShhShell -// -// Created by neon443 on 27/06/2025. -// - -import SwiftUI - -struct ThemesView: View { - @ObservedObject var hostsManager: HostsManager - - @State var showAlert: Bool = false - @State var importURL: String = "" - @State var toImportName: String = "" - - var body: some View { - NavigationStack { - List { - ScrollView(.horizontal) { - HStack { - ForEach(hostsManager.themes) { theme in - ZStack(alignment: .center) { - RoundedRectangle(cornerRadius: 10) - .fill(theme.background.suiColor) - VStack(alignment: .leading) { - Text(theme.name) - .foregroundStyle(theme.foreground.suiColor) - HStack { - ForEach(0..<8, id: \.self) { index in - Rectangle() - .frame(width: 12, height: 12) - .foregroundStyle(theme.ansi[index].suiColor) - } - } - HStack { - ForEach(8..<16, id: \.self) { index in - Rectangle() - .frame(width: 12, height: 12) - .foregroundStyle(theme.ansi[index].suiColor) - } - } - } - } - .frame(width: 100, height: 100) - } - } - } - .scrollIndicators(.hidden) - } - .alert("Enter URL of your theme", isPresented: $showAlert) { - TextField("", text: $importURL, prompt: Text("from iterm2colorschemes.com")) - Button() { - hostsManager.downloadTheme(fromUrl: URL(string: importURL)) - importURL = "" - } label: { - Label("Import", systemImage: "square.and.arrow.down") - } - } - .toolbar { - ToolbarItem(placement: .confirmationAction) { - Button() { - if let pasteboard = UIPasteboard().string { - hostsManager.importTheme(name: toImportName, data: pasteboard.data(using: .utf8)) - } - } label: { - Label("Import", systemImage: "plus") - } - } - ToolbarItem() { - Button() { - UIApplication.shared.open(URL(string: "https://iterm2colorschemes.com")!) - } label: { - Label("Open themes site", systemImage: "safari") - } - } - ToolbarItem() { - Button() { - showAlert.toggle() - } label: { - Label("From URL", systemImage: "link") - } - } - } - } - } -} - -#Preview { - ThemesView(hostsManager: HostsManager()) -}