diff --git a/ShhShell/Views/Hosts/ConnectionView.swift b/ShhShell/Views/Hosts/ConnectionView.swift index e86e83a..ab251a9 100644 --- a/ShhShell/Views/Hosts/ConnectionView.swift +++ b/ShhShell/Views/Hosts/ConnectionView.swift @@ -12,6 +12,8 @@ struct ConnectionView: View { @ObservedObject var hostsManager: HostsManager @ObservedObject var keyManager: KeyManager + @State private var shellView: ShellView? = nil + @State var passphrase: String = "" @State var pubkeyStr: String = "" @@ -145,6 +147,7 @@ struct ConnectionView: View { Button() { handler.go() showTerminal = checkShell(handler.state) + TerminalController.TerminalViewContainer.shared = nil } label: { Label( handler.connected ? "Disconnect" : "Connect", @@ -156,7 +159,11 @@ struct ConnectionView: View { } } .fullScreenCover(isPresented: $showTerminal) { - ShellView(handler: handler) + if let shellView { + shellView + } else { + Text("no shellview") + } } .onChange(of: handler.host.key) { _ in guard let previousKnownHost = hostsManager.getHostMatching(handler.host) else { return } @@ -176,6 +183,11 @@ struct ConnectionView: View { privkeyStr = String(data: privateKeyData, encoding: .utf8) ?? "" } } + .onAppear { + if shellView == nil { + shellView = ShellView(handler: handler) + } + } } } diff --git a/ShhShell/Views/Terminal/SSHTerminalView.swift b/ShhShell/Views/Terminal/SSHTerminalView.swift index 9aef1ed..a89811b 100644 --- a/ShhShell/Views/Terminal/SSHTerminalView.swift +++ b/ShhShell/Views/Terminal/SSHTerminalView.swift @@ -18,8 +18,6 @@ final class SSHTerminalView: TerminalView, Sendable, @preconcurrency TerminalVie self.init(frame: frame) self.handler = handler - restoreScrollback() - DispatchQueue.main.async { Task { guard let handler = self.handler else { return } @@ -88,8 +86,10 @@ final class SSHTerminalView: TerminalView, Sendable, @preconcurrency TerminalVie func restoreScrollback() { guard let scrollback = handler?.scrollback else { return } + guard !scrollback.isEmpty else { return } - DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { + self.getTerminal().resetToInitialState() for line in scrollback { self.feed(text: line) } diff --git a/ShhShell/Views/Terminal/ShellView.swift b/ShhShell/Views/Terminal/ShellView.swift index 3da140e..58851a4 100644 --- a/ShhShell/Views/Terminal/ShellView.swift +++ b/ShhShell/Views/Terminal/ShellView.swift @@ -12,12 +12,14 @@ struct ShellView: View { @Environment(\.dismiss) var dismiss - @State private var terminalControllerRef: TerminalController? - var body: some View { NavigationStack { ZStack { - terminalControllerRef + TerminalController(handler: handler) + .onAppear { + print("asd\(handler.scrollback.count)") + TerminalController.TerminalViewContainer.shared?.restoreScrollback() + } Group { Color.gray.opacity(0.2) @@ -31,9 +33,6 @@ struct ShellView: View { DialogView(handler: handler, showDialog: !handler.connected) } } - .task { - terminalControllerRef = TerminalController(handler: handler) - } .toolbar { ToolbarItem { Button() { diff --git a/ShhShell/Views/Terminal/TerminalController.swift b/ShhShell/Views/Terminal/TerminalController.swift index 247511c..c9e480e 100644 --- a/ShhShell/Views/Terminal/TerminalController.swift +++ b/ShhShell/Views/Terminal/TerminalController.swift @@ -13,18 +13,21 @@ import SwiftTerm struct TerminalController: UIViewRepresentable { @ObservedObject var handler: SSHHandler + final class TerminalViewContainer { + @MainActor static var shared: SSHTerminalView? + } + func makeUIView(context: Context) -> TerminalView { - let tv = SSHTerminalView( - frame: CGRect( - origin: CGPoint(x: 0, y: 0), - size: .zero - ), - handler: handler - ) + if let existing = TerminalViewContainer.shared { + return existing + } + let tv = SSHTerminalView(frame: CGRect(origin: CGPoint(x: 0, y: 0), size: .zero), handler: handler) tv.translatesAutoresizingMaskIntoConstraints = false tv.autoresizingMask = [.flexibleWidth, .flexibleHeight] + TerminalViewContainer.shared = tv + return tv } @@ -32,8 +35,4 @@ struct TerminalController: UIViewRepresentable { tv.setNeedsLayout() tv.layoutIfNeeded() } - - static func dismantleUIView(_ uiView: SSHTerminalView, coordinator: ()) { - uiView.handler?.disconnect() - } }