eleven / messenger Public

Clone
git clone https://amadan.net/eleven/messenger

Plain git — no account needed to clone.

Download

Download this file

1import SwiftUI
2import LChatCore
3
4// 🤖 Mac host for Eleven's native onboarding conversation (setup / welcome):
5// the takeover pane NativeChatView routes these app-threads to. The finish
6// chips' thread hop selects the target in the sidebar.
7struct ElevenConversationPane: View {
8 let instance: SavedInstance
9 let thread: ChatThread
10 @ObservedObject var store: ThreadStore
11 @Binding var selectedID: String?
12 @EnvironmentObject private var app: MacAppState
13 @State private var model: ElevenConversationModel?
14 @State private var showDiscover = false
15 @State private var showQuickForm = false
16 @AppStorage(ChatTextSize.key) private var chatTextSize = ChatTextSize.defaultSize
17 @AppStorage("nativeTheme") private var themeName = "classic"
18
19 var body: some View {
20 Group {
21 if let model {
22 ElevenChatView(model: model, theme: .named(themeName))
23 .environment(\.chatFontSize, CGFloat(ChatTextSize.snap(chatTextSize)))
24 } else {
25 ProgressView().frame(maxWidth: .infinity, maxHeight: .infinity)
26 }
27 }
28 .sheet(isPresented: $showDiscover) {
29 // The community directory (shared view; web: showDiscover) — the
30 // welcome finish's "Browse open groups" chip lands here. Mirrors
31 // NativeChatView's Discover sheet.
32 VStack(spacing: 0) {
33 DiscoverGroupsView(store: store) { threadID in
34 showDiscover = false
35 selectedID = threadID
36 }
37 Divider()
38 HStack {
39 Spacer()
40 Button("Done") { showDiscover = false }
41 .keyboardShortcut(.cancelAction)
42 }
43 .padding(12)
44 }
45 .frame(minWidth: 420, minHeight: 420)
46 }
47 .sheet(isPresented: $showQuickForm) {
48 // "Fill in a form instead" — the whole conversation's questions at
49 // once; submitting fast-fills the flow's records and it resumes.
50 if let model {
51 ElevenQuickFormView(model: model)
52 }
53 }
54 .onAppear {
55 guard model == nil else { return }
56 let m = ElevenConversationCache.shared.model(for: instance, thread: thread,
57 myUserId: store.myUserId)
58 m?.openQuickForm = { showQuickForm = true }
59 m?.openThread = { id in selectedID = id }
60 m?.openAdmin = {
61 Task { @MainActor in
62 if let id = await store.openOrCreateAppThread(app: "admin", title: "Admin") {
63 selectedID = id
64 }
65 }
66 }
67 m?.openDiscover = { showDiscover = true }
68 // Outgoing payloads stamp the SavedInstance's name — persist a
69 // flow rename, the way MacSettingsView persists a manual one.
70 m?.onNameSet = { name in
71 app.noteIdentity(origin: instance.origin, token: instance.deviceToken,
72 name: name, userPub: instance.userPub, userPriv: instance.userPriv)
73 }
74 m?.start(roster: store.roster, threads: store.threads)
75 model = m
76 }
77 }
78}
79