mirror of
https://github.com/nitnelave/lldap.git
synced 2023-04-12 14:25:13 +00:00
Updates
This commit is contained in:
parent
970af4f01a
commit
590825fe73
26
Cargo.lock
generated
26
Cargo.lock
generated
@ -352,6 +352,12 @@ version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
|
||||
|
||||
[[package]]
|
||||
name = "anymap2"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.6"
|
||||
@ -2434,6 +2440,7 @@ dependencies = [
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"yew",
|
||||
"yew-agent",
|
||||
"yew-router",
|
||||
"yew_form",
|
||||
"yew_form_derive",
|
||||
@ -4798,6 +4805,25 @@ dependencies = [
|
||||
"yew-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yew-agent"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "616700dc3851945658c44ba4477ede6b77c795462fbbb9b0ad9a8b6273a3ca77"
|
||||
dependencies = [
|
||||
"anymap2",
|
||||
"bincode",
|
||||
"gloo-console",
|
||||
"gloo-utils",
|
||||
"js-sys",
|
||||
"serde",
|
||||
"slab",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"yew",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yew-macro"
|
||||
version = "0.19.3"
|
||||
|
@ -24,6 +24,7 @@ wasm-bindgen = "0.2"
|
||||
wasm-bindgen-futures = "*"
|
||||
yew = "0.19.3"
|
||||
yew-router = "0.16"
|
||||
yew-agent = "0.1.0"
|
||||
|
||||
# Needed because of https://github.com/tkaitchuck/aHash/issues/95
|
||||
indexmap = "=1.6.2"
|
||||
|
@ -350,15 +350,7 @@ impl App {
|
||||
id="dropdownUser"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="32"
|
||||
height="32"
|
||||
fill="currentColor"
|
||||
class="bi bi-person-circle"
|
||||
viewBox="0 0 16 16">
|
||||
<path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
|
||||
<path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"/>
|
||||
</svg>
|
||||
<Avatar username={user_id.clone()} width=32 height=32 />
|
||||
<span class="ms-2">
|
||||
{user_id}
|
||||
</span>
|
||||
|
@ -1,7 +1,10 @@
|
||||
use crate::infra::common_component::{CommonComponent, CommonComponentParts};
|
||||
use crate::{
|
||||
components::avatar_event_bus::AvatarEventBus,
|
||||
infra::common_component::{CommonComponent, CommonComponentParts}};
|
||||
use anyhow::{bail, Result};
|
||||
use graphql_client::GraphQLQuery;
|
||||
use yew::prelude::*;
|
||||
use yew::{prelude::*};
|
||||
use yew_agent::{Bridge, Bridged};
|
||||
|
||||
#[derive(GraphQLQuery)]
|
||||
#[graphql(
|
||||
@ -17,6 +20,7 @@ pub struct Avatar {
|
||||
/// The user info. If none, the error is in `error`. If `error` is None, then we haven't
|
||||
/// received the server response yet.
|
||||
avatar: Option<String>,
|
||||
_producer: Box<dyn Bridge<AvatarEventBus>>,
|
||||
}
|
||||
|
||||
/// State machine describing the possible transitions of the component state.
|
||||
@ -35,16 +39,16 @@ pub struct Props {
|
||||
}
|
||||
|
||||
impl CommonComponent<Avatar> for Avatar {
|
||||
fn handle_msg(&mut self, msg: <Self as Component>::Message) -> Result<bool> {
|
||||
fn handle_msg(&mut self, ctx: &Context<Self>, msg: <Self as Component>::Message) -> Result<bool> {
|
||||
match msg {
|
||||
Msg::UserAvatarResponse(response) => match response {
|
||||
Ok(user) => self.avatar = user.user.avatar,
|
||||
Err(e) => {
|
||||
self.avatar = None;
|
||||
bail!("Error getting user details: {}", e);
|
||||
bail!("Error getting user avatar: {}", e);
|
||||
}
|
||||
},
|
||||
Msg::Update => self.get_user_avatar(),
|
||||
Msg::Update => self.get_user_avatar(ctx),
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
@ -55,16 +59,15 @@ impl CommonComponent<Avatar> for Avatar {
|
||||
}
|
||||
|
||||
impl Avatar {
|
||||
fn get_user_avatar(&mut self) {
|
||||
if self.common.username.len() > 0 {
|
||||
self.common.call_graphql::<GetUserAvatar, _>(
|
||||
get_user_avatar::Variables {
|
||||
id: self.common.username.clone(),
|
||||
},
|
||||
Msg::UserAvatarResponse,
|
||||
"Error trying to fetch user avatar",
|
||||
)
|
||||
}
|
||||
fn get_user_avatar(&mut self, ctx: &Context<Self>) {
|
||||
self.common.call_graphql::<GetUserAvatar, _>(
|
||||
ctx,
|
||||
get_user_avatar::Variables {
|
||||
id: ctx.props().username.clone(),
|
||||
},
|
||||
Msg::UserAvatarResponse,
|
||||
"Error trying to fetch user avatar",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,36 +75,33 @@ impl Component for Avatar {
|
||||
type Message = Msg;
|
||||
type Properties = Props;
|
||||
|
||||
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
|
||||
fn create(ctx: &Context<Self>) -> Self {
|
||||
let mut avatar = Self {
|
||||
common: CommonComponentParts::<Self>::create(props, link),
|
||||
common: CommonComponentParts::<Self>::create(),
|
||||
avatar: None,
|
||||
_producer: AvatarEventBus::bridge(ctx.link().callback(|_| Msg::Update)),
|
||||
};
|
||||
avatar.get_user_avatar();
|
||||
avatar.get_user_avatar(ctx);
|
||||
avatar
|
||||
}
|
||||
|
||||
fn update(&mut self, msg: Self::Message) -> ShouldRender {
|
||||
CommonComponentParts::<Self>::update(self, msg)
|
||||
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
|
||||
CommonComponentParts::<Self>::update(self, ctx, msg)
|
||||
}
|
||||
|
||||
fn change(&mut self, props: Self::Properties) -> ShouldRender {
|
||||
self.common.change(props)
|
||||
}
|
||||
|
||||
fn view(&self) -> Html {
|
||||
fn view(&self, ctx: &Context<Self>) -> Html {
|
||||
match &self.avatar {
|
||||
Some(avatar) => html! {
|
||||
<img
|
||||
id="avatarDisplay"
|
||||
src={format!("data:image/jpeg;base64, {}", avatar)}
|
||||
style={format!("max-height:{}px;max-width:{}px;height:auto;width:auto;", self.common.props.height,self.common.props.width)}
|
||||
style={format!("max-height:{}px;max-width:{}px;height:auto;width:auto;", ctx.props().height,ctx.props().width)}
|
||||
alt="Avatar" />
|
||||
},
|
||||
None => html! {
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width={self.common.props.width.to_string()}
|
||||
height={self.common.props.height.to_string()}
|
||||
width={ctx.props().width.to_string()}
|
||||
height={ctx.props().height.to_string()}
|
||||
fill="currentColor"
|
||||
class="bi bi-person-circle"
|
||||
viewBox="0 0 16 16">
|
||||
|
47
app/src/components/avatar_event_bus.rs
Normal file
47
app/src/components/avatar_event_bus.rs
Normal file
@ -0,0 +1,47 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashSet;
|
||||
use yew_agent::{Agent, AgentLink, Context, HandlerId};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub enum Request {
|
||||
Update,
|
||||
}
|
||||
|
||||
pub struct AvatarEventBus {
|
||||
link: AgentLink<AvatarEventBus>,
|
||||
subscribers: HashSet<HandlerId>,
|
||||
}
|
||||
|
||||
impl Agent for AvatarEventBus {
|
||||
type Reach = Context<Self>;
|
||||
type Message = ();
|
||||
type Input = Request;
|
||||
type Output = ();
|
||||
|
||||
fn create(link: AgentLink<Self>) -> Self {
|
||||
Self {
|
||||
link,
|
||||
subscribers: HashSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, _msg: Self::Message) {}
|
||||
|
||||
fn handle_input(&mut self, msg: Self::Input, _id: HandlerId) {
|
||||
match msg {
|
||||
Request::Update => {
|
||||
for sub in self.subscribers.iter() {
|
||||
self.link.respond(*sub, ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn connected(&mut self, id: HandlerId) {
|
||||
self.subscribers.insert(id);
|
||||
}
|
||||
|
||||
fn disconnected(&mut self, id: HandlerId) {
|
||||
self.subscribers.remove(&id);
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ pub mod add_group_member;
|
||||
pub mod add_user_to_group;
|
||||
pub mod app;
|
||||
pub mod avatar;
|
||||
pub mod avatar_event_bus;
|
||||
pub mod change_password;
|
||||
pub mod create_group;
|
||||
pub mod create_user;
|
||||
|
@ -2,6 +2,7 @@ use std::str::FromStr;
|
||||
|
||||
use crate::{
|
||||
components::user_details::User,
|
||||
components::avatar_event_bus::{AvatarEventBus, Request},
|
||||
infra::common_component::{CommonComponent, CommonComponentParts},
|
||||
};
|
||||
use anyhow::{bail, Error, Result};
|
||||
@ -14,6 +15,7 @@ use validator_derive::Validate;
|
||||
use web_sys::{FileList, HtmlInputElement, InputEvent};
|
||||
use yew::prelude::*;
|
||||
use yew_form_derive::Model;
|
||||
use yew_agent::{Dispatched, Dispatcher};
|
||||
|
||||
#[derive(Default)]
|
||||
struct JsFile {
|
||||
@ -72,6 +74,7 @@ pub struct UserDetailsForm {
|
||||
/// True if we just successfully updated the user, to display a success message.
|
||||
just_updated: bool,
|
||||
user: User,
|
||||
avatar_event_bus: Dispatcher<AvatarEventBus>,
|
||||
}
|
||||
|
||||
pub enum Msg {
|
||||
@ -163,6 +166,7 @@ impl Component for UserDetailsForm {
|
||||
just_updated: false,
|
||||
reader: None,
|
||||
user: ctx.props().user.clone(),
|
||||
avatar_event_bus: AvatarEventBus::dispatcher(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -402,6 +406,7 @@ impl UserDetailsForm {
|
||||
self.user.avatar = Some(avatar);
|
||||
}
|
||||
self.just_updated = true;
|
||||
self.avatar_event_bus.send(Request::Update);
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user