working onsolarium support

new ios 26 button for keyimporter view (currently kaput)
added glassbutton viewmodifier
added glassbutton view might remove
cleaned up wording and stuff in settingsview
fix extra spacing on font size slider labels
centre aligned about view vs left align
toolbar grouping
This commit is contained in:
neon443
2025-09-10 20:54:43 +01:00
parent d26d564fda
commit 0b83009b39
11 changed files with 121 additions and 33 deletions

View File

@@ -96,6 +96,7 @@
A9C897EF2DF1A9A400EF9A5F /* SSHHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C897EE2DF1A9A400EF9A5F /* SSHHandler.swift */; }; A9C897EF2DF1A9A400EF9A5F /* SSHHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C897EE2DF1A9A400EF9A5F /* SSHHandler.swift */; };
A9CC786B2E4E681400FAEE58 /* RecentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9CC786A2E4E681400FAEE58 /* RecentsView.swift */; }; A9CC786B2E4E681400FAEE58 /* RecentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9CC786A2E4E681400FAEE58 /* RecentsView.swift */; };
A9CC786D2E4F534600FAEE58 /* History.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9CC786C2E4F534600FAEE58 /* History.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 */; }; A9D819292E0E904200442D38 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D819282E0E904200442D38 /* Theme.swift */; };
A9D8192D2E0E9EB500442D38 /* ThemeManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D8192C2E0E9EB500442D38 /* ThemeManagerView.swift */; }; A9D8192D2E0E9EB500442D38 /* ThemeManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D8192C2E0E9EB500442D38 /* ThemeManagerView.swift */; };
A9D8192F2E0F1BEE00442D38 /* ThemeButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D8192E2E0F1BEE00442D38 /* ThemeButton.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 = "<group>"; }; A9C897EE2DF1A9A400EF9A5F /* SSHHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSHHandler.swift; sourceTree = "<group>"; };
A9CC786A2E4E681400FAEE58 /* RecentsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentsView.swift; sourceTree = "<group>"; }; A9CC786A2E4E681400FAEE58 /* RecentsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentsView.swift; sourceTree = "<group>"; };
A9CC786C2E4F534600FAEE58 /* History.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = History.swift; sourceTree = "<group>"; }; A9CC786C2E4F534600FAEE58 /* History.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = History.swift; sourceTree = "<group>"; };
A9D45DD82E7204FF00BA9E4A /* GlassButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlassButton.swift; sourceTree = "<group>"; };
A9D819282E0E904200442D38 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; }; A9D819282E0E904200442D38 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; };
A9D8192C2E0E9EB500442D38 /* ThemeManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeManagerView.swift; sourceTree = "<group>"; }; A9D8192C2E0E9EB500442D38 /* ThemeManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeManagerView.swift; sourceTree = "<group>"; };
A9D8192E2E0F1BEE00442D38 /* ThemeButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeButton.swift; sourceTree = "<group>"; }; A9D8192E2E0F1BEE00442D38 /* ThemeButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeButton.swift; sourceTree = "<group>"; };
@@ -546,6 +548,7 @@
A93143C52DF61FE300FCD5DB /* ViewModifiers.swift */, A93143C52DF61FE300FCD5DB /* ViewModifiers.swift */,
A96C90A02E12B87900724253 /* TextBox.swift */, A96C90A02E12B87900724253 /* TextBox.swift */,
A9835C3B2E17CCA500969508 /* TrafficLights.swift */, A9835C3B2E17CCA500969508 /* TrafficLights.swift */,
A9D45DD82E7204FF00BA9E4A /* GlassButton.swift */,
); );
path = Misc; path = Misc;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -908,6 +911,7 @@
A9FD37552E143D23005319A8 /* SecKeyConvertible.swift in Sources */, A9FD37552E143D23005319A8 /* SecKeyConvertible.swift in Sources */,
A94B832F2E5B929C00EBA09C /* Backgrounder.swift in Sources */, A94B832F2E5B929C00EBA09C /* Backgrounder.swift in Sources */,
A96C6AFE2E0C43B600F377FE /* Keypair.swift in Sources */, A96C6AFE2E0C43B600F377FE /* Keypair.swift in Sources */,
A9D45DD92E7204FF00BA9E4A /* GlassButton.swift in Sources */,
A90B38322E3E8FC9002B56FC /* AboutView.swift in Sources */, A90B38322E3E8FC9002B56FC /* AboutView.swift in Sources */,
A9C4140C2E096DB7005E3047 /* SSHError.swift in Sources */, A9C4140C2E096DB7005E3047 /* SSHError.swift in Sources */,
A96BE6AA2E116EC000C0FEE9 /* TerminalViewContainer.swift in Sources */, A96BE6AA2E116EC000C0FEE9 /* TerminalViewContainer.swift in Sources */,

