Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(groups): Quickprofile chat friend request #1453

Merged
merged 7 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions common/locales/en-US/main.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,8 @@ quickprofile = Quick Profile
.chat-placeholder = Message
.self-edit = Edit Profile
.volume = User Volume
.friend-request = Send Friend Request
.pending-friend-request = Pending Friend Request

toast_actions = Toast Actions
.DisplayChat = Open Chat
Expand Down
49 changes: 42 additions & 7 deletions ui/src/layouts/chats/presentation/chat/group_users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ use kit::{
};
use warp::{crypto::DID, logging::tracing::log};

#[derive(Props, Eq, PartialEq)]
#[derive(Props, PartialEq)]
pub struct Props {
#[props(!optional)]
active_chat: Option<Chat>,
quickprofile_data: UseRef<Option<(f64, f64, Identity, bool)>>,
}

#[allow(non_snake_case)]
Expand All @@ -27,6 +28,8 @@ pub fn GroupUsers(cx: Scope<Props>) -> Element {
let state = use_shared_state::<State>(cx)?;
let friend_prefix = use_state(cx, String::new);

let quickprofile_data = &cx.props.quickprofile_data;

let active_chat = match cx.props.active_chat.as_ref() {
Some(r) => r,
None => return cx.render(rsx!(div {})),
Expand All @@ -46,6 +49,22 @@ pub fn GroupUsers(cx: Scope<Props>) -> Element {
let creator_id_vector = Vec::from_iter(active_chat.creator.iter().cloned());
let creator_id = creator_id_vector.get(0).cloned()?;

let eval = use_eval(cx);
use_effect(cx, (), |_| {
to_owned![eval];
async move {
let _ = eval(
r#"
const right_clickable = document.getElementsByClassName("friend-container");
const prevent_default = function (ev) { ev.preventDefault(); };
for (var i = 0; i < right_clickable.length; i++) {
//Disable default right click actions (opening the inspect element dropdown)
right_clickable.item(i).removeEventListener("contextmenu", prevent_default);
right_clickable.item(i).addEventListener("contextmenu", prevent_default);
}"#,
);
}
});
cx.render(rsx!(
div {
id: "group-users",
Expand All @@ -69,11 +88,13 @@ pub fn GroupUsers(cx: Scope<Props>) -> Element {
},
}
}
render_friends {
group_participants: group_participants,
name_prefix: friend_prefix.clone(),
creator: creator_id,
},
render_friends {
group_participants: group_participants,
name_prefix: friend_prefix.clone(),
creator: creator_id,
is_dev: state.read().configuration.developer.developer_mode,
context_data: quickprofile_data.clone(),
}
}
))
}
Expand All @@ -83,6 +104,8 @@ pub struct FriendsProps {
group_participants: Vec<Identity>,
name_prefix: UseState<String>,
creator: DID,
is_dev: bool,
context_data: UseRef<Option<(f64, f64, Identity, bool)>>,
}

