mirror of
https://github.com/neon443/ShhShell.git
synced 2026-03-11 13:26:16 +00:00
added mac-like traffic lights to the top of tabshellview
This commit is contained in:
@@ -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 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,40 @@ struct ShellTabView: View {
|
|||||||
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) {
|
||||||
|
Button() {
|
||||||
|
for session in container.sessions.values {
|
||||||
|
session.handler.disconnect()
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
Image(systemName: "xmark.circle.fill")
|
||||||
|
.resizable().scaledToFit()
|
||||||
|
.symbolRenderingMode(.palette)
|
||||||
|
.foregroundStyle(
|
||||||
|
ColorCodable(red: 0.5411764706, green: 0, blue: 0).stColor.suiColor,
|
||||||
|
.red
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Button() {
|
||||||
|
dismiss()
|
||||||
|
} label: {
|
||||||
|
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) {
|
ScrollView(.horizontal, showsIndicators: false) {
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
ForEach(container.sessionIDs, id: \.self) { id in
|
ForEach(container.sessionIDs, id: \.self) { id in
|
||||||
@@ -31,15 +64,6 @@ struct ShellTabView: View {
|
|||||||
Rectangle()
|
Rectangle()
|
||||||
.fill(selected ? ansi7 : background)
|
.fill(selected ? ansi7 : background)
|
||||||
HStack {
|
HStack {
|
||||||
if selected {
|
|
||||||
Button() {
|
|
||||||
container.sessions[id]?.handler.disconnect()
|
|
||||||
} label: {
|
|
||||||
Image(systemName: "xmark.app.fill")
|
|
||||||
.resizable().scaledToFit()
|
|
||||||
}
|
|
||||||
.padding()
|
|
||||||
}
|
|
||||||
Spacer()
|
Spacer()
|
||||||
VStack {
|
VStack {
|
||||||
Text(container.sessions[id]!.handler.title)
|
Text(container.sessions[id]!.handler.title)
|
||||||
@@ -60,12 +84,17 @@ struct ShellTabView: View {
|
|||||||
withAnimation { selectedID = id }
|
withAnimation { selectedID = id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Button() {
|
Button() {
|
||||||
dismiss()
|
dismiss()
|
||||||
} label: {
|
} label: {
|
||||||
Image(systemName: "arrow.down.right.and.arrow.up.left")
|
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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user