made the titlebar have the host label and hide tab bar when only one tab

added a lot of logic fore foreground color calculation, based on luminance of foreground, background and selectedAnsi colors
fixed fallback when opening the first session
fixed text of unselected tabs being unreadable
added tint var to hostsmanager to get accentcolor
reduced ios version to ios 16
This commit is contained in:
neon443
2025-07-04 14:51:54 +01:00
parent 70f11579c5
commit b5f8c4e716
4 changed files with 62 additions and 21 deletions

View File

@@ -824,7 +824,7 @@
INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 17; IPHONEOS_DEPLOYMENT_TARGET = 16;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
@@ -861,7 +861,7 @@
INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 17; IPHONEOS_DEPLOYMENT_TARGET = 16;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",

View File

@@ -17,6 +17,10 @@ class HostsManager: ObservableObject, @unchecked Sendable {
@Published var selectedTheme: Theme = Theme.defaultTheme @Published var selectedTheme: Theme = Theme.defaultTheme
@Published var selectedAnsi: Int = 1 @Published var selectedAnsi: Int = 1
var tint: SwiftUI.Color {
selectedTheme.ansi[selectedAnsi].suiColor
}
init() { init() {
loadHosts() loadHosts()
loadThemes() loadThemes()

View File

@@ -28,7 +28,7 @@ struct ShhShellApp: App {
keyManager: keyManager keyManager: keyManager
) )
.colorScheme(hostsManager.selectedTheme.background.luminance > 0.5 ? .light : .dark) .colorScheme(hostsManager.selectedTheme.background.luminance > 0.5 ? .light : .dark)
.tint(hostsManager.selectedTheme.ansi[hostsManager.selectedAnsi].suiColor) .tint(hostsManager.tint)
} }
} }
} }

View File

@@ -16,7 +16,25 @@ struct ShellTabView: View {
@Environment(\.dismiss) var dismiss @Environment(\.dismiss) var dismiss
var foreground: Color { hostsManager.selectedTheme.foreground.suiColor } var foreground: Color {
let selectedTheme = hostsManager.selectedTheme
let foreground = selectedTheme.foreground
let background = selectedTheme.background
if selectedTheme.ansi[hostsManager.selectedAnsi].luminance > 0.5 {
if foreground.luminance > 0.5 {
return background.suiColor
} else {
return foreground.suiColor
}
} else {
if foreground.luminance > 0.5 {
return foreground.suiColor
} else {
return background.suiColor
}
}
}
var background: Color { hostsManager.selectedTheme.background.suiColor } var background: Color { hostsManager.selectedTheme.background.suiColor }
var body: some View { var body: some View {
@@ -32,6 +50,7 @@ struct ShellTabView: View {
for session in container.sessions.values { for session in container.sessions.values {
session.handler.disconnect() session.handler.disconnect()
} }
dismiss()
} label: { } label: {
TrafficLightRed() TrafficLightRed()
} }
@@ -41,40 +60,51 @@ struct ShellTabView: View {
TrafficLightYellow() TrafficLightYellow()
} }
Spacer() Spacer()
Text(container.sessions[selectedID ?? UUID()]?.handler.title ?? "title") VStack {
.bold() Text(container.sessions[selectedID ?? UUID()]?.handler.title ?? handler?.title ?? "")
.monospaced() .bold()
.foregroundStyle(foreground)
.monospaced()
.contentTransition(.numericText())
if container.sessionIDs.count == 1 {
Text(container.sessions[selectedID ?? UUID()]?.handler.host.description ?? handler?.host.description ?? "")
.bold()
.foregroundStyle(foreground)
.monospaced()
.font(.caption2)
}
}
Spacer() Spacer()
} }
.padding(.horizontal, 10) .padding(.horizontal, 10)
.padding(.bottom, 10) .padding(.bottom, 10)
.background(Color.accentColor, ignoresSafeAreaEdges: .all) .background(hostsManager.tint, ignoresSafeAreaEdges: .all)
.frame(height: 30) .frame(height: 30)
HStack(alignment: .center, spacing: 0) { if container.sessionIDs.count > 1 {
ScrollView(.horizontal, showsIndicators: false) { ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 0) { HStack(spacing: 0) {
ForEach(container.sessionIDs, id: \.self) { id in ForEach(container.sessionIDs, id: \.self) { id in
let selected: Bool = selectedID == id let selected: Bool = selectedID == id
ZStack { ZStack {
Rectangle() Rectangle()
.fill(selected ? .accentColor : background) .fill(selected ? hostsManager.tint : background)
HStack { HStack {
Spacer() Spacer()
VStack { VStack {
if !selected { if !selected {
Text(container.sessions[id]!.handler.title) Text(container.sessions[id]!.handler.title)
.monospaced() .monospaced()
.foregroundStyle(foreground) .foregroundStyle(selected ? foreground : hostsManager.tint)
.opacity(0.7) .opacity(0.7)
.font(.callout) .font(.callout)
} }
Text(container.sessions[id]!.handler.host.description) Text(container.sessions[id]!.handler.host.description)
.foregroundStyle(foreground) .foregroundStyle(selected ? foreground : hostsManager.tint)
.opacity(selected ? 1 : 0.7) .opacity(selected ? 1 : 0.7)
.monospaced() .monospaced()
.bold(selected) .bold(selected)
.font(.caption) .font(.caption2)
} }
Spacer() Spacer()
} }
@@ -86,14 +116,14 @@ struct ShellTabView: View {
} }
} }
} }
} .frame(height: 30)
.frame(height: 30) .onAppear {
.onAppear { if selectedID == nil {
if selectedID == nil { if let handler {
if let handler { selectedID = handler.sessionID
selectedID = handler.sessionID } else {
} else { dismiss()
dismiss() }
} }
} }
} }
@@ -105,6 +135,7 @@ struct ShellTabView: View {
handler: session.handler, handler: session.handler,
hostsManager: hostsManager hostsManager: hostsManager
) )
.border(.blue)
.onDisappear { .onDisappear {
if !checkShell(session.handler.state) { if !checkShell(session.handler.state) {
if let lastSession = container.sessionIDs.last { if let lastSession = container.sessionIDs.last {
@@ -119,6 +150,12 @@ struct ShellTabView: View {
} else { } else {
if let handler { if let handler {
ShellView(handler: handler, hostsManager: hostsManager) ShellView(handler: handler, hostsManager: hostsManager)
.onAppear {
if selectedID == nil {
selectedID = handler.sessionID
}
}
.border(.red)
} else { } else {
Text("No SSH Handler") Text("No SSH Handler")
} }