Compare commits

..

2 Commits

Author SHA1 Message Date
spinline
6106d1cd22 fix(ui): prevent selection checkboxes from opening torrent details sheet
All checks were successful
Build MIPS Binary / build (push) Successful in 1m56s
2026-02-21 00:50:26 +03:00
spinline
50b83ebacf chore(ui): remove debugging logs for sse connection
All checks were successful
Build MIPS Binary / build (push) Successful in 1m56s
2026-02-21 00:44:50 +03:00
2 changed files with 37 additions and 43 deletions

View File

@@ -597,10 +597,12 @@ fn TorrentRow(
on:click=move |_| store.selected_torrent.set(Some(stored_hash.get_value())) on:click=move |_| store.selected_torrent.set(Some(stored_hash.get_value()))
> >
<DataTableCell class="w-12 px-4"> <DataTableCell class="w-12 px-4">
<Checkbox <div on:click=move |e| e.stop_propagation()>
checked=is_selected <Checkbox
on_checked_change=on_select checked=is_selected
/> on_checked_change=on_select
/>
</div>
</DataTableCell> </DataTableCell>
{move || visible_columns.get().contains("Name").then({ {move || visible_columns.get().contains("Name").then({
@@ -730,17 +732,23 @@ fn TorrentCard(
} }
) )
on:click=move |_| { on:click=move |_| {
let current = is_selected.get();
on_select.run(!current);
store.selected_torrent.set(Some(stored_hash.get_value())); store.selected_torrent.set(Some(stored_hash.get_value()));
} }
> >
<div class="p-4 space-y-3"> <div class="p-4 space-y-3">
<div class="flex justify-between items-start gap-3"> <div class="flex justify-between items-start gap-3">
<div class="flex-1 min-w-0"> <div class="flex items-start gap-3 flex-1 min-w-0">
<h3 class="text-sm font-bold leading-tight line-clamp-2 break-all">{t_name.clone()}</h3> <div on:click=move |e| e.stop_propagation() class="mt-0.5">
<Checkbox
checked=is_selected
on_checked_change=on_select
/>
</div>
<div class="flex-1 min-w-0">
<h3 class="text-sm font-bold leading-tight line-clamp-2 break-all">{t_name.clone()}</h3>
</div>
</div> </div>
<Badge variant=status_variant class="uppercase tracking-wider text-[10px]"> <Badge variant=status_variant class="uppercase tracking-wider text-[10px] shrink-0">
{format!("{:?}", t.status)} {format!("{:?}", t.status)}
</Badge> </Badge>
</div> </div>

View File

@@ -88,13 +88,10 @@ pub fn provide_torrent_store() {
let mut disconnect_notified = false; let mut disconnect_notified = false;
loop { loop {
log::info!("[SSE] Attempting to connect to /api/events...");
let es_result = EventSource::new("/api/events"); let es_result = EventSource::new("/api/events");
match es_result { match es_result {
Ok(mut es) => { Ok(mut es) => {
log::info!("[SSE] EventSource instantiated successfully.");
if let Ok(mut stream) = es.subscribe("message") { if let Ok(mut stream) = es.subscribe("message") {
log::info!("[SSE] Subscribed to 'message' events.");
let mut got_first_message = false; let mut got_first_message = false;
while let Some(Ok((_, msg))) = stream.next().await { while let Some(Ok((_, msg))) = stream.next().await {
if !got_first_message { if !got_first_message {
@@ -108,40 +105,29 @@ pub fn provide_torrent_store() {
} }
if let Some(data_str) = msg.data().as_string() { if let Some(data_str) = msg.data().as_string() {
log::info!("[SSE] Received message: {:?}", data_str.chars().take(50).collect::<String>()); if let Ok(bytes) = BASE64.decode(&data_str) {
match BASE64.decode(&data_str) { if let Ok(event) = rmp_serde::from_slice::<AppEvent>(&bytes) {
Ok(bytes) => { match event {
match rmp_serde::from_slice::<AppEvent>(&bytes) { AppEvent::FullList(list, _) => {
Ok(event) => { torrents_for_sse.update(|map| {
match event { let new_hashes: std::collections::HashSet<String> = list.iter().map(|t| t.hash.clone()).collect();
AppEvent::FullList(list, _) => { map.retain(|hash, _| new_hashes.contains(hash));
torrents_for_sse.update(|map| { for new_torrent in list { map.insert(new_torrent.hash.clone(), new_torrent); }
let new_hashes: std::collections::HashSet<String> = list.iter().map(|t| t.hash.clone()).collect(); });
map.retain(|hash, _| new_hashes.contains(hash)); }
for new_torrent in list { map.insert(new_torrent.hash.clone(), new_torrent); } AppEvent::Update(patch) => {
}); if let Some(hash) = patch.hash.clone() {
} torrents_for_sse.update(|map| { if let Some(t) = map.get_mut(&hash) { t.apply(patch); } });
AppEvent::Update(patch) => { }
if let Some(hash) = patch.hash.clone() { }
torrents_for_sse.update(|map| { if let Some(t) = map.get_mut(&hash) { t.apply(patch); } }); AppEvent::Stats(stats) => { global_stats_for_sse.set(stats); }
} AppEvent::Notification(n) => {
} show_toast(n.level.clone(), n.message.clone());
AppEvent::Stats(stats) => { global_stats_for_sse.set(stats); } if n.message.contains("tamamlandı") || n.level == shared::NotificationLevel::Error {
AppEvent::Notification(n) => { show_browser_notification("VibeTorrent", &n.message);
show_toast(n.level.clone(), n.message.clone());
if n.message.contains("tamamlandı") || n.level == shared::NotificationLevel::Error {
show_browser_notification("VibeTorrent", &n.message);
}
}
} }
},
Err(e) => {
log::error!("[SSE] Failed to deserialize AppEvent: {:?}", e);
} }
} }
},
Err(e) => {
log::error!("[SSE] Failed to decode base64: {:?}", e);
} }
} }
} }