30 std::shared_ptr<async::async_queue<events::display_filter_input_t>>
display;
31 std::shared_ptr<async::async_queue<events::transport::in_t>>
transport;
32 std::shared_ptr<async::async_queue<events::session_orchestrator::in_t>>
session;
43 : bridge_(bridge), display_out_queue_(queues.display), transport_out_queue_(queues.transport),
44 session_out_queue_(queues.session), connection_monitor_out_queue_(queues.
connection_monitor)
53 template<events::Command T>
auto handle(
const T &command)
const ->
void { handle_impl(command); }
60 [[nodiscard]]
auto get_bridge() -> std::shared_ptr<Bridge> {
return bridge_; }
63 template<
typename... Args>
auto emit(fmt::format_string<Args...> format_string, Args &&...args)
const ->
void
65 display_out_queue_->push(
67 .contact_rdx = std::nullopt,
72 auto handle_impl(
const events::help & )
const ->
void
74 std::ignore = initialized_;
76 "Interactive Commands:\n"
77 " /broadcast <message> Send to all local peers\n"
78 " /chat <contact> Enter chat mode with contact\n"
79 " /connect <relay> Add Nostr relay\n"
80 " /disconnect Disconnect from Nostr relay\n"
81 " /identities List discovered identities\n"
82 " /leave Exit chat mode\n"
83 " /mode <internet|mesh|hybrid> Switch transport mode\n"
84 " /peers List discovered peers\n"
85 " /publish Publish identity to network\n"
86 " /scan Force peer discovery\n"
87 " /send <peer> <message> Send encrypted message to peer\n"
88 " /sessions Show encrypted sessions\n"
89 " /status Show network status\n"
90 " /trust <peer> [alias] Establish session with peer\n"
91 " /verify <peer> Show safety numbers\n"
92 " /version Show version information\n"
93 " /quit Exit interactive mode\n");
96 auto handle_impl(
const events::peers & )
const ->
void
98 std::ignore = initialized_;
100 "Connected Peers: (transport layer not implemented)\n"
101 " No peers discovered yet\n");
104 auto handle_impl(
const events::status & )
const ->
void
106 std::ignore = initialized_;
108 connection_monitor_out_queue_->push(events::connection_monitor::query_status{});
110 std::string node_fingerprint = bridge_->get_node_fingerprint();
111 emit(
"\nCrypto Status:\n Node Fingerprint: {}\n", node_fingerprint);
114 auto handle_impl(
const events::sessions & )
const ->
void
116 std::ignore = initialized_;
117 auto contacts = bridge_->list_contacts();
119 if (contacts.empty()) {
120 emit(
"No active sessions\n");
124 emit(
"Active Sessions ({}):\n", contacts.size());
125 for (
const auto &contact : contacts) {
126 if (contact.user_alias.empty()) {
127 emit(
" {}\n", contact.rdx_fingerprint);
129 emit(
" {} ({})\n", contact.user_alias, contact.rdx_fingerprint);
134 auto handle_impl(
const events::identities & )
const ->
void
136 std::ignore = initialized_;
137 session_out_queue_->push(events::list_identities{});
140 auto handle_impl(
const events::publish_identity & )
const ->
void
142 std::ignore = initialized_;
143 session_out_queue_->push(events::publish_identity{});
144 emit(
"Publishing identity to network...\n");
147 auto handle_impl(
const events::unpublish_identity & )
const ->
void
149 std::ignore = initialized_;
150 session_out_queue_->push(events::unpublish_identity{});
151 emit(
"Unpublishing identity from network...\n");
154 auto handle_impl(
const events::scan & )
const ->
void
156 std::ignore = initialized_;
158 "Scanning for BLE peers... (BLE transport not implemented)\n"
159 " No peers found\n");
162 auto handle_impl(
const events::version & )
const ->
void
164 std::ignore = initialized_;
165 emit(
"Radix Relay v{}\n", radix_relay::cmake::project_version);
168 auto handle_impl(
const events::mode &command)
const ->
void
170 std::ignore = initialized_;
171 if (command.new_mode ==
"internet" or command.new_mode ==
"mesh" or command.new_mode ==
"hybrid") {
172 emit(
"Switched to {} mode\n", command.new_mode);
174 emit(
"Invalid mode. Use: internet, mesh, or hybrid\n");
178 auto handle_impl(
const events::send &command)
const ->
void
180 std::ignore = initialized_;
181 if (not command.peer.empty() and not command.message.empty()) {
182 session_out_queue_->push(command);
183 emit(
"Sending '{}' to '{}'...\n", command.message, command.peer);
185 emit(
"Usage: send <peer> <message>\n");
189 auto handle_impl(
const events::broadcast &command)
const ->
void
191 std::ignore = initialized_;
192 if (not command.message.empty()) {
193 emit(
"Broadcasting '{}' to all local peers (not implemented)\n", command.message);
195 emit(
"Usage: broadcast <message>\n");
199 auto handle_impl(
const events::connect &command)
const ->
void
201 std::ignore = initialized_;
202 if (not command.relay.empty()) {
203 session_out_queue_->push(command);
204 emit(
"Connecting to Nostr relay {}\n", command.relay);
206 emit(
"Usage: connect <relay>\n");
210 auto handle_impl(
const events::disconnect & )
const ->
void
212 std::ignore = initialized_;
213 transport_out_queue_->push(events::transport::disconnect{});
214 emit(
"Disconnecting from Nostr relay\n");
217 auto handle_impl(
const events::trust &command)
const ->
void
219 std::ignore = initialized_;
220 if (not command.peer.empty()) {
221 session_out_queue_->push(command);
222 emit(
"Establishing session with {}...\n", command.peer);
224 emit(
"Usage: trust <peer> [alias]\n");
228 auto handle_impl(
const events::verify &command)
const ->
void
230 std::ignore = initialized_;
231 if (not command.peer.empty()) {
232 emit(
"Safety numbers for {} (Signal Protocol not implemented)\n", command.peer);
234 emit(
"Usage: verify <peer>\n");
238 auto handle_impl(
const events::chat &command)
const ->
void
240 std::ignore = initialized_;
241 if (command.contact.empty()) {
242 emit(
"Usage: /chat <contact>\n");
247 const auto contact = bridge_->lookup_contact(command.contact);
248 display_out_queue_->push(events::enter_chat_mode{ .rdx_fingerprint = contact.rdx_fingerprint });
249 const auto display_name = contact.user_alias.empty() ? contact.rdx_fingerprint : contact.user_alias;
250 emit(
"Entering chat with {} ({})\n", display_name, contact.rdx_fingerprint);
251 }
catch (
const std::exception & ) {
252 emit(
"Contact not found: {}\n", command.contact);
256 auto handle_impl(
const events::leave & )
const ->
void
258 std::ignore = initialized_;
259 display_out_queue_->push(events::exit_chat_mode{});
260 emit(
"Exiting chat mode\n");
263 std::shared_ptr<Bridge> bridge_;
264 std::shared_ptr<async::async_queue<events::display_filter_input_t>> display_out_queue_;
265 std::shared_ptr<async::async_queue<events::transport::in_t>> transport_out_queue_;
266 std::shared_ptr<async::async_queue<events::session_orchestrator::in_t>> session_out_queue_;
267 std::shared_ptr<async::async_queue<events::connection_monitor::in_t>> connection_monitor_out_queue_;
268 bool initialized_ =
true;