diff --git a/ShhShell.xcodeproj/project.pbxproj b/ShhShell.xcodeproj/project.pbxproj index bd40d1a..43d01f0 100644 --- a/ShhShell.xcodeproj/project.pbxproj +++ b/ShhShell.xcodeproj/project.pbxproj @@ -96,6 +96,7 @@ A9C897EF2DF1A9A400EF9A5F /* SSHHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C897EE2DF1A9A400EF9A5F /* SSHHandler.swift */; }; A9CC786B2E4E681400FAEE58 /* RecentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9CC786A2E4E681400FAEE58 /* RecentsView.swift */; }; A9CC786D2E4F534600FAEE58 /* History.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9CC786C2E4F534600FAEE58 /* History.swift */; }; + A9D45DD92E7204FF00BA9E4A /* GlassButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D45DD82E7204FF00BA9E4A /* GlassButton.swift */; }; A9D819292E0E904200442D38 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D819282E0E904200442D38 /* Theme.swift */; }; A9D8192D2E0E9EB500442D38 /* ThemeManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D8192C2E0E9EB500442D38 /* ThemeManagerView.swift */; }; A9D8192F2E0F1BEE00442D38 /* ThemeButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D8192E2E0F1BEE00442D38 /* ThemeButton.swift */; }; @@ -238,6 +239,7 @@ A9C897EE2DF1A9A400EF9A5F /* SSHHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSHHandler.swift; sourceTree = ""; }; A9CC786A2E4E681400FAEE58 /* RecentsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentsView.swift; sourceTree = ""; }; A9CC786C2E4F534600FAEE58 /* History.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = History.swift; sourceTree = ""; }; + A9D45DD82E7204FF00BA9E4A /* GlassButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlassButton.swift; sourceTree = ""; }; A9D819282E0E904200442D38 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; }; A9D8192C2E0E9EB500442D38 /* ThemeManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeManagerView.swift; sourceTree = ""; }; A9D8192E2E0F1BEE00442D38 /* ThemeButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeButton.swift; sourceTree = ""; }; @@ -546,6 +548,7 @@ A93143C52DF61FE300FCD5DB /* ViewModifiers.swift */, A96C90A02E12B87900724253 /* TextBox.swift */, A9835C3B2E17CCA500969508 /* TrafficLights.swift */, + A9D45DD82E7204FF00BA9E4A /* GlassButton.swift */, ); path = Misc; sourceTree = ""; @@ -908,6 +911,7 @@ A9FD37552E143D23005319A8 /* SecKeyConvertible.swift in Sources */, A94B832F2E5B929C00EBA09C /* Backgrounder.swift in Sources */, A96C6AFE2E0C43B600F377FE /* Keypair.swift in Sources */, + A9D45DD92E7204FF00BA9E4A /* GlassButton.swift in Sources */, A90B38322E3E8FC9002B56FC /* AboutView.swift in Sources */, A9C4140C2E096DB7005E3047 /* SSHError.swift in Sources */, A96BE6AA2E116EC000C0FEE9 /* TerminalViewContainer.swift in Sources */, diff --git a/ShhShell/Views/About/AboutView.swift b/ShhShell/Views/About/AboutView.swift index 41f318c..7ef3874 100644 --- a/ShhShell/Views/About/AboutView.swift +++ b/ShhShell/Views/About/AboutView.swift @@ -14,8 +14,7 @@ struct AboutView: View { ZStack { hostsManager.selectedTheme.background.suiColor.opacity(0.7) .ignoresSafeArea(.all) -// List { - VStack(alignment: .leading) { + VStack { hostsManager.settings.appIcon.image .resizable().scaledToFit() .frame(width: 100) @@ -32,7 +31,7 @@ struct AboutView: View { } .padding(.bottom) - Section("Thanks to") { + HStack(spacing: 10) { Link(destination: URL(string: "https://libssh.org")!) { Text("LibSSH") .padding(10) @@ -57,7 +56,7 @@ struct AboutView: View { VStack { Text("Shader Playground") .bold() - Text("This is a collection of all the shaders I made while learning!") + Text("A collection of shaders I made while learning!") .font(.caption2) } } @@ -65,8 +64,6 @@ struct AboutView: View { .transition(.scale) .frame(maxWidth: .infinity) .padding() -// } -// .scrollContentBackground(.hidden) } } } diff --git a/ShhShell/Views/Fonts/FontManagerView.swift b/ShhShell/Views/Fonts/FontManagerView.swift index 9f77b24..489f99d 100644 --- a/ShhShell/Views/Fonts/FontManagerView.swift +++ b/ShhShell/Views/Fonts/FontManagerView.swift @@ -29,9 +29,9 @@ struct FontManagerView: View { Slider(value: $hostsManager.fontSize, in: 1...20, step: 1) { } minimumValueLabel: { - Label("", systemImage: "textformat.size.smaller") + Image(systemName: "textformat.size.smaller") } maximumValueLabel: { - Label("", systemImage: "textformat.size.larger") + Image(systemName: "textformat.size.larger") } onEditingChanged: { bool in hostsManager.saveFonts() } diff --git a/ShhShell/Views/Hosts/ConnectionView.swift b/ShhShell/Views/Hosts/ConnectionView.swift index b3da1c8..9ebc6d3 100644 --- a/ShhShell/Views/Hosts/ConnectionView.swift +++ b/ShhShell/Views/Hosts/ConnectionView.swift @@ -139,6 +139,10 @@ Hostkey fingerprint is \(handler.getHostkey() ?? "nil") } } + if #available(iOS 26, *) { + ToolbarSpacer() + } + ToolbarItem() { Button() { handler.go() diff --git a/ShhShell/Views/Keys/KeyImporterView.swift b/ShhShell/Views/Keys/KeyImporterView.swift index ddd728a..727c006 100644 --- a/ShhShell/Views/Keys/KeyImporterView.swift +++ b/ShhShell/Views/Keys/KeyImporterView.swift @@ -59,19 +59,28 @@ struct KeyImporterView: View { } .preferredColorScheme(.dark) .overlay(alignment: .bottom) { - Button() { - keyManager.importKey(type: keyType, priv: privkeyStr, name: keyName) - dismiss() - } label: { - Text("Import") + if #available(iOS 26, *) { + Button { + + } label: { + Text("Import") .font(.title) .bold() + } + .modifier(glassButton(prominent: true)) + } else { + Button() { + keyManager.importKey(type: keyType, priv: privkeyStr, name: keyName) + UINotificationFeedbackGenerator().notificationOccurred(.success) + dismiss() + } label: { + Text("Import") + .font(.title) + .bold() + } + .buttonStyle(.borderedProminent) + .padding(.bottom, 15) } - .onTapGesture { - UINotificationFeedbackGenerator().notificationOccurred(.success) - } - .buttonStyle(.borderedProminent) - .padding(.bottom, 15) } } } diff --git a/ShhShell/Views/Misc/GlassButton.swift b/ShhShell/Views/Misc/GlassButton.swift new file mode 100644 index 0000000..f683924 --- /dev/null +++ b/ShhShell/Views/Misc/GlassButton.swift @@ -0,0 +1,49 @@ +// +// GlassButton.swift +// ShhShell +// +// Created by neon443 on 10/09/2025. +// + +import SwiftUI + +struct GlassButton: View { + var action: (() -> Void) + var prominent: Bool = false + @ViewBuilder var label: Label + @ViewBuilder var fallbackLabel: Label + + var body: some View { + if #available(iOS 26, *) { + Button { + action() + } label: { + label + } + .buttonStyle(.glassProminent) + } else { + Button { + action() + } label: { + fallbackLabel + } + } + } +} + +#Preview { + GlassButton( + action: { + + }, + prominent: true, + label: { + Text("iOS 26+") + .padding(5) + }, + fallbackLabel: { + Text("iOS 26+") + .padding(5) + } + ) +} diff --git a/ShhShell/Views/Misc/ViewModifiers.swift b/ShhShell/Views/Misc/ViewModifiers.swift index 0fcf92b..3604bfe 100644 --- a/ShhShell/Views/Misc/ViewModifiers.swift +++ b/ShhShell/Views/Misc/ViewModifiers.swift @@ -8,6 +8,26 @@ import Foundation import SwiftUI +struct glassButton: ViewModifier { + var prominent: Bool + + init(prominent: Bool = false) { + self.prominent = prominent + } + + func body(content: Content) -> some View { + if #available(iOS 26, *) { + if prominent { + content.buttonStyle(.glassProminent) + } else { + content.buttonStyle(.glass) + } + } else { + content + } + } +} + struct foregroundColorStyle: ViewModifier { var color: Color diff --git a/ShhShell/Views/Onboarding/WelcomeView.swift b/ShhShell/Views/Onboarding/WelcomeView.swift index c59513a..4c95f62 100644 --- a/ShhShell/Views/Onboarding/WelcomeView.swift +++ b/ShhShell/Views/Onboarding/WelcomeView.swift @@ -78,7 +78,7 @@ struct WelcomeView: View { Button("Continue") { hostsManager.setOnboarding(to: true) } - .buttonStyle(.glassProminent) + .modifier(glassButton(prominent: true)) #else Button { hostsManager.setOnboarding(to: true) diff --git a/ShhShell/Views/Settings/SettingsView.swift b/ShhShell/Views/Settings/SettingsView.swift index e96a8e7..229358f 100644 --- a/ShhShell/Views/Settings/SettingsView.swift +++ b/ShhShell/Views/Settings/SettingsView.swift @@ -108,7 +108,9 @@ struct SettingsView: View { } .pickerStyle(.inline) .labelsHidden() - + } + + Section("Cursor Animations") { Picker("Animation Type", selection: $hostsManager.settings.cursorAnimations.type) { ForEach(CursorAnimationType.allCases, id: \.self) { animType in Text(animType.description).tag(animType) @@ -137,7 +139,7 @@ struct SettingsView: View { HStack { Text("Stretch Multiplier") Spacer() - Text("\(hostsManager.settings.cursorAnimations.length)s") + Text("\(hostsManager.settings.cursorAnimations.stretchMultiplier)x") .monospaced() .contentTransition(.numericText()) } @@ -153,18 +155,18 @@ struct SettingsView: View { } Section("Keepalive") { - Toggle("location persistence", systemImage: "location.fill", isOn: $hostsManager.settings.locationPersist) + Toggle("Location Persistence", systemImage: "location.fill", isOn: $hostsManager.settings.locationPersist) .onChange(of: hostsManager.settings.locationPersist) { _ in if hostsManager.settings.locationPersist && !Backgrounder.shared.checkPermsStatus() { Backgrounder.shared.requestPerms() } } - Toggle("keep screen awake", systemImage: "cup.and.saucer.fill", isOn: $hostsManager.settings.caffeinate) + Toggle("Keep Display Awake", systemImage: "cup.and.saucer.fill", isOn: $hostsManager.settings.caffeinate) } - Section("Bell") { - Toggle("bell sound", systemImage: "bell.and.waves.left.and.right", isOn: $hostsManager.settings.bellSound) - Toggle("bell haptic",systemImage: "iphone.radiowaves.left.and.right", isOn: $hostsManager.settings.bellHaptic) + Section("Bell Feedback") { + Toggle("Sound", systemImage: "bell.and.waves.left.and.right", isOn: $hostsManager.settings.bellSound) + Toggle("Haptic",systemImage: "iphone.radiowaves.left.and.right", isOn: $hostsManager.settings.bellHaptic) } diff --git a/ShhShell/Views/Terminal/ShellTabView.swift b/ShhShell/Views/Terminal/ShellTabView.swift index 63c4288..ae75916 100644 --- a/ShhShell/Views/Terminal/ShellTabView.swift +++ b/ShhShell/Views/Terminal/ShellTabView.swift @@ -16,7 +16,8 @@ struct ShellTabView: View { @State var selectedID: UUID? var selectedHandler: SSHHandler { guard let selectedID, let contained = container.sessions[selectedID] else { - return handler! + guard let handler else { fatalError("no handler in shelltabview") } + return handler } return contained.handler } diff --git a/ShhShell/Views/Themes/ThemeManagerView.swift b/ShhShell/Views/Themes/ThemeManagerView.swift index df287e9..0395582 100644 --- a/ShhShell/Views/Themes/ThemeManagerView.swift +++ b/ShhShell/Views/Themes/ThemeManagerView.swift @@ -115,21 +115,23 @@ struct ThemeManagerView: View { } } .toolbar { - ToolbarItem() { + ToolbarItemGroup { Button() { UIApplication.shared.open(URL(string: "https://iterm2colorschemes.com")!) } label: { - Label("Open themes site", systemImage: "safari") + Label("Browse", systemImage: "safari") } - } - ToolbarItem() { Button() { showAlert.toggle() } label: { - Label("From URL", systemImage: "link") + Label("URL", systemImage: "link") } - } + + if #available(iOS 26, *) { + ToolbarSpacer() + } + ToolbarItem() { Button() { newTheme = Theme.defaultTheme