// // Copyright © 2022 osy. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // import SwiftUI @MainActor struct UTMSingleWindowView: View { private var isInteractive: Bool { data != nil } #if WITH_REMOTE typealias DataType = UTMRemoteData #else typealias DataType = UTMData #endif private let data: DataType? @State private var session: VMSessionState? @State private var identifier: VMSessionState.WindowID? private let vmSessionCreatedNotification = NotificationCenter.default.publisher(for: .vmSessionCreated) private let vmSessionEndedNotification = NotificationCenter.default.publisher(for: .vmSessionEnded) init(data: DataType? = nil) { self.data = data } var body: some View { ZStack { if let session = session { VMWindowView(id: identifier!, isInteractive: isInteractive).environmentObject(session) } else if isInteractive { #if WITH_REMOTE RemoteContentView(remoteClientState: data!.remoteClient.state).environmentObject(data!) #else ContentView().environmentObject(data!) #endif } else { VStack { Text("Waiting for VM to connect to display...") .font(.headline) BusyIndicator() } } } .onAppear { session = VMSessionState.allActiveSessions.first?.value if let session = session { identifier = session.newWindow().windowID } } .onReceive(vmSessionCreatedNotification) { output in let newSession = output.userInfo!["Session"] as! VMSessionState withAnimation { session = newSession identifier = newSession.newWindow().windowID } } .onReceive(vmSessionEndedNotification) { output in let endedSession = output.userInfo!["Session"] as! VMSessionState if endedSession == session { withAnimation { session = nil } } } } } struct UTMSingleWindowView_Previews: PreviewProvider { static var previews: some View { UTMSingleWindowView(data: UTMSingleWindowView.DataType()) } }