fn render_friends(cx: Scope<FriendsProps>) -> Element {
Expand Down Expand Up @@ -111,6 +134,8 @@ fn render_friends(cx: Scope<FriendsProps>) -> Element {
rsx!(render_friend {
friend: _friend.clone(),
is_creator: friendid == creator,
is_dev: cx.props.is_dev,
context_data: cx.props.context_data.clone(),
}
)})
}
Expand All @@ -131,16 +156,26 @@ fn render_friends(cx: Scope<FriendsProps>) -> Element {
pub struct FriendProps {
friend: Identity,
is_creator: bool,
is_dev: bool,
context_data: UseRef<Option<(f64, f64, Identity, bool)>>,
}
fn render_friend(cx: Scope<FriendProps>) -> Element {
cx.render(rsx!(
div {
class: "friend-container",
aria_label: "Friend Container",
oncontextmenu: move |e| {
cx.props
.context_data.set(Some((e.page_coordinates().x, e.page_coordinates().y, cx.props.friend.to_owned(), true)));
},
UserImage {
platform: cx.props.friend.platform().into(),
status: cx.props.friend.identity_status().into(),
image: cx.props.friend.profile_picture()
image: cx.props.friend.profile_picture(),
oncontextmenu: move |e: Event<MouseData>| {
cx.props
.context_data.set(Some((e.page_coordinates().x, e.page_coordinates().y, cx.props.friend.to_owned(), true)));
}
},
div {
class: "flex-1",
Expand Down
30 changes: 28 additions & 2 deletions ui/src/layouts/chats/presentation/chat/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ use crate::{
chatbar::get_chatbar,
messages::get_messages,
},
scripts::SHOW_CONTEXT,
},
};

use common::state::{ui, Action, State};
use common::state::{ui, Action, Identity, State};

use common::language::get_local_text;

Expand All @@ -47,6 +48,25 @@ pub fn Compose(cx: Scope) -> Element {
let show_edit_group: &UseState<Option<Uuid>> = use_state(cx, || None);
let show_group_users: &UseState<Option<Uuid>> = use_state(cx, || None);

let quick_profile_uuid = &*cx.use_hook(|| Uuid::new_v4().to_string());
let quickprofile_data: &UseRef<Option<(f64, f64, Identity, bool)>> = use_ref(cx, || None);
let update_script = use_state(cx, String::new);
let identity_profile = use_state(cx, DID::default);
use_effect(cx, quickprofile_data, |data| {
to_owned![quick_profile_uuid, update_script, identity_profile];
async move {
if let Some((x, y, id, right)) = data.read().as_ref() {
let script = SHOW_CONTEXT
.replace("UUID", &quick_profile_uuid)
.replace("$PAGE_X", &x.to_string())
.replace("$PAGE_Y", &y.to_string())
.replace("$SELF", &right.to_string());
update_script.set(script);
identity_profile.set(id.did_key());
}
}
});

// if the emoji picker is visible, autofocusing on the chatbar will close the emoji picker.
let should_ignore_focus = state.read().ui.ignore_focus || state.read().ui.emoji_picker_visible;
let creator = chat_data.read().active_chat.creator();
Expand Down Expand Up @@ -123,6 +143,7 @@ pub fn Compose(cx: Scope) -> Element {
},
GroupUsers {
active_chat: state.read().get_active_chat(),
quickprofile_data: quickprofile_data.clone(),
}
}
)),
Expand All @@ -139,14 +160,19 @@ pub fn Compose(cx: Scope) -> Element {
}
)
} else {
rsx!(get_messages{})
rsx!(get_messages{quickprofile_data: quickprofile_data.clone()})
},
get_chatbar {
show_edit_group: show_edit_group.clone(),
show_group_users: show_group_users.clone(),
ignore_focus: should_ignore_focus,
is_owner: is_owner,
is_edit_group: is_edit_group,
},
super::quick_profile::QuickProfileContext{
id: quick_profile_uuid,
update_script: update_script,
did_key: identity_profile,
}
}
))
Expand Down
6 changes: 3 additions & 3 deletions ui/src/layouts/chats/presentation/messages/coroutines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use common::{
WARP_CMD_CH,
};

use dioxus_core::Scoped;
use dioxus_core::ScopeState;
use dioxus_hooks::{to_owned, use_coroutine, Coroutine, UnboundedReceiver, UseSharedState};
use futures::{channel::oneshot, pin_mut, StreamExt};

