Improve code readability with comments and annotations.

This commit is contained in:
Werner Kroneman 2023-12-10 15:27:50 +01:00
parent 5ba1b454bd
commit 1ddf72d8a4
4 changed files with 39 additions and 2 deletions

View File

@ -19,11 +19,15 @@ use dioxus::core_macro::Props;
use dioxus::hooks::use_state; use dioxus::hooks::use_state;
use dioxus::prelude::*; use dioxus::prelude::*;
/// The props for the room join widget, including:
/// * The event handler for when the user clicks the join button, passing in a room name. This name is not validated in any way.
#[derive(Props)] #[derive(Props)]
pub struct RoomJoinProps<'a> { pub struct RoomJoinProps<'a> {
on_join_room: EventHandler<'a, String>, on_join_room: EventHandler<'a, String>,
} }
/// A simple widget that allows the user to join a room by typing
/// its name into a text field and clicking a button.
pub fn RoomJoinWidget<'a>(cx: Scope<'a, RoomJoinProps>) -> Element<'a> { pub fn RoomJoinWidget<'a>(cx: Scope<'a, RoomJoinProps>) -> Element<'a> {
let room = use_state(cx, || "".to_owned()); let room = use_state(cx, || "".to_owned());

View File

@ -19,33 +19,47 @@ use dioxus::core_macro::Props;
use dioxus::prelude::*; use dioxus::prelude::*;
use jid::BareJid; use jid::BareJid;
/// The props for the room list widget, including:
/// * The list of rooms to show.
/// * The event handler for when the user clicks a room.
/// * The event handler for when the user clicks the "leave" button for a room.
#[derive(Props)] #[derive(Props)]
pub struct RoomListProps<'a> { pub struct RoomListProps<'a> {
rooms: Vec<BareJid>, rooms: Vec<BareJid>, // TODO: Should this be a reference of some kind?
on_room_picked: EventHandler<'a, BareJid>, on_room_picked: EventHandler<'a, BareJid>,
on_room_left: EventHandler<'a, BareJid>, on_room_left: EventHandler<'a, BareJid>,
} }
/// A Dioxus component that renders a list of rooms /// A widget that shows a list of rooms known to the client.
///
/// It provides an overview of the rooms, and allows the user to
/// select a room or to leave it.
///
/// How "selecting" and "leaving" a room is handled is up to the context.
pub fn RoomList<'a>(cx: Scope<'a, RoomListProps>) -> Element<'a> { pub fn RoomList<'a>(cx: Scope<'a, RoomListProps>) -> Element<'a> {
render! { render! {
// An <ul> with a list of <li> elements, each containing a room name and a button.
ul { ul {
list_style: "none", list_style: "none",
flex_grow: 1, flex_grow: 1,
margin: 0, margin: 0,
padding: 0, padding: 0,
for room in cx.props.rooms.iter() { for room in cx.props.rooms.iter() {
// A single <li> element, containing a room name and a button.
rsx! { li { rsx! { li {
display: "flex", display: "flex",
flex_direction: "row", flex_direction: "row",
onclick: |_evt| cx.props.on_room_picked.call(room.to_owned()), onclick: |_evt| cx.props.on_room_picked.call(room.to_owned()),
// The room name inside a <div>.
div { div {
flex_grow: 1, flex_grow: 1,
"{room}" "{room}"
} }
// A button to leave the room.
button { button {
onclick: |evt| { onclick: |evt| {

View File

@ -22,6 +22,10 @@ use dioxus::hooks::use_state;
use dioxus::prelude::*; use dioxus::prelude::*;
use jid::BareJid; use jid::BareJid;
/// The props for the room view widget, including:
/// * The room identifier (BareJid) to display.
/// * The list of messages to display.
/// * The event handler for when the user sends a message.
#[derive(Props)] #[derive(Props)]
pub struct RoomViewProps<'a> { pub struct RoomViewProps<'a> {
room: BareJid, room: BareJid,
@ -29,6 +33,7 @@ pub struct RoomViewProps<'a> {
on_message_sent: EventHandler<'a, String>, on_message_sent: EventHandler<'a, String>,
} }
/// A widget that shows a room, including a list of messages and a widget to send new messages.
pub fn RoomView<'a>(cx: Scope<'a, RoomViewProps>) -> Element<'a> { pub fn RoomView<'a>(cx: Scope<'a, RoomViewProps>) -> Element<'a> {
let _message = use_state(cx, || "".to_owned()); let _message = use_state(cx, || "".to_owned());
@ -39,12 +44,16 @@ pub fn RoomView<'a>(cx: Scope<'a, RoomViewProps>) -> Element<'a> {
display: "flex", display: "flex",
background_color: "#166322", background_color: "#166322",
flex_direction: "column", flex_direction: "column",
// The room name, as an H2 (H1 is reserved for the app name).
h2 { h2 {
margin: 0, margin: 0,
padding: 0, padding: 0,
border_bottom: "1px solid lightgray", border_bottom: "1px solid lightgray",
"{cx.props.room}" "{cx.props.room}"
} }
// The list of messages, as an <ul>, where each message is an <li>.
ul { ul {
flex_grow: 1, flex_grow: 1,
overflow_y: "scroll", overflow_y: "scroll",
@ -54,6 +63,8 @@ pub fn RoomView<'a>(cx: Scope<'a, RoomViewProps>) -> Element<'a> {
} } } }
} }
} }
// The widget to compose new messages and send them.
SendMessage { SendMessage {
on_message_sent: |x:String| cx.props.on_message_sent.call(x), on_message_sent: |x:String| cx.props.on_message_sent.call(x),
} }

View File

@ -24,13 +24,19 @@ pub struct SendMessageProps<'a> {
on_message_sent: EventHandler<'a, String>, on_message_sent: EventHandler<'a, String>,
} }
/// A simple widget that allows the user to compose a message and a button to send it.
pub fn SendMessage<'a>(cx: Scope<'a, SendMessageProps>) -> Element<'a> { pub fn SendMessage<'a>(cx: Scope<'a, SendMessageProps>) -> Element<'a> {
// The message body being written.
let message = use_state(cx, || "".to_owned()); let message = use_state(cx, || "".to_owned());
render! { render! {
div { div {
class: "send-message-widget",
display: "flex", display: "flex",
flex_direction: "row", flex_direction: "row",
// A non-resizable text area for the message body.
textarea { textarea {
resize: "none", resize: "none",
flex_grow: 1, flex_grow: 1,
@ -38,6 +44,8 @@ pub fn SendMessage<'a>(cx: Scope<'a, SendMessageProps>) -> Element<'a> {
message.set(evt.value.clone()); message.set(evt.value.clone());
} }
} }
// A button to send the message.
button { button {
height: "100%", height: "100%",
onclick: move |_| { onclick: move |_| {