diff --git a/ShhShell/SSH/SSHHandler.swift b/ShhShell/SSH/SSHHandler.swift index 3d74f2f..6d57bd1 100644 --- a/ShhShell/SSH/SSHHandler.swift +++ b/ShhShell/SSH/SSHHandler.swift @@ -185,8 +185,8 @@ class SSHHandler: @unchecked Sendable, ObservableObject { } func setTitle(_ newTitle: String) { - DispatchQueue.main.async { - self.title = newTitle + Task { @MainActor in + withAnimation { self.title = newTitle } } } diff --git a/ShhShell/Views/Terminal/ShellTabView.swift b/ShhShell/Views/Terminal/ShellTabView.swift index ca10142..cd49d99 100644 --- a/ShhShell/Views/Terminal/ShellTabView.swift +++ b/ShhShell/Views/Terminal/ShellTabView.swift @@ -16,56 +16,85 @@ struct ShellTabView: View { @Environment(\.dismiss) var dismiss - var body: some View { + var body: some View { GeometryReader { geo in VStack { - let oneTabWidth = max(60, geo.size.width/CGFloat(container.sessionIDs.count)) - 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 { - if selected { - Button() { - container.sessions[id]?.handler.disconnect() - } label: { - Image(systemName: "xmark.app.fill") - .resizable().scaledToFit() + 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) { + 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 { - 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) - } - Spacer() + } + .frame(width: oneTabWidth) + .ignoresSafeArea(.all) + .onTapGesture { + withAnimation { selectedID = id } } } - .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) .onAppear { @@ -104,7 +133,7 @@ struct ShellTabView: View { } } } - } + } } #Preview {