116 lines
4.0 KiB
Rust
116 lines
4.0 KiB
Rust
use yew::prelude::*;
|
|
use web_sys::HtmlTextAreaElement;
|
|
|
|
use crate::pages::room::ChatMessage;
|
|
|
|
#[derive(Properties, PartialEq)]
|
|
pub struct ChatSidebarProps {
|
|
pub messages: Vec<ChatMessage>,
|
|
pub on_send_message: Callback<String>,
|
|
}
|
|
|
|
#[function_component(ChatSidebar)]
|
|
pub fn chat_sidebar(props: &ChatSidebarProps) -> Html {
|
|
let input_ref = use_node_ref();
|
|
let message_input = use_state(|| String::new());
|
|
|
|
let on_input_change = {
|
|
let message_input = message_input.clone();
|
|
Callback::from(move |e: InputEvent| {
|
|
let input: HtmlTextAreaElement = e.target_unchecked_into();
|
|
message_input.set(input.value());
|
|
})
|
|
};
|
|
|
|
let on_send = {
|
|
let message_input = message_input.clone();
|
|
let on_send_message = props.on_send_message.clone();
|
|
let input_ref = input_ref.clone();
|
|
Callback::from(move |e: KeyboardEvent| {
|
|
if e.key() == "Enter" && !e.shift_key() {
|
|
e.prevent_default();
|
|
let content = (*message_input).trim().to_string();
|
|
if !content.is_empty() {
|
|
on_send_message.emit(content);
|
|
message_input.set(String::new());
|
|
if let Some(input) = input_ref.cast::<HtmlTextAreaElement>() {
|
|
input.set_value("");
|
|
}
|
|
}
|
|
}
|
|
})
|
|
};
|
|
|
|
let on_send_button = {
|
|
let message_input = message_input.clone();
|
|
let on_send_message = props.on_send_message.clone();
|
|
let input_ref = input_ref.clone();
|
|
Callback::from(move |_: MouseEvent| {
|
|
let content = (*message_input).trim().to_string();
|
|
if !content.is_empty() {
|
|
on_send_message.emit(content);
|
|
message_input.set(String::new());
|
|
if let Some(input) = input_ref.cast::<HtmlTextAreaElement>() {
|
|
input.set_value("");
|
|
}
|
|
}
|
|
})
|
|
};
|
|
|
|
html! {
|
|
<div class="chat-sidebar">
|
|
<div class="chat-header">
|
|
{"Chat"}
|
|
</div>
|
|
|
|
<div class="chat-messages">
|
|
{for props.messages.iter().map(|message| {
|
|
html! {
|
|
<div key={message.id.clone()} class="chat-message">
|
|
<div class="chat-message-author">
|
|
{&message.author}
|
|
<span style="margin-left: 0.5rem; font-size: 0.75rem; color: var(--lk-fg-2);">
|
|
{message.timestamp.format("%H:%M").to_string()}
|
|
</span>
|
|
</div>
|
|
<div class="chat-message-content">
|
|
{&message.content}
|
|
</div>
|
|
</div>
|
|
}
|
|
})}
|
|
|
|
{if props.messages.is_empty() {
|
|
html! {
|
|
<div style="text-align: center; color: var(--lk-fg-2); margin-top: 2rem;">
|
|
{"No messages yet. Start the conversation!"}
|
|
</div>
|
|
}
|
|
} else {
|
|
html! {}
|
|
}}
|
|
</div>
|
|
|
|
<div class="chat-input-container">
|
|
<textarea
|
|
ref={input_ref}
|
|
class="chat-input"
|
|
placeholder="Type a message..."
|
|
value={(*message_input).clone()}
|
|
oninput={on_input_change}
|
|
onkeydown={on_send}
|
|
rows="2"
|
|
/>
|
|
<button
|
|
class="primary-button"
|
|
style="margin-top: 0.5rem; padding: 0.5rem 1rem;"
|
|
onclick={on_send_button}
|
|
disabled={message_input.trim().is_empty()}
|
|
>
|
|
{"Send"}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
}
|
|
}
|