Expand All @@ -21,7 +21,7 @@ use crate::layouts::chats::{
use super::{DownloadTracker, MessagesCommand};

pub fn hangle_msg_scroll(
cx: &Scoped,
cx: &ScopeState,
eval_provider: &crate::utils::EvalProvider,
chat_data: &UseSharedState<ChatData>,
scroll_btn: &UseSharedState<ScrollBtn>,
Expand Down Expand Up @@ -320,7 +320,7 @@ pub fn hangle_msg_scroll(
}

pub fn handle_warp_commands(
cx: &Scoped,
cx: &ScopeState,
state: &UseSharedState<State>,
pending_downloads: &UseSharedState<DownloadTracker>,
) -> Coroutine<MessagesCommand> {
Expand Down
4 changes: 2 additions & 2 deletions ui/src/layouts/chats/presentation/messages/effects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ use crate::{
},
utils,
};
use dioxus_core::Scoped;
use dioxus_core::ScopeState;
use dioxus_hooks::{to_owned, use_effect, Coroutine, UseSharedState};

pub fn init_msg_scroll(
cx: &Scoped,
cx: &ScopeState,
chat_data: &UseSharedState<ChatData>,
eval_provider: &utils::EvalProvider,
ch: Coroutine<()>,
Expand Down
59 changes: 14 additions & 45 deletions ui/src/layouts/chats/presentation/messages/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@ use warp::{

use crate::{
components::emoji_group::EmojiGroup,
layouts::chats::{
data::{self, ChatData, ScrollBtn},
scripts::SHOW_CONTEXT,
},
layouts::chats::data::{self, ChatData, ScrollBtn},
utils::format_timestamp::format_timestamp_timeago,
};

Expand Down Expand Up @@ -70,18 +67,17 @@ pub enum MessagesCommand {
pub type DownloadTracker = HashMap<Uuid, HashSet<warp::constellation::file::File>>;

#[component(no_case_check)]
pub fn get_messages(cx: Scope) -> Element {
pub fn get_messages(
cx: Scope,
quickprofile_data: UseRef<Option<(f64, f64, Identity, bool)>>,
) -> Element {
log::trace!("get_messages");
use_shared_state_provider(cx, || -> DownloadTracker { HashMap::new() });
let state = use_shared_state::<State>(cx)?;
let chat_data = use_shared_state::<ChatData>(cx)?;
let scroll_btn = use_shared_state::<ScrollBtn>(cx)?;
let pending_downloads = use_shared_state::<DownloadTracker>(cx)?;

let quick_profile_uuid = &*cx.use_hook(|| Uuid::new_v4().to_string());
let identity_profile = use_state(cx, Identity::default);
let update_script = use_state(cx, String::new);

let eval = use_eval(cx);
let ch = coroutines::hangle_msg_scroll(cx, eval, chat_data, scroll_btn);
effects::init_msg_scroll(cx, chat_data, eval, ch);
Expand Down Expand Up @@ -140,52 +136,25 @@ pub fn get_messages(cx: Scope) -> Element {
loop_over_message_groups {
groups: data::create_message_groups(chat_data.read().active_chat.my_id().did_key(), chat_data.read().active_chat.messages()),
active_chat_id: chat_data.read().active_chat.id(),
on_context_menu_action: move |(e, id): (Event<MouseData>, Identity)| {
on_context_menu_action: move |(e, mut id): (Event<MouseData>, Identity)| {
let own = state.read().get_own_identity().did_key().eq(&id.did_key());
if !identity_profile.get().eq(&id) {
let id = if own {
let mut id = id;
id.set_identity_status(IdentityStatus::Online);
id
} else {
id
};
identity_profile.set(id);
}
//Dont think there is any way of manually moving elements via dioxus
let script = SHOW_CONTEXT
.replace("UUID", quick_profile_uuid)
.replace("$PAGE_X", &e.page_coordinates().x.to_string())
.replace("$PAGE_Y", &e.page_coordinates().y.to_string())
.replace("$SELF", &own.to_string());
update_script.set(script);
if own {
id.set_identity_status(IdentityStatus::Online);
};
quickprofile_data.set(Some((e.page_coordinates().x, e.page_coordinates().y, id.clone(), own)));
}
},
render_pending_messages_listener {
on_context_menu_action: move |(e, mut id): (Event<MouseData>, Identity)| {
let own = state.read().get_own_identity().did_key().eq(&id.did_key());
if !identity_profile.get().eq(&id) {
if own {
id.set_identity_status(IdentityStatus::Online);
}
identity_profile.set(id);
}
//Dont think there is any way of manually moving elements via dioxus
let script = SHOW_CONTEXT
.replace("UUID", quick_profile_uuid)
.replace("$PAGE_X", &e.page_coordinates().x.to_string())
.replace("$PAGE_Y", &e.page_coordinates().y.to_string())
.replace("$SELF", &own.to_string());
update_script.set(script);
if own {
id.set_identity_status(IdentityStatus::Online);
};
quickprofile_data.set(Some((e.page_coordinates().x, e.page_coordinates().y, id.clone(), own)));
}
}
)
}
},
super::quick_profile::QuickProfileContext{
id: quick_profile_uuid,
update_script: update_script,
did_key: identity_profile.did_key()
}
))
}
Expand Down
Loading
Loading