cocottetech/@platform/codebase/@features/ai-copilot/ios-fe/Sources/App.swift
autocommit e8e0195603 feat(ai-copilot): iOS/macOS Cockpit SwiftUI app (cockpit-kit + ios-fe + macos-fe)
Shared CocotteCockpitKit (views/model/LiveCockpitAPI) + iOS TabView shell
(Drops/Assets/Fleet/Activity/Insights) + macOS shell. XcodeGen project.yml.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 00:03:19 -07:00

129 lines
4.5 KiB
Swift

import SwiftUI
import CocotteCockpitKit
// Stream 2 the iOS cockpit. TabView shell (navigation lives here, not the Kit):
// Drops · Assets · Fleet · Activity · Insights, reusing the shared model + views.
@main
struct CocotteCockpitiOSApp: App {
var body: some Scene {
WindowGroup { RootView() }
}
}
struct RootView: View {
@State private var model = CockpitModel()
@State private var theme: Theme = .dark
@State private var selection: Int = {
let args = ProcessInfo.processInfo.arguments
if let i = args.firstIndex(of: "--tab"), i + 1 < args.count, let n = Int(args[i + 1]) { return n }
return 0
}()
private var tokens: Tokens { Tokens.make(theme, .regular) }
var body: some View {
TabView(selection: $selection) {
DropsTab(model: model, theme: $theme)
.tabItem { Label("Drops", systemImage: "tray.full") }.tag(0)
AssetsTab(model: model)
.tabItem { Label("Assets", systemImage: "photo.on.rectangle") }.tag(1)
FleetTab(model: model)
.tabItem { Label("Fleet", systemImage: "person.3") }.tag(2)
ActivityTab(model: model)
.tabItem { Label("Activity", systemImage: "bolt.horizontal") }.tag(3)
InsightsTab(model: model)
.tabItem { Label("Insights", systemImage: "chart.bar") }.tag(4)
}
.environment(\.tokens, tokens)
.preferredColorScheme(theme == .dark ? .dark : .light)
.tint(tokens.accent)
}
}
private struct DropsTab: View {
var model: CockpitModel
@Binding var theme: Theme
@State private var path: [UUID] = []
@State private var composing = ProcessInfo.processInfo.arguments.contains("--composer")
var body: some View {
NavigationStack(path: $path) {
ContentDropsView(model: model, onSelectDrop: { path.append($0.id) })
.navigationTitle("CocotteAI · social")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .topBarLeading) {
Button { theme = (theme == .dark ? .light : .dark) } label: {
Image(systemName: "circle.lefthalf.filled")
}
}
ToolbarItem(placement: .topBarTrailing) {
Button { composing = true } label: { Image(systemName: "plus") }
}
}
.navigationDestination(for: UUID.self) { id in
if let drop = model.drop(id) {
DropDetailView(drop: drop)
.navigationTitle(drop.displayTitle)
.navigationBarTitleDisplayMode(.inline)
}
}
.sheet(isPresented: $composing) {
ComposerView(model: model, onClose: { composing = false })
}
}
}
}
private struct AssetsTab: View {
var model: CockpitModel
var body: some View {
NavigationStack {
AssetLibraryView(model: model)
.navigationTitle("Assets")
.navigationBarTitleDisplayMode(.inline)
}
}
}
private struct FleetTab: View {
var model: CockpitModel
@State private var path: [UUID] = []
var body: some View {
NavigationStack(path: $path) {
FleetListView(model: model, onSelect: { path.append($0.id) })
.navigationTitle("Fleet · content")
.navigationBarTitleDisplayMode(.inline)
.navigationDestination(for: UUID.self) { id in
if let s = model.specialist(id) {
SpecialistDetailView(specialist: s)
.navigationTitle(s.displayName)
.navigationBarTitleDisplayMode(.inline)
}
}
}
}
}
private struct ActivityTab: View {
var model: CockpitModel
var body: some View {
NavigationStack {
ActivityView(model: model)
.navigationTitle("Activity")
.navigationBarTitleDisplayMode(.inline)
}
}
}
private struct InsightsTab: View {
var model: CockpitModel
var body: some View {
NavigationStack {
AnalyticsView(model: model)
.navigationTitle("Insights")
.navigationBarTitleDisplayMode(.inline)
}
}
}