added mac-like traffic lights to the top of tabshellview

This commit is contained in:
neon443
2025-07-04 09:29:21 +01:00
parent 89669b4596
commit a9df89eae2
2 changed files with 74 additions and 45 deletions

View File

@@ -185,8 +185,8 @@ class SSHHandler: @unchecked Sendable, ObservableObject {
} }
func setTitle(_ newTitle: String) { func setTitle(_ newTitle: String) {
DispatchQueue.main.async { Task { @MainActor in
self.title = newTitle withAnimation { self.title = newTitle }
} }
} }

View File

@@ -16,56 +16,85 @@ struct ShellTabView: View {
@Environment(\.dismiss) var dismiss @Environment(\.dismiss) var dismiss
var body: some View { var body: some View {
GeometryReader { geo in GeometryReader { geo in
VStack { VStack {
let oneTabWidth = max(60, geo.size.width/CGFloat(container.sessionIDs.count)) HStack(alignment: .center, spacing: 10) {
ScrollView(.horizontal, showsIndicators: false) { Button() {
HStack(spacing: 0) { for session in container.sessions.values {
ForEach(container.sessionIDs, id: \.self) { id in session.handler.disconnect()
let selected = selectedID == id }
let foreground = hostsManager.selectedTheme.foreground.suiColor } label: {
let ansi7 = hostsManager.selectedTheme.ansi[6].suiColor.opacity(0.7) Image(systemName: "xmark.circle.fill")
let background = hostsManager.selectedTheme.background.suiColor .resizable().scaledToFit()
ZStack { .symbolRenderingMode(.palette)
Rectangle() .foregroundStyle(
.fill(selected ? ansi7 : background) ColorCodable(red: 0.5411764706, green: 0, blue: 0).stColor.suiColor,
HStack { .red
if selected { )
Button() { }
container.sessions[id]?.handler.disconnect() Button() {
} label: { dismiss()
Image(systemName: "xmark.app.fill") } label: {
.resizable().scaledToFit() Image(systemName: "minus.circle.fill")
.resizable().scaledToFit()
.symbolRenderingMode(.palette)
.foregroundStyle(
ColorCodable(red: 0.5764705882, green: 0.5333333333, blue: 0.2784313725).stColor.suiColor,
.yellow
)
}
Spacer()
Text(container.sessions[selectedID ?? UUID()]?.handler.title ?? "title")
Spacer()
}
.frame(height: 30)
.padding(10)
let oneTabWidth = max(60, (geo.size.width-35)/CGFloat(container.sessionIDs.count))
HStack(alignment: .center, spacing: 0) {
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 0) {
ForEach(container.sessionIDs, id: \.self) { id in
let selected = selectedID == id
let foreground = hostsManager.selectedTheme.foreground.suiColor
let ansi7 = hostsManager.selectedTheme.ansi[6].suiColor.opacity(0.7)
let background = hostsManager.selectedTheme.background.suiColor
ZStack {
Rectangle()
.fill(selected ? ansi7 : background)
HStack {
Spacer()
VStack {
Text(container.sessions[id]!.handler.title)
.monospaced()
.foregroundStyle(foreground)
.bold(selected)
Text(container.sessions[id]!.handler.host.description)
.foregroundStyle(foreground.opacity(0.7))
.monospaced()
.font(.caption)
} }
.padding() Spacer()
} }
Spacer() }
VStack { .frame(width: oneTabWidth)
Text(container.sessions[id]!.handler.title) .ignoresSafeArea(.all)
.monospaced() .onTapGesture {
.foregroundStyle(foreground) withAnimation { selectedID = id }
.bold(selected)
Text(container.sessions[id]!.handler.host.description)
.foregroundStyle(foreground.opacity(0.7))
.monospaced()
.font(.caption)
}
Spacer()
} }
} }
.frame(width: oneTabWidth)
.ignoresSafeArea(.all)
.onTapGesture {
withAnimation { selectedID = id }
}
}
Button() {
dismiss()
} label: {
Image(systemName: "arrow.down.right.and.arrow.up.left")
} }
} }
Button() {
dismiss()
} label: {
Image(systemName: "arrow.down.right.and.arrow.up.left")
.resizable().scaledToFit()
}
.buttonStyle(.plain)
.frame(width: 30)
.padding(.horizontal, 2.5)
} }
.frame(height: 30) .frame(height: 30)
.onAppear { .onAppear {
@@ -104,7 +133,7 @@ struct ShellTabView: View {
} }
} }
} }
} }
} }
#Preview { #Preview {