View File

@@ -14,8 +14,7 @@ struct AboutView: View {
ZStack { ZStack {
hostsManager.selectedTheme.background.suiColor.opacity(0.7) hostsManager.selectedTheme.background.suiColor.opacity(0.7)
.ignoresSafeArea(.all) .ignoresSafeArea(.all)
// List { VStack {
VStack(alignment: .leading) {
hostsManager.settings.appIcon.image hostsManager.settings.appIcon.image
.resizable().scaledToFit() .resizable().scaledToFit()
.frame(width: 100) .frame(width: 100)
@@ -32,7 +31,7 @@ struct AboutView: View {
} }
.padding(.bottom) .padding(.bottom)
Section("Thanks to") { HStack(spacing: 10) {
Link(destination: URL(string: "https://libssh.org")!) { Link(destination: URL(string: "https://libssh.org")!) {
Text("LibSSH") Text("LibSSH")
.padding(10) .padding(10)
@@ -57,7 +56,7 @@ struct AboutView: View {
VStack { VStack {
Text("Shader Playground") Text("Shader Playground")
.bold() .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) .font(.caption2)
} }
} }
@@ -65,8 +64,6 @@ struct AboutView: View {
.transition(.scale) .transition(.scale)
.frame(maxWidth: .infinity) .frame(maxWidth: .infinity)
.padding() .padding()
// }
// .scrollContentBackground(.hidden)
} }
} }
} }

View File

@@ -29,9 +29,9 @@ struct FontManagerView: View {
Slider(value: $hostsManager.fontSize, in: 1...20, step: 1) { Slider(value: $hostsManager.fontSize, in: 1...20, step: 1) {
} minimumValueLabel: { } minimumValueLabel: {
Label("", systemImage: "textformat.size.smaller") Image(systemName: "textformat.size.smaller")
} maximumValueLabel: { } maximumValueLabel: {
Label("", systemImage: "textformat.size.larger") Image(systemName: "textformat.size.larger")
} onEditingChanged: { bool in } onEditingChanged: { bool in
hostsManager.saveFonts() hostsManager.saveFonts()
} }

View File

@@ -139,6 +139,10 @@ Hostkey fingerprint is \(handler.getHostkey() ?? "nil")
} }
} }
if #available(iOS 26, *) {
ToolbarSpacer()
}
ToolbarItem() { ToolbarItem() {
Button() { Button() {
handler.go() handler.go()

View File

@@ -59,22 +59,31 @@ struct KeyImporterView: View {
} }
.preferredColorScheme(.dark) .preferredColorScheme(.dark)
.overlay(alignment: .bottom) { .overlay(alignment: .bottom) {
if #available(iOS 26, *) {
Button {
} label: {
Text("Import")
.font(.title)
.bold()
}
.modifier(glassButton(prominent: true))
} else {
Button() { Button() {
keyManager.importKey(type: keyType, priv: privkeyStr, name: keyName) keyManager.importKey(type: keyType, priv: privkeyStr, name: keyName)
UINotificationFeedbackGenerator().notificationOccurred(.success)
dismiss() dismiss()
} label: { } label: {
Text("Import") Text("Import")
.font(.title) .font(.title)
.bold() .bold()
} }
.onTapGesture {
UINotificationFeedbackGenerator().notificationOccurred(.success)
}
.buttonStyle(.borderedProminent) .buttonStyle(.borderedProminent)
.padding(.bottom, 15) .padding(.bottom, 15)
} }
} }
} }
}
#Preview { #Preview {
KeyImporterView(keyManager: KeyManager()) KeyImporterView(keyManager: KeyManager())

View File

@@ -0,0 +1,49 @@
//
// GlassButton.swift
// ShhShell
//
// Created by neon443 on 10/09/2025.
//
import SwiftUI
struct GlassButton<Label: View>: 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)
}
)
}

View File

@@ -8,6 +8,26 @@
import Foundation import Foundation
import SwiftUI 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 { struct foregroundColorStyle: ViewModifier {
var color: Color var color: Color

View File

@@ -78,7 +78,7 @@ struct WelcomeView: View {
Button("Continue") { Button("Continue") {
hostsManager.setOnboarding(to: true) hostsManager.setOnboarding(to: true)
} }
.buttonStyle(.glassProminent) .modifier(glassButton(prominent: true))
#else #else
Button { Button {
hostsManager.setOnboarding(to: true) hostsManager.setOnboarding(to: true)

View File

@@ -108,7 +108,9 @@ struct SettingsView: View {
} }
.pickerStyle(.inline) .pickerStyle(.inline)
.labelsHidden() .labelsHidden()
}
Section("Cursor Animations") {
Picker("Animation Type", selection: $hostsManager.settings.cursorAnimations.type) { Picker("Animation Type", selection: $hostsManager.settings.cursorAnimations.type) {
ForEach(CursorAnimationType.allCases, id: \.self) { animType in ForEach(CursorAnimationType.allCases, id: \.self) { animType in
Text(animType.description).tag(animType) Text(animType.description).tag(animType)
@@ -137,7 +139,7 @@ struct SettingsView: View {
HStack { HStack {
Text("Stretch Multiplier") Text("Stretch Multiplier")
Spacer() Spacer()
Text("\(hostsManager.settings.cursorAnimations.length)s") Text("\(hostsManager.settings.cursorAnimations.stretchMultiplier)x")
.monospaced() .monospaced()
.contentTransition(.numericText()) .contentTransition(.numericText())
} }
@@ -153,18 +155,18 @@ struct SettingsView: View {
} }
Section("Keepalive") { 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 .onChange(of: hostsManager.settings.locationPersist) { _ in
if hostsManager.settings.locationPersist && !Backgrounder.shared.checkPermsStatus() { if hostsManager.settings.locationPersist && !Backgrounder.shared.checkPermsStatus() {
Backgrounder.shared.requestPerms() 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") { Section("Bell Feedback") {
Toggle("bell sound", systemImage: "bell.and.waves.left.and.right", isOn: $hostsManager.settings.bellSound) Toggle("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) Toggle("Haptic",systemImage: "iphone.radiowaves.left.and.right", isOn: $hostsManager.settings.bellHaptic)
} }

View File

@@ -16,7 +16,8 @@ struct ShellTabView: View {
@State var selectedID: UUID? @State var selectedID: UUID?
var selectedHandler: SSHHandler { var selectedHandler: SSHHandler {
guard let selectedID, let contained = container.sessions[selectedID] else { 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 return contained.handler
} }

View File

@@ -115,21 +115,23 @@ struct ThemeManagerView: View {
} }
} }
.toolbar { .toolbar {
ToolbarItem() { ToolbarItemGroup {
Button() { Button() {
UIApplication.shared.open(URL(string: "https://iterm2colorschemes.com")!) UIApplication.shared.open(URL(string: "https://iterm2colorschemes.com")!)
} label: { } label: {
Label("Open themes site", systemImage: "safari") Label("Browse", systemImage: "safari")
} }
}
ToolbarItem() {
Button() { Button() {
showAlert.toggle() showAlert.toggle()
} label: { } label: {
Label("From URL", systemImage: "link") Label("URL", systemImage: "link")
}
} }
if #available(iOS 26, *) {
ToolbarSpacer()
} }
ToolbarItem() { ToolbarItem() {
Button() { Button() {
newTheme = Theme.defaultTheme newTheme = Theme.defaultTheme