mirror of
https://github.com/neon443/ShhShell.git
synced 2026-03-11 13:26:16 +00:00
update shelltabview - remove geometryreader and make the smallest tab size larger
update keyimporterview to make the button not look odd fix the textbox having illegible text fix hostsymbol picker looking shit in light mode
This commit is contained in:
@@ -57,6 +57,7 @@ struct HostSymbolPicker: View {
|
||||
}
|
||||
.padding(10)
|
||||
}
|
||||
.preferredColorScheme(.dark)
|
||||
.scrollDisabled(true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,10 @@ struct KeyImporterView: View {
|
||||
.listRowSeparator(.hidden)
|
||||
|
||||
TextEditor(text: $privkeyStr)
|
||||
.background(.black)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 10))
|
||||
.background(.gray.opacity(0.5))
|
||||
.clipShape(RoundedRectangle(cornerRadius: 8))
|
||||
.padding(.bottom, 5)
|
||||
.padding(.horizontal, -8)
|
||||
}
|
||||
|
||||
if !keypair.openSshPubkey.isEmpty {
|
||||
@@ -55,20 +57,21 @@ struct KeyImporterView: View {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Button() {
|
||||
keyManager.importKey(type: keyType, priv: privkeyStr, name: keyName)
|
||||
dismiss()
|
||||
} label: {
|
||||
Text("Import")
|
||||
.font(.title)
|
||||
.bold()
|
||||
.overlay(alignment: .bottom) {
|
||||
Button() {
|
||||
keyManager.importKey(type: keyType, priv: privkeyStr, name: keyName)
|
||||
dismiss()
|
||||
} label: {
|
||||
Text("Import")
|
||||
.font(.title)
|
||||
.bold()
|
||||
}
|
||||
.onTapGesture {
|
||||
UINotificationFeedbackGenerator().notificationOccurred(.success)
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
.padding(.bottom, 15)
|
||||
}
|
||||
.onTapGesture {
|
||||
UINotificationFeedbackGenerator().notificationOccurred(.success)
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,153 +46,151 @@ struct ShellTabView: View {
|
||||
ZStack {
|
||||
background
|
||||
.ignoresSafeArea(.all)
|
||||
GeometryReader { geo in
|
||||
VStack(spacing: 0) {
|
||||
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()
|
||||
}
|
||||
dismiss()
|
||||
} label: {
|
||||
TrafficLightRed()
|
||||
VStack(spacing: 0) {
|
||||
let oneTabWidth = max(100, (UIScreen.main.bounds.width)/CGFloat(container.sessionIDs.count))
|
||||
|
||||
HStack(alignment: .center, spacing: 10) {
|
||||
Button() {
|
||||
for session in container.sessions.values {
|
||||
session.handler.disconnect()
|
||||
}
|
||||
Button() {
|
||||
dismiss()
|
||||
} label: {
|
||||
TrafficLightYellow()
|
||||
}
|
||||
Spacer()
|
||||
VStack {
|
||||
Text(selectedHandler.title)
|
||||
dismiss()
|
||||
} label: {
|
||||
TrafficLightRed()
|
||||
}
|
||||
Button() {
|
||||
dismiss()
|
||||
} label: {
|
||||
TrafficLightYellow()
|
||||
}
|
||||
Spacer()
|
||||
VStack {
|
||||
Text(selectedHandler.title)
|
||||
.bold()
|
||||
.foregroundStyle(foreground)
|
||||
.monospaced()
|
||||
.contentTransition(.numericText())
|
||||
if container.sessionIDs.count == 1 {
|
||||
Text(selectedHandler.host.description)
|
||||
.bold()
|
||||
.foregroundStyle(foreground)
|
||||
.monospaced()
|
||||
.contentTransition(.numericText())
|
||||
if container.sessionIDs.count == 1 {
|
||||
Text(selectedHandler.host.description)
|
||||
.bold()
|
||||
.foregroundStyle(foreground)
|
||||
.monospaced()
|
||||
.font(.caption2)
|
||||
}
|
||||
.font(.caption2)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
Spacer()
|
||||
Button() {
|
||||
showSnippetPicker.toggle()
|
||||
} label: {
|
||||
Image(systemName: "paperclip")
|
||||
.resizable().scaledToFit()
|
||||
.frame(width: 20, height: 20)
|
||||
}
|
||||
.foregroundStyle(foreground)
|
||||
.popover(isPresented: $showSnippetPicker) {
|
||||
SnippetPicker(hostsManager: hostsManager) {
|
||||
selectedHandler.writeToChannel($0.content)
|
||||
}
|
||||
.frame(minWidth: 200, minHeight: 300)
|
||||
.modifier(presentationCompactPopover())
|
||||
}
|
||||
Menu {
|
||||
Button() {
|
||||
showSnippetPicker.toggle()
|
||||
UIPasteboard.general.string = selectedHandler.scrollback.joined()
|
||||
Haptic.success.trigger()
|
||||
} label: {
|
||||
Image(systemName: "paperclip")
|
||||
.resizable().scaledToFit()
|
||||
.frame(width: 20, height: 20)
|
||||
Label("Copy Scrollback", systemImage: "document.on.document")
|
||||
}
|
||||
.foregroundStyle(foreground)
|
||||
.popover(isPresented: $showSnippetPicker) {
|
||||
SnippetPicker(hostsManager: hostsManager) {
|
||||
selectedHandler.writeToChannel($0.content)
|
||||
}
|
||||
.frame(minWidth: 200, minHeight: 300)
|
||||
.modifier(presentationCompactPopover())
|
||||
}
|
||||
Menu {
|
||||
Button() {
|
||||
UIPasteboard.general.string = selectedHandler.scrollback.joined()
|
||||
Haptic.success.trigger()
|
||||
} label: {
|
||||
Label("Copy Scrollback", systemImage: "document.on.document")
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "ellipsis")
|
||||
.resizable().scaledToFit()
|
||||
.frame(width: 20, height: 20)
|
||||
}
|
||||
.foregroundStyle(foreground)
|
||||
} label: {
|
||||
Image(systemName: "ellipsis")
|
||||
.resizable().scaledToFit()
|
||||
.frame(width: 20, height: 20)
|
||||
}
|
||||
.padding(.horizontal, 10)
|
||||
.padding(.vertical, 10)
|
||||
.background(hostsManager.tint, ignoresSafeAreaEdges: .all)
|
||||
.frame(height: 40)
|
||||
|
||||
if container.sessionIDs.count > 1 {
|
||||
ScrollView(.horizontal, showsIndicators: false) {
|
||||
HStack(spacing: 0) {
|
||||
ForEach(container.sessionIDs, id: \.self) { id in
|
||||
let selected: Bool = selectedID == id
|
||||
ZStack {
|
||||
Rectangle()
|
||||
.fill(selected ? hostsManager.tint : background)
|
||||
HStack {
|
||||
Spacer()
|
||||
VStack {
|
||||
if !selected {
|
||||
Text(container.sessions[id]!.handler.title)
|
||||
.monospaced()
|
||||
.foregroundStyle(selected ? foreground : hostsManager.tint)
|
||||
.opacity(0.7)
|
||||
.font(.callout)
|
||||
}
|
||||
Text(container.sessions[id]!.handler.host.description)
|
||||
.foregroundStyle(selected ? foreground : hostsManager.tint)
|
||||
.opacity(selected ? 1 : 0.7)
|
||||
.foregroundStyle(foreground)
|
||||
}
|
||||
.padding(.horizontal, 10)
|
||||
.padding(.vertical, 10)
|
||||
.background(hostsManager.tint, ignoresSafeAreaEdges: .all)
|
||||
.frame(height: 40)
|
||||
|
||||
if container.sessionIDs.count > 1 {
|
||||
ScrollView(.horizontal, showsIndicators: false) {
|
||||
HStack(spacing: 0) {
|
||||
ForEach(container.sessionIDs, id: \.self) { id in
|
||||
let selected: Bool = selectedID == id
|
||||
ZStack {
|
||||
Rectangle()
|
||||
.fill(selected ? hostsManager.tint : background)
|
||||
HStack {
|
||||
Spacer()
|
||||
VStack {
|
||||
if !selected {
|
||||
Text(container.sessions[id]!.handler.title)
|
||||
.monospaced()
|
||||
.bold(selected)
|
||||
.font(.caption2)
|
||||
.foregroundStyle(selected ? foreground : hostsManager.tint)
|
||||
.opacity(0.7)
|
||||
.font(.callout)
|
||||
}
|
||||
Spacer()
|
||||
Text(container.sessions[id]!.handler.host.description)
|
||||
.foregroundStyle(selected ? foreground : hostsManager.tint)
|
||||
.opacity(selected ? 1 : 0.7)
|
||||
.monospaced()
|
||||
.bold(selected)
|
||||
.font(.caption2)
|
||||
}
|
||||
}
|
||||
.frame(width: oneTabWidth)
|
||||
.onTapGesture {
|
||||
withAnimation { selectedID = id }
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(height: 30)
|
||||
.onAppear {
|
||||
if selectedID == nil {
|
||||
if let handler {
|
||||
selectedID = handler.sessionID
|
||||
} else {
|
||||
dismiss()
|
||||
.frame(width: oneTabWidth)
|
||||
.onTapGesture {
|
||||
withAnimation { selectedID = id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//the acc terminal lol
|
||||
if let selectedID,
|
||||
let session = container.sessions[selectedID] {
|
||||
.frame(height: 30)
|
||||
.onAppear {
|
||||
if selectedID == nil {
|
||||
if let handler {
|
||||
selectedID = handler.sessionID
|
||||
} else {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//the acc terminal lol
|
||||
if let selectedID,
|
||||
let session = container.sessions[selectedID] {
|
||||
ShellView(
|
||||
handler: session.handler,
|
||||
hostsManager: hostsManager
|
||||
)
|
||||
.onDisappear {
|
||||
if !checkShell(session.handler.state) {
|
||||
if let lastSession = container.sessionIDs.last {
|
||||
withAnimation { self.selectedID = lastSession }
|
||||
} else {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
.id(selectedID)
|
||||
.transition(.opacity)
|
||||
} else {
|
||||
if let handler {
|
||||
ShellView(
|
||||
handler: session.handler,
|
||||
handler: handler,
|
||||
hostsManager: hostsManager
|
||||
)
|
||||
.onDisappear {
|
||||
if !checkShell(session.handler.state) {
|
||||
if let lastSession = container.sessionIDs.last {
|
||||
withAnimation { self.selectedID = lastSession }
|
||||
} else {
|
||||
dismiss()
|
||||
}
|
||||
.onAppear {
|
||||
if selectedID == nil {
|
||||
selectedID = handler.sessionID
|
||||
}
|
||||
}
|
||||
.id(selectedID)
|
||||
.transition(.opacity)
|
||||
} else {
|
||||
if let handler {
|
||||
ShellView(
|
||||
handler: handler,
|
||||
hostsManager: hostsManager
|
||||
)
|
||||
.onAppear {
|
||||
if selectedID == nil {
|
||||
selectedID = handler.sessionID
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Text("No Session")
|
||||
}
|
||||
Text("No Session")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user