import SwiftUI import LChatCore // 🤖 The native surface for a schema-described app thread (To-do, Reminders): // the Interface view is SchemaAppView — native components assembled from the // app's schema — with the companion Chat view (the same DM-with-the-app the // web offers) switched from the ⋮ menu (AppViewPicker rows — dropdown items, // never a segmented control in the bar) and rendered by the native feed. The // webview is out of the loop entirely for these apps; apps without a schema // get the same shape from AppThreadScreen, with a webview only as the // Interface. struct SchemaAppScreen: View { let instance: SavedInstance let thread: ChatThread @ObservedObject var store: ThreadStore let schemaStore: SchemaAppStore // The Interface IS the app (the web's takeover default); Chat is the // companion conversation, a menu pick away. @State private var mode = "interface" // "chat" | "interface" // Passed through to the companion chat: its profile cards hop threads. @Binding private var path: [Route] @Environment(\.dismiss) private var dismiss init?(instance: SavedInstance, thread: ChatThread, store: ThreadStore, path: Binding<[Route]>) { guard let schemaStore = SchemaAppStoreCache.shared.store(for: instance, thread: thread, myUserId: store.myUserId) else { return nil } self.instance = instance self.thread = thread self.store = store self.schemaStore = schemaStore self._path = path } var body: some View { if mode == "chat" { NativeChatScreen(instance: instance, thread: thread, store: store, path: $path, appView: $mode) } else { SchemaAppView(store: schemaStore) .navigationTitle(thread.title) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .primaryAction) { AppInterfaceKebab(store: store, thread: thread, appView: $mode, onClose: { dismiss() }) } } } } }