Files
openworm/src/bin/client/ui/friends.rs
2026-02-21 00:19:57 -05:00

114 lines
4.0 KiB
Rust

use openworm::net::{AddFriend, AddFriendResp, GenerateToken, RequestFriends, ServerPerms};
use super::*;
pub fn view(rsc: &mut Rsc, session: &Session) -> StrongWidget {
(
gen_token(rsc, session),
add_friend_area(rsc, session),
friends_list(rsc, session),
)
.span(Dir::DOWN)
.add_strong(rsc)
}
fn add_friend_area(rsc: &mut Rsc, session: &Session) -> WeakWidget {
let username_field = field("", "username").add(rsc);
let add = Button::submit("add friend", rsc);
let con = session.con.clone();
rsc.events.register(add, Submit, move |ctx, rsc| {
let con = con.clone();
let username = username_field.edit(rsc).take();
add.disable(rsc);
rsc.tasks.spawn(async move |mut ctx| {
let Ok(resp) = con.request(AddFriend { username }).await else {
ctx.update(move |ctx, rsc| {
ctx.error("failed to add user", rsc);
});
return;
};
ctx.update(move |ctx, rsc| {
add.enable(rsc);
match resp {
AddFriendResp::Ok => {}
AddFriendResp::UnknownUser => {
ctx.error("unknown user", rsc);
}
AddFriendResp::CannotAddSelf => {
ctx.error("cannot add self", rsc);
}
AddFriendResp::AlreadySent => {
ctx.error("already sent request to user", rsc);
}
AddFriendResp::AlreadyFriends => {
ctx.error("already friends with user", rsc);
}
}
});
});
});
(field_box(username_field).width(300), add.width(200))
.span(Dir::RIGHT)
.add(rsc)
}
fn gen_token(rsc: &mut Rsc, session: &Session) -> WeakWidget {
let generate = Button::normal("generate token", rsc);
let con = session.con.clone();
let token = wtext("")
.size(30)
.editable(EditMode::SingleLine)
.attr::<Selectable>(())
.add(rsc);
rsc.events.register(generate, Submit, move |_, rsc| {
let con = con.clone();
token.edit(rsc).set("loading...");
rsc.spawn_task(async move |mut ctx| {
let resp = con
.request(GenerateToken {
perms: ServerPerms::NONE,
})
.await;
ctx.update(move |_, rsc| match resp {
Ok(resp) => {
token.edit(rsc).set(&resp.token);
}
Err(_) => {
token.edit(rsc).set("failed to generate token");
}
});
});
});
(generate.width(200), token).span(Dir::RIGHT).add(rsc)
}
fn friends_list(rsc: &mut Rsc, session: &Session) -> WeakWidget {
let ptr = loading_area("loading friends").add(rsc);
let con = session.con.clone();
rsc.events.register(ptr, Draw, move |_, rsc| {
let con = con.clone();
// TODO: maybe have rsc.request method that takes in &con?
// need to also handle error tho
rsc.spawn_task(async move |mut ctx| {
let Ok(resp) = con.request(RequestFriends).await else {
return;
};
ctx.update(move |_, rsc| {
let mut all = Span::empty(Dir::DOWN);
if !resp.incoming.is_empty() {
all.push(section_label("incoming").add_strong(rsc));
all.push(user_list(&resp.incoming, rsc).add_strong(rsc))
}
all.push(section_label("friends").add_strong(rsc));
all.push(user_list(&resp.current, rsc).add_strong(rsc));
if !resp.outgoing.is_empty() {
all.push(section_label("outgoing").add_strong(rsc));
all.push(user_list(&resp.outgoing, rsc).add_strong(rsc))
}
all.set_ptr(ptr, rsc);
});
});
});
ptr
}