summaryrefslogtreecommitdiffstats
path: root/src/components/roster_list.rs
blob: 21a96666b31549723ece47e0bded6d9ed6a62ac2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use std::collections::HashSet;

use contact_request_manager::AddContact;
use jid::BareJID;
use js_sys::{wasm_bindgen::UnwrapThrowExt, Object, Reflect, JSON};
use leptos::{html::Div, prelude::*};
use overlay_scrollbars::OverlayScrollbars;
use reactive_stores::Store;
use roster_list_item::RosterListItem;
use tracing::debug;

use crate::{
    components::icon::IconComponent,
    icon::Icon,
    open_chats::{OpenChatsPanel, OpenChatsPanelStoreFields},
    roster::{Roster, RosterStoreFields},
};

mod contact_request_manager;
mod roster_list_item;

#[component]
pub fn RosterList() -> impl IntoView {
    let requests: ReadSignal<HashSet<BareJID>> =
        use_context().expect("no pending subscriptions in context");

    let open_chats: Store<OpenChatsPanel> =
        use_context().expect("no open chats panel store in context");

    let roster: Store<Roster> = use_context().expect("no roster in context");
    let (open_add_contact, set_open_add_contact) = signal(false);
    let open_chat = Memo::new(move |_| open_chats.chat_view().get());
    provide_context(open_chat);

    let roster_list: NodeRef<Div> = NodeRef::new();
    let roster_list_viewport: NodeRef<Div> = NodeRef::new();

    let _scrollbars = Effect::new(move |_| {
        if let Some(buffer) = roster_list.get() {
            if let Some(viewport) = roster_list_viewport.get() {
                let elements_obj = Object::new();
                Reflect::set(&elements_obj, &"viewport".into(), &viewport.into()).unwrap_throw();
                let element_obj = Object::new();
                Reflect::set(&elements_obj, &"elements".into(), &elements_obj).unwrap_throw();
                Reflect::set(&element_obj, &"target".into(), &buffer.into()).unwrap_throw();
                // let element = Object::define_property(&Object::define_property(&Object::new(), &"target".into(), &buffer.into()), &"elements".into(), &Object::define_property(&Object::new(), &"viewport".into(), &viewport.into()));
                debug!(
                    "scrollable element: {}",
                    JSON::stringify(&element_obj.clone().into()).unwrap_throw()
                );
                OverlayScrollbars(element_obj, Object::new());
            }
        }
    });

    let add_contact: NodeRef<Div> = NodeRef::new();
    let add_contact_viewport: NodeRef<Div> = NodeRef::new();

    let _scrollbars = Effect::new(move |_| {
        if let Some(buffer) = add_contact.get() {
            if let Some(viewport) = add_contact_viewport.get() {
                let scrollbars_obj = Object::new();
                Reflect::set(&scrollbars_obj, &"theme".into(), &"os-macaw".into()).unwrap_throw();
                Reflect::set(&scrollbars_obj, &"move".into(), &"leave".into()).unwrap_throw();
                let options_obj = Object::new();
                Reflect::set(&options_obj, &"scrollbars".into(), &scrollbars_obj).unwrap_throw();

                let elements_obj = Object::new();
                Reflect::set(&elements_obj, &"viewport".into(), &viewport.into()).unwrap_throw();
                let element_obj = Object::new();
                Reflect::set(&elements_obj, &"elements".into(), &elements_obj).unwrap_throw();
                Reflect::set(&element_obj, &"target".into(), &buffer.into()).unwrap_throw();
                // let element = Object::define_property(&Object::define_property(&Object::new(), &"target".into(), &buffer.into()), &"elements".into(), &Object::define_property(&Object::new(), &"viewport".into(), &viewport.into()));
                debug!(
                    "scrollable element: {}",
                    JSON::stringify(&element_obj.clone().into()).unwrap_throw()
                );
                OverlayScrollbars(element_obj, options_obj);
            }
        }
    });

    // TODO: filter new messages signal
    view! {
        <div class="roster-list panel">
            <div class="header">
                <h2>Roster</h2>
                <div class="add-contact header-icon" class:open=open_add_contact>
                    <IconComponent
                        icon=Icon::AddContact24
                        on:click=move |_| set_open_add_contact.update(|state| *state = !*state)
                    />
                    {move || {
                        if !requests.read().is_empty() {
                            view! { <div class="badge"></div> }.into_any()
                        } else {
                            view! {}.into_any()
                        }
                    }}
                </div>
            </div>
            {move || {
                if *open_add_contact.read() {
                    view! {
                        <div class="overlay-scroll add-contact-panel" node_ref=add_contact>
                            <div class="roster-add-contact" node_ref=add_contact_viewport>
                                <AddContact />
                            </div>
                        </div>
                    }
                        .into_any()
                } else {
                    view! {}.into_any()
                }
            }}
            <div class="overlay-scroll" node_ref=roster_list>
                <div class="roster-list-roster" node_ref=roster_list_viewport>
                    <For
                        each=move || roster.contacts().get()
                        key=|contact| contact.0.clone()
                        let(contact)
                    >
                        <RosterListItem contact=contact.1 />
                    </For>
                </div>
            </div>
        </div>
    }
}