Compare commits
2 Commits
8b89b635a8
...
863f05f8bc
Author | SHA1 | Date |
---|---|---|
ryan | 863f05f8bc | |
ryan | 9da8b03de2 |
|
@ -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 {
|
||||||
|
|
|
@ -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" }}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue