mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 12:05:19 +00:00
* Refactor app runtime and view model architecture * Move app ownership into stores and coordinators * Fix smoke test environment injection * Stabilize fragmentation package tests * Fix coordinator build warnings * Clean up chat view model warnings * Fix Nostr relay startup coalescing --------- Co-authored-by: jack <jackjackbits@users.noreply.github.com>
97 lines
3.1 KiB
Swift
97 lines
3.1 KiB
Swift
//
|
|
// CommandSuggestionsView.swift
|
|
// bitchat
|
|
//
|
|
// Created by Islam on 29/10/2025.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct CommandSuggestionsView: View {
|
|
@EnvironmentObject private var privateConversationModel: PrivateConversationModel
|
|
@EnvironmentObject private var locationChannelsModel: LocationChannelsModel
|
|
|
|
@Binding var messageText: String
|
|
|
|
let textColor: Color
|
|
let backgroundColor: Color
|
|
let secondaryTextColor: Color
|
|
|
|
private var filteredCommands: [CommandInfo] {
|
|
guard messageText.hasPrefix("/") && !messageText.contains(" ") else { return [] }
|
|
let isGeoPublic = locationChannelsModel.selectedChannel.isLocation
|
|
let isGeoDM = privateConversationModel.selectedPeerID?.isGeoDM == true
|
|
return CommandInfo.all(isGeoPublic: isGeoPublic, isGeoDM: isGeoDM).filter { command in
|
|
command.alias.starts(with: messageText.lowercased())
|
|
}
|
|
}
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading, spacing: 0) {
|
|
ForEach(filteredCommands) { command in
|
|
Button {
|
|
messageText = command.alias + " "
|
|
} label: {
|
|
buttonRow(for: command)
|
|
}
|
|
.buttonStyle(.plain)
|
|
.background(Color.gray.opacity(0.1))
|
|
}
|
|
}
|
|
.background(backgroundColor)
|
|
.overlay(
|
|
RoundedRectangle(cornerRadius: 4)
|
|
.stroke(secondaryTextColor.opacity(0.3), lineWidth: 1)
|
|
)
|
|
}
|
|
|
|
private func buttonRow(for command: CommandInfo) -> some View {
|
|
HStack {
|
|
Text(command.alias)
|
|
.font(.bitchatSystem(size: 11, design: .monospaced))
|
|
.foregroundColor(textColor)
|
|
.fontWeight(.medium)
|
|
|
|
if let placeholder = command.placeholder {
|
|
Text(placeholder)
|
|
.font(.bitchatSystem(size: 10, design: .monospaced))
|
|
.foregroundColor(secondaryTextColor.opacity(0.8))
|
|
}
|
|
|
|
Spacer()
|
|
|
|
Text(command.description)
|
|
.font(.bitchatSystem(size: 10, design: .monospaced))
|
|
.foregroundColor(secondaryTextColor)
|
|
}
|
|
.padding(.horizontal, 12)
|
|
.padding(.vertical, 3)
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
}
|
|
}
|
|
|
|
@available(iOS 17, macOS 14, *)
|
|
#Preview {
|
|
@Previewable @State var messageText: String = "/"
|
|
let keychain = KeychainManager()
|
|
let viewModel = ChatViewModel(
|
|
keychain: keychain,
|
|
idBridge: NostrIdentityBridge(),
|
|
identityManager: SecureIdentityStateManager(keychain)
|
|
)
|
|
let privateConversationModel = PrivateConversationModel(
|
|
chatViewModel: viewModel,
|
|
conversationStore: viewModel.conversationStore
|
|
)
|
|
let locationChannelsModel = LocationChannelsModel()
|
|
|
|
CommandSuggestionsView(
|
|
messageText: $messageText,
|
|
textColor: .green,
|
|
backgroundColor: .primary,
|
|
secondaryTextColor: .secondary
|
|
)
|
|
.environmentObject(privateConversationModel)
|
|
.environmentObject(locationChannelsModel)
|
|
}
|