Compare commits

...

2 Commits

3 changed files with 35 additions and 19 deletions

View File

@ -18,7 +18,7 @@ pub fn App() -> impl IntoView {
// Nostr client subscription for items // Nostr client subscription for items
spawn_local(async move { spawn_local(async move {
let nostr_client = NostrClient::new("wss://relay.damus.io").await.unwrap(); let nostr_client = NostrClient::new("wss://relay.example.com").await.unwrap();
nostr_client.subscribe_to_items(tx.clone()).await.unwrap(); nostr_client.subscribe_to_items(tx.clone()).await.unwrap();
while let Some(content) = rx.recv().await { while let Some(content) = rx.recv().await {

View File

@ -4,8 +4,10 @@ use leptos::*;
pub fn EditableCell( pub fn EditableCell(
value: String, value: String,
on_input: impl Fn(String) + 'static, on_input: impl Fn(String) + 'static,
#[prop(optional)] key: Option<String>, // Optional `key` prop
) -> impl IntoView { ) -> impl IntoView {
let (input_value, set_input_value) = create_signal(value.clone()); let (input_value, set_input_value) = create_signal(value.clone());
let (has_focus, set_has_focus) = create_signal(false); // Track focus state locally
let handle_input = move |e: web_sys::Event| { let handle_input = move |e: web_sys::Event| {
let new_value = event_target_value(&e); let new_value = event_target_value(&e);
@ -13,11 +15,25 @@ pub fn EditableCell(
on_input(new_value); on_input(new_value);
}; };
let handle_focus = move |_: web_sys::FocusEvent| {
set_has_focus.set(true);
};
let handle_blur = move |_: web_sys::FocusEvent| {
set_has_focus.set(false);
};
// Use key to force updates only when necessary
let _key = key.unwrap_or_default();
view! { view! {
<input <input
type="text" type="text"
value={input_value.get()} value={input_value.get()}
on:input=handle_input on:input=handle_input
on:focus=handle_focus
on:blur=handle_blur
class={if has_focus.get() { "focused" } else { "not-focused" }}
/> />
} }
} }

View File

@ -89,7 +89,7 @@ pub fn ItemsList(
name: String::new(), name: String::new(),
description: String::new(), description: String::new(),
tags: vec![], tags: vec![],
reviews:vec![], reviews: vec![],
wikidata_id: None, wikidata_id: None,
}); });
}); });
@ -121,15 +121,15 @@ pub fn ItemsList(
<tr> <tr>
// Editable Name Field with Wikidata Integration // Editable Name Field with Wikidata Integration
<td> <td>
<EditableCell <EditableCell
value=item.name.clone() value=item.name.clone()
on_input=move |value| update_item(index, "name", value) on_input=move |value| update_item(index, "name", value)
/> key=format!("name-{}", index) // Unique key per cell
/>
<ul> <ul>
{move || { {move || {
let suggestions = wikidata_suggestions.get().to_vec(); let suggestions = wikidata_suggestions.get().to_vec();
suggestions.into_iter().map(|suggestion| { suggestions.into_iter().map(|suggestion| {
// Clone all necessary fields upfront
let label_for_click = suggestion.label.clone(); let label_for_click = suggestion.label.clone();
let label_for_display = suggestion.label.clone(); let label_for_display = suggestion.label.clone();
let description_for_click = suggestion.description.clone().unwrap_or_default(); let description_for_click = suggestion.description.clone().unwrap_or_default();
@ -146,34 +146,34 @@ pub fn ItemsList(
<li on:click=move |_| { <li on:click=move |_| {
set_items.update(|items| { set_items.update(|items| {
if let Some(item) = items.get_mut(index) { if let Some(item) = items.get_mut(index) {
item.description = description_for_click.clone(); // Update description item.description = description_for_click.clone();
item.tags.extend(tags.clone()); // Add tags item.tags.extend(tags.clone());
item.wikidata_id = Some(id.clone()); item.wikidata_id = Some(id.clone());
item.name = label_for_click.clone(); // Use the cloned version for updating item.name = label_for_click.clone();
} }
}); });
}> }>
{ format!("{} - {}", label_for_display, description_for_display) } // Use the cloned version for display { format!("{} - {}", label_for_display, description_for_display) }
</li> </li>
} }
}).collect::<Vec<_>>()
}).collect::<Vec<_>>()
}} }}
</ul> </ul>
</td> </td>
// Editable Description Field // Editable Description Field
<td> <td>
<EditableCell <EditableCell
value=item.description.clone() value=item.description.clone()
on_input=move |value| update_item(index, "description", value) on_input=move |value| update_item(index, "description", value)
/> key=format!("description-{}", index)
/>
</td> </td>
// Tag Editor // Tag Editor
<td> <td>
<TagEditor <TagEditor
tags=item.tags.clone() tags=item.tags.clone()
on_add=move |key, value| add_tag(index, key, value) on_add=move |key, value| add_tag(index, key, value)
on_remove=Arc::new (Mutex:: new (move |tag_index:usize| remove_tag(index, tag_index))) on_remove=Arc::new(Mutex::new(move |tag_index: usize| remove_tag(index, tag_index)))
/> />
</td> </td>
// Actions // Actions