import SwiftUI struct InputPanelView: View { @Bindable var appState: AppState let accountStore: AccountStore let onPost: () -> Void let onDismiss: () -> Void @FocusState private var isTextFieldFocused: Bool var body: some View { VStack(spacing: 12) { // Account selector AccountSelectorView( accounts: accountStore.accounts, selectedIDs: $appState.selectedAccountIDs ) // Text input TextEditor(text: $appState.inputText) .font(.system(size: 14)) .frame(minHeight: 80, maxHeight: 160) .focused($isTextFieldFocused) .scrollContentBackground(.hidden) .padding(8) .background(Color(nsColor: .controlBackgroundColor)) .clipShape(RoundedRectangle(cornerRadius: 8)) // Image attachments ImageAttachmentArea(attachedImages: Bindable(appState).attachedImages) // Status message if let status = appState.statusMessage { Text(status.text) .font(.caption) .foregroundStyle(status.isError ? .red : .green) .frame(maxWidth: .infinity, alignment: .leading) } // Bottom bar HStack { Text("\(appState.inputText.count)") .font(.caption) .foregroundStyle(.secondary) .monospacedDigit() Spacer() if appState.isSubmitting { ProgressView() .controlSize(.small) } Button("Post") { onPost() } .buttonStyle(.borderedProminent) .disabled(!appState.canPost) .keyboardShortcut(.return, modifiers: .command) } } .padding() .frame(width: 420) .onAppear { isTextFieldFocused = true } } } struct AccountSelectorView: View { let accounts: [Account] @Binding var selectedIDs: Set var body: some View { if accounts.isEmpty { Text("No accounts configured. Open Settings to add one.") .font(.caption) .foregroundStyle(.secondary) .frame(maxWidth: .infinity, alignment: .center) .padding(.vertical, 4) } else { ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: 6) { ForEach(accounts) { account in AccountChip( account: account, isSelected: selectedIDs.contains(account.id) ) { if selectedIDs.contains(account.id) { selectedIDs.remove(account.id) } else { selectedIDs.insert(account.id) } } } } } } } } struct AccountChip: View { let account: Account let isSelected: Bool let action: () -> Void var body: some View { Button(action: action) { HStack(spacing: 4) { Image(systemName: account.serviceType.iconName) .font(.caption2) Text(account.displayName) .font(.caption) } .padding(.horizontal, 8) .padding(.vertical, 4) .background(isSelected ? Color.accentColor.opacity(0.2) : Color.secondary.opacity(0.1)) .foregroundStyle(isSelected ? Color.accentColor : .secondary) .clipShape(Capsule()) .overlay( Capsule() .strokeBorder(isSelected ? Color.accentColor : Color.clear, lineWidth: 1) ) } .buttonStyle(.plain) } }