diff options
| author | 2025-06-01 21:32:13 +0100 | |
|---|---|---|
| committer | 2025-06-01 21:32:13 +0100 | |
| commit | 12d9e5955092b282a96add03ddfc148f01f3a3e8 (patch) | |
| tree | bca74c6132c25c8493b8b209f20203c71b1daad6 | |
| parent | 33bb7130943b5f74b3b0f08c5e6d8f7c5e54d4c0 (diff) | |
| download | macaw-web-12d9e5955092b282a96add03ddfc148f01f3a3e8.tar.gz macaw-web-12d9e5955092b282a96add03ddfc148f01f3a3e8.tar.bz2 macaw-web-12d9e5955092b282a96add03ddfc148f01f3a3e8.zip  | |
WIP: fix untracked stateleptos-fetch
| -rw-r--r-- | src/chat.rs | 35 | ||||
| -rw-r--r-- | src/components/chat_header.rs | 8 | ||||
| -rw-r--r-- | src/components/chats_list.rs | 4 | ||||
| -rw-r--r-- | src/components/chats_list/chats_list_item.rs | 16 | ||||
| -rw-r--r-- | src/components/message.rs | 19 | ||||
| -rw-r--r-- | src/components/message_history_buffer.rs | 37 | ||||
| -rw-r--r-- | src/components/new_chat.rs | 72 | ||||
| -rw-r--r-- | src/components/personal_status.rs | 2 | ||||
| -rw-r--r-- | src/components/roster_list/roster_list_item.rs | 14 | ||||
| -rw-r--r-- | src/message.rs | 34 | ||||
| -rw-r--r-- | src/open_chats.rs | 12 | ||||
| -rw-r--r-- | src/user.rs | 29 | ||||
| -rw-r--r-- | src/views/macaw/open_chats_panel.rs | 4 | 
13 files changed, 117 insertions, 169 deletions
diff --git a/src/chat.rs b/src/chat.rs index a1ced32..6612431 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -8,14 +8,19 @@ use leptos::prelude::*;  use crate::{client::Client, user::MacawUser}; +#[derive(Clone)] +pub struct GotChat(Chat); +  async fn get_chat(jid: BareJID) -> ArcStore<Chat> { -    let client: Client = use_context().expect("no client in context"); -    ArcStore::new(client.get_chat(jid).await.unwrap()) +    // let client: Client = use_context().expect("no client in context"); +    // ArcStore::new(client.get_chat(jid).await.unwrap()) +    let GotChat(chat) = use_context().expect("no chat in context"); +    ArcStore::new(chat)  } -#[derive(Clone)] +#[derive(Clone, Copy)]  pub struct MacawChat { -    pub chat: ArcStore<Chat>, +    pub chat: LocalResource<ArcStore<Chat>>,      pub user: MacawUser,      // user: StateListener<BareJID, ArcStore<User>>,  } @@ -25,26 +30,18 @@ impl MacawChat {          let query_client: QueryClient = expect_context();          let jid = chat.correspondent.clone(); -        let chat_store = query_client.subscribe_value_local(get_chat, move || jid.clone()); -        if let Some(chat_store) = chat_store.get() { -            chat_store.set(chat); -            let user = MacawUser::got_user(user); -            Self { chat: chat_store, user } -        } else { -            let jid = chat.correspondent.clone(); -            let chat_store = ArcStore::new(chat); -            query_client.set_query_local(get_chat, jid, chat_store.clone()); -            let user = MacawUser::got_user(user); -            Self { -                chat: chat_store, -                user, -            } +        provide_context(GotChat(chat)); +        let chat = query_client.local_resource(get_chat, move || jid.clone()); +        let user = MacawUser::got_user(user); +        Self { +            chat, +            user,          }      }  }  impl Deref for MacawChat { -    type Target = ArcStore<Chat>; +    type Target = LocalResource<ArcStore<Chat>>;      fn deref(&self) -> &Self::Target {          &self.chat diff --git a/src/components/chat_header.rs b/src/components/chat_header.rs index 208e7f6..7d2f195 100644 --- a/src/components/chat_header.rs +++ b/src/components/chat_header.rs @@ -6,13 +6,13 @@ use crate::{chat::MacawChat, components::avatar::AvatarWithPresence, user::get_n  #[component]  pub fn ChatViewHeader(chat: MacawChat) -> impl IntoView { -    let chat_user = <ArcStore<filamento::user::User> as Clone>::clone(&chat.user).into(); -    let name = move || get_name(chat_user, true); -    let jid = move || chat_user.jid().read().to_string(); +    // let chat_user = <ArcStore<filamento::user::User> as Clone>::clone(&chat.user).into(); +    let name = move || get_name(chat.user.get().unwrap().into(), true); +    let jid = move || chat.user.get().unwrap().jid().read().to_string();      view! {          <div class="chat-view-header panel"> -            <AvatarWithPresence user=chat_user /> +            <AvatarWithPresence user=chat.user.get().unwrap().into() />              <div class="user-info">                  <h2 class="name">{name}</h2>                  <h3>{jid}</h3> diff --git a/src/components/chats_list.rs b/src/components/chats_list.rs index d520f56..ceac1f4 100644 --- a/src/components/chats_list.rs +++ b/src/components/chats_list.rs @@ -55,7 +55,7 @@ pub fn ChatsList() -> impl IntoView {              if let Some((chat, _latest_message)) = chats.shift_remove(&to) {                  // TODO: check if new message is actually latest message                  debug!("chat existed"); -                debug!("new message: {}", new_message.message.read().body.body); +                debug!("new message: {}", new_message.message.get().unwrap().read().body.body);                  chats.insert_before(0, to, (chat.clone(), new_message));                  debug!("done setting");              } else { @@ -99,7 +99,7 @@ pub fn ChatsList() -> impl IntoView {                  </div>              </div>              <div class="chats-list-chats"> -                <For each=move || chats.get() key=|chat| chat.1.1.message.read().id let(chat)> +                <For each=move || chats.get() key=|chat| chat.1.1.message.get().unwrap().read().id let(chat)>                      <ChatsListItem chat=chat.1.0 message=chat.1.1 />                  </For>              </div> diff --git a/src/components/chats_list/chats_list_item.rs b/src/components/chats_list/chats_list_item.rs index 191f163..265e748 100644 --- a/src/components/chats_list/chats_list_item.rs +++ b/src/components/chats_list/chats_list_item.rs @@ -10,14 +10,10 @@ use crate::{chat::MacawChat, components::{avatar::AvatarWithPresence, sidebar::O  #[component]  pub fn ChatsListItem(chat: MacawChat, message: MacawMessage) -> impl IntoView { -    let chat_chat: Store<Chat> = <ArcStore<Chat> as Clone>::clone(&chat.chat).into(); -    let chat_user: Store<User> = -        <ArcStore<filamento::user::User> as Clone>::clone(&chat.user).into(); -    let message_message: Store<Message> = <ArcStore<Message> as Clone>::clone(&message.message).into(); -    let name = move || get_name(chat_user, true); +    let name = move || get_name(chat.user.get().unwrap().into(), true);      // TODO: store fine-grained reactivity -    let latest_message_body = move || message_message.body().get().body; +    let latest_message_body = move || message.message.get().unwrap().body().get().body;      let open_chats: Store<OpenChatsPanel> =          use_context().expect("no open chats panel store in context"); @@ -29,14 +25,14 @@ pub fn ChatsListItem(chat: MacawChat, message: MacawMessage) -> impl IntoView {      let open = move || {          if let Some(open_chat) = &*open_chats.chat_view().read() {              debug!("got open chat: {:?}", open_chat); -            if *open_chat == *chat_chat.correspondent().read() { +            if *open_chat == *chat.chat.get().unwrap().correspondent().read() {                  return Open::Focused;              }          }          if let Some(_backgrounded_chat) = open_chats              .chats()              .read() -            .get(chat_chat.correspondent().read().deref()) +            .get(chat.chat.get().unwrap().correspondent().read().deref())          {              return Open::Open;          } @@ -45,7 +41,7 @@ pub fn ChatsListItem(chat: MacawChat, message: MacawMessage) -> impl IntoView {      let focused = move || open().is_focused();      let open = move || open().is_open(); -    let date = move || message_message.timestamp().read().naive_local(); +    let date = move || message.message.get().unwrap().timestamp().read().naive_local();      let now = move || Local::now().naive_local();      let timeinfo = move || if date().date() == now().date() {          // TODO: localisation/config @@ -56,7 +52,7 @@ pub fn ChatsListItem(chat: MacawChat, message: MacawMessage) -> impl IntoView {      view! {          <div class="chats-list-item" class:open=move || open() class:focused=move || focused() on:click=open_chat> -            <AvatarWithPresence user=chat_user /> +            <AvatarWithPresence user=chat.user.get().unwrap().into() />              <div class="item-info">                  <div class="main-info"><p class="name">{name}</p><p class="timestamp">{timeinfo}</p></div>                  <div class="sub-info"><p class="message-preview">{latest_message_body}</p><p><!-- "TODO: delivery or unread state" --></p></div> diff --git a/src/components/message.rs b/src/components/message.rs index 2ae2ef0..1711b35 100644 --- a/src/components/message.rs +++ b/src/components/message.rs @@ -8,11 +8,8 @@ use super::icon::Delivery;  #[component]  pub fn Message(message: MacawMessage, major: bool, r#final: bool) -> impl IntoView { -    let message_message: Store<filamento::chat::Message> = -        <ArcStore<filamento::chat::Message> as Clone>::clone(&message.message).into(); -    let message_user = <ArcStore<filamento::user::User> as Clone>::clone(&message.user).into(); -    let avatar = LocalResource::new(move || get_avatar(message_user)); -    let name = move || get_name(message_user, false); +    let avatar = LocalResource::new(move || get_avatar(message.user.get().unwrap().into())); +    let name = move || get_name(message.user.get().unwrap().into(), false);      // TODO: chrono-humanize?      // TODO: if final, show delivery not only on hover. @@ -28,23 +25,23 @@ pub fn Message(message: MacawMessage, major: bool, r#final: bool) -> impl IntoVi                  <div class="middle">                      <div class="message-info">                          <div class="message-user-name">{name}</div> -                        <div class="message-timestamp">{move || message_message.timestamp().read().format("%H:%M").to_string()}</div> +                        <div class="message-timestamp">{move || message.message.get().unwrap().timestamp().read().format("%H:%M").to_string()}</div>                      </div>                      <div class="message-text"> -                        {move || message_message.body().read().body.clone()} +                        {move || message.message.get().unwrap().body().read().body.clone()}                      </div>                  </div> -                <div class="right message-delivery">{move || message_message.delivery().get().map(|delivery| view! { <Delivery class:light=true delivery /> } ) }</div> +                <div class="right message-delivery">{move || message.message.get().unwrap().delivery().get().map(|delivery| view! { <Delivery class:light=true delivery /> } ) }</div>              </div>          }.into_any()      } else {          view! {              <div class:final=r#final class="chat-message minor">                  <div class="left message-timestamp"> -                    {move || message_message.timestamp().read().format("%H:%M").to_string()} +                    {move || message.message.get().unwrap().timestamp().read().format("%H:%M").to_string()}                  </div> -                <div class="middle message-text">{move || message_message.body().read().body.clone()}</div> -                <div class="right message-delivery">{move || message_message.delivery().get().map(|delivery| view! { <Delivery delivery /> } ) }</div> +                <div class="middle message-text">{move || message.message.get().unwrap().body().read().body.clone()}</div> +                <div class="right message-delivery">{move || message.message.get().unwrap().delivery().get().map(|delivery| view! { <Delivery delivery /> } ) }</div>              </div>          }.into_any()      } diff --git a/src/components/message_history_buffer.rs b/src/components/message_history_buffer.rs index 632209d..5622f3e 100644 --- a/src/components/message_history_buffer.rs +++ b/src/components/message_history_buffer.rs @@ -12,10 +12,6 @@ use crate::{chat::MacawChat, client::Client, components::message::Message, messa  #[component]  pub fn MessageHistoryBuffer(chat: MacawChat) -> impl IntoView {      let (messages, set_messages) = arc_signal(IndexMap::new()); -    let chat_chat: Store<Chat> = -        <ArcStore<filamento::chat::Chat> as Clone>::clone(&chat.chat).into(); -    let chat_user: Store<User> = -        <ArcStore<filamento::user::User> as Clone>::clone(&chat.user).into();      let load_set_messages = set_messages.clone();      let load_messages = LocalResource::new(move || { @@ -23,7 +19,7 @@ pub fn MessageHistoryBuffer(chat: MacawChat) -> impl IntoView {          async move {              let client = use_context::<Client>().expect("client not in context");              let messages = client -                .get_messages_with_users(chat_chat.correspondent().get()) +                .get_messages_with_users(chat.chat.get().unwrap().correspondent().get())                  .await                  .map_err(|e| e.to_string());              match messages { @@ -57,23 +53,22 @@ pub fn MessageHistoryBuffer(chat: MacawChat) -> impl IntoView {              load_messages.await;              let (sub_id, mut new_messages) = new_messages_signal                  .write() -                .subscribe_chat(chat_chat.correspondent().get()); +                .subscribe_chat(chat.chat.get().unwrap().correspondent().get());              set_sub_id.set(Some(sub_id));              while let Some(new_message) = new_messages.recv().await {                  debug!("got new message in let message buffer");                  let mut messages = load_new_messages_set.write();                  if let Some((_, last)) = messages.last() { -                    if *<ArcStore<filamento::chat::Message> as Clone>::clone(&last.message) +                    if *last.message.get().unwrap()                          .timestamp()                          .read() -                        < *<ArcStore<filamento::chat::Message> as Clone>::clone(&new_message.message) +                        < *new_message.message.get().unwrap()                              .timestamp()                              .read()                      {                          messages.insert( -                            <ArcStore<filamento::chat::Message> as Clone>::clone( -                                &new_message.message, -                            ) +                             +                            new_message.message.get().unwrap()                              .id()                              .get(),                              new_message, @@ -81,13 +76,11 @@ pub fn MessageHistoryBuffer(chat: MacawChat) -> impl IntoView {                          debug!("set the new message in message buffer");                      } else {                          let index = match messages.binary_search_by(|_, value| { -                            <ArcStore<filamento::chat::Message> as Clone>::clone(&value.message) +                            value.message.get().unwrap()                                  .timestamp()                                  .read()                                  .cmp( -                                    &<ArcStore<filamento::chat::Message> as Clone>::clone( -                                        &new_message.message, -                                    ) +                                    &new_message.message.get().unwrap()                                      .timestamp()                                      .read(),                                  ) @@ -98,9 +91,7 @@ pub fn MessageHistoryBuffer(chat: MacawChat) -> impl IntoView {                          messages.insert_before(                              // TODO: check if this logic is correct                              index, -                            <ArcStore<filamento::chat::Message> as Clone>::clone( -                                &new_message.message, -                            ) +                            new_message.message.get().unwrap()                              .id()                              .get(),                              new_message, @@ -109,7 +100,7 @@ pub fn MessageHistoryBuffer(chat: MacawChat) -> impl IntoView {                      }                  } else {                      messages.insert( -                        <ArcStore<filamento::chat::Message> as Clone>::clone(&new_message.message) +                        new_message.message.get().unwrap()                              .id()                              .get(),                          new_message, @@ -123,7 +114,7 @@ pub fn MessageHistoryBuffer(chat: MacawChat) -> impl IntoView {          if let Some(sub_id) = sub_id.get() {              new_messages_signal                  .write() -                .unsubscribe_chat(sub_id, chat_chat.correspondent().get_untracked()); +                .unsubscribe_chat(sub_id, chat.chat.get().unwrap().correspondent().get_untracked());          }      }); @@ -135,7 +126,7 @@ pub fn MessageHistoryBuffer(chat: MacawChat) -> impl IntoView {              .into_iter()              .map(|(id, message)| {                  let message_timestamp = -                    <ArcStore<filamento::chat::Message> as Clone>::clone(&message.message) +                    message.message.get().unwrap()                          .timestamp()                          .read()                          .naive_local(); @@ -143,7 +134,7 @@ pub fn MessageHistoryBuffer(chat: MacawChat) -> impl IntoView {                  // if message_timestamp.date() > last_timestamp.date() {                  //     messages_view = messages_view.push(date(message_timestamp.date()));                  // } -                let major = if last_user.as_ref() != Some(&message.message.read().from) +                let major = if last_user.as_ref() != Some(&message.message.get().unwrap().read().from)                      || message_timestamp - last_timestamp > TimeDelta::minutes(3)                  {                      true @@ -151,7 +142,7 @@ pub fn MessageHistoryBuffer(chat: MacawChat) -> impl IntoView {                      false                  };                  last_user = Some( -                    <ArcStore<filamento::chat::Message> as Clone>::clone(&message.message) +                    message.message.get().unwrap()                          .from()                          .get(),                  ); diff --git a/src/components/new_chat.rs b/src/components/new_chat.rs index 6d64c96..33508b2 100644 --- a/src/components/new_chat.rs +++ b/src/components/new_chat.rs @@ -20,14 +20,24 @@ pub enum NewChatError {  }  // TODO: remove +#[derive(Clone)] +pub struct GotChat(Chat); +  async fn get_chat(jid: BareJID) -> ArcStore<Chat> { -    let client: Client = use_context().expect("no client in context"); -    ArcStore::new(client.get_chat(jid).await.unwrap()) +    // let client: Client = use_context().expect("no client in context"); +    // ArcStore::new(client.get_chat(jid).await.unwrap()) +    let GotChat(chat) = use_context().expect("no chat in context"); +    ArcStore::new(chat)  } +#[derive(Clone)] +pub struct GotUser(User); +  async fn get_user(jid: BareJID) -> ArcStore<User> { -    let client: Client = use_context().expect("no client in context"); -    ArcStore::new(client.get_user(jid).await.unwrap()) +    // let client: Client = use_context().expect("no client in context"); +    // ArcStore::new(client.get_user(jid).await.unwrap()) +    let GotUser(user) = use_context().expect("no user in context"); +    ArcStore::new(user)  }  #[component] @@ -87,51 +97,17 @@ pub fn NewChatWidget(set_open_new_chat: WriteSignal<bool>) -> impl IntoView {              let chat = {                  // let user = MacawUser::got_user(user);                  let jid = chat.correspondent.clone(); -                let chat_store = query_client.subscribe_value_local(get_chat, move || jid.clone()); -                if let Some(chat_store) = chat_store.get() { -                    chat_store.set(chat); -                    let user = { -                        let jid = user.jid.clone(); -                        let user_store = query_client.subscribe_value_local(get_user, move || jid.clone()); -                        if let Some(user_store) = user_store.get() { -                            user_store.set(user); -                            MacawUser { user: user_store } -                        } else { -                            let jid = user.jid.clone(); -                            let user_store = ArcStore::new(user); -                            query_client.set_query_local(get_user, jid, user_store.clone()); -                            MacawUser { -                                user: user_store, -                            } -                        } -                         -                    }; -                    MacawChat { chat: chat_store, user } -                } else { -                    let jid = chat.correspondent.clone(); -                    let chat_store = ArcStore::new(chat); -                    query_client.set_query_local(get_chat, jid, chat_store.clone()); -                    let user = { -                        let jid = user.jid.clone(); -                        let user_store = query_client.subscribe_value_local(get_user, move || jid.clone()); -                        if let Some(user_store) = user_store.get() { -                            user_store.set(user); -                            MacawUser { user: user_store } -                        } else { -                            let jid = user.jid.clone(); -                            let user_store = ArcStore::new(user); -                            query_client.set_query_local(get_user, jid, user_store.clone()); -                            MacawUser { -                                user: user_store, -                            } -                        } -                         -                    }; -                    MacawChat { -                        chat: chat_store, -                        user, +                provide_context(GotChat(chat)); +                let chat = query_client.local_resource(get_chat, move || jid.clone()); +                let user = { +                    let jid = user.jid.clone(); +                    provide_context(GotUser(user)); +                    MacawUser { +                        user: query_client.local_resource(get_user, move || jid.clone())                      } -                } +                     +                }; +                MacawChat { chat, user }              };              open_chats.update(|open_chats| open_chats.open(chat.clone()));              set_open_new_chat.set(false); diff --git a/src/components/personal_status.rs b/src/components/personal_status.rs index 81a27b5..397aade 100644 --- a/src/components/personal_status.rs +++ b/src/components/personal_status.rs @@ -11,7 +11,7 @@ pub fn PersonalStatus() -> impl IntoView {      let (open, set_open) = signal(false);      move || if let Some(user) = user.get() { -        let user: Store<User> = <ArcStore<filamento::user::User> as Clone>::clone(&user.user).into(); +        let user: Store<User> = user.user.get().unwrap().into();          view! {              <div class="dock-item" class:focused=move || *open.read()  on:click=move |_| {                  debug!("set open to true"); diff --git a/src/components/roster_list/roster_list_item.rs b/src/components/roster_list/roster_list_item.rs index 46ac1cc..9b884f7 100644 --- a/src/components/roster_list/roster_list_item.rs +++ b/src/components/roster_list/roster_list_item.rs @@ -10,9 +10,7 @@ use crate::{chat::MacawChat, components::{avatar::AvatarWithPresence, sidebar::O  #[component]  pub fn RosterListItem(contact: MacawContact) -> impl IntoView {      let contact_contact: Store<Contact> = contact.contact; -    let contact_user: Store<User> = -        <ArcStore<filamento::user::User> as Clone>::clone(&contact.user).into(); -    let name = move || get_name(contact_user, false); +    let name = move || get_name(contact.user.get().unwrap().into(), false);      let open_chats: Store<OpenChatsPanel> =          use_context().expect("no open chats panel store in context"); @@ -20,10 +18,10 @@ pub fn RosterListItem(contact: MacawContact) -> impl IntoView {      // TODO: why can this not be in the closure?????      // TODO: not good, as overwrites preexisting chat state with possibly incorrect one...      let chat = Chat { -        correspondent: contact_user.jid().get(), +        correspondent: contact.user.get().unwrap().jid().get(),          have_chatted: false,      }; -    let chat = MacawChat::got_chat_and_user(chat, contact_user.get()); +    let chat = MacawChat::got_chat_and_user(chat, contact.user.get().unwrap().get());      let open_chat = move |_| {          debug!("opening chat"); @@ -33,14 +31,14 @@ pub fn RosterListItem(contact: MacawContact) -> impl IntoView {      let open = move || {          if let Some(open_chat) = &*open_chats.chat_view().read() {              debug!("got open chat: {:?}", open_chat); -            if *open_chat == *contact_user.jid().read() { +            if *open_chat == *contact.user.get().unwrap().jid().read() {                  return Open::Focused;              }          }          if let Some(_backgrounded_chat) = open_chats              .chats()              .read() -            .get(contact_user.jid().read().deref()) +            .get(contact.user.get().unwrap().jid().read().deref())          {              return Open::Open;          } @@ -51,7 +49,7 @@ pub fn RosterListItem(contact: MacawContact) -> impl IntoView {      view! {          <div class="roster-list-item" class:open=move || open() class:focused=move || focused() on:click=open_chat> -            <AvatarWithPresence user=contact_user /> +            <AvatarWithPresence user=contact.user.get().unwrap().into() />              <div class="item-info">                  <div class="main-info"><p class="name">{name}<span class="jid"> - {move || contact_contact.user_jid().read().to_string()}</span></p></div>                  <div class="sub-info">{move || contact_contact.subscription().read().to_string()}</div> diff --git a/src/message.rs b/src/message.rs index a47c75f..2a5fe18 100644 --- a/src/message.rs +++ b/src/message.rs @@ -8,14 +8,19 @@ use leptos::prelude::*;  use crate::{client::Client, user::MacawUser}; +#[derive(Clone)] +pub struct GotMessage(Message); +  async fn get_message(id: Uuid) -> ArcStore<Message> { -    let client: Client = use_context().expect("no client in context"); -    ArcStore::new(client.get_message(id).await.unwrap()) +    // let client: Client = use_context().expect("no client in context"); +    // ArcStore::new(client.get_message(id).await.unwrap()) +    let GotMessage(message) = use_context().expect("no message in context"); +    ArcStore::new(message)  } -#[derive(Clone)] +#[derive(Clone, Copy)]  pub struct MacawMessage { -    pub message: ArcStore<Message>, +    pub message: LocalResource<ArcStore<Message>>,      pub user: MacawUser,  } @@ -24,25 +29,18 @@ impl MacawMessage {          let query_client: QueryClient = expect_context();          let id = message.id; -        let message_store = query_client.subscribe_value_local(get_message, move || id); -        if let Some(message_store) = message_store.get() { -            message_store.set(message); -            let user = MacawUser::got_user(user); -            Self { message: message_store, user } -        } else { -            let message_store = ArcStore::new(message); -            query_client.set_query_local(get_message, id, message_store.clone()); -            let user = MacawUser::got_user(user); -            Self { -                message: message_store, -                user, -            } +        provide_context(GotMessage(message)); +        let message = query_client.local_resource(get_message, move || id); +        let user = MacawUser::got_user(user); +        Self { +            message, +            user,          }      }  }  impl Deref for MacawMessage { -    type Target = ArcStore<Message>; +    type Target = LocalResource<ArcStore<Message>>;      fn deref(&self) -> &Self::Target {          &self.message diff --git a/src/open_chats.rs b/src/open_chats.rs index ed89537..3f33a60 100644 --- a/src/open_chats.rs +++ b/src/open_chats.rs @@ -18,7 +18,7 @@ pub struct OpenChatsPanel {  pub fn open_chat(open_chats: Store<OpenChatsPanel>, chat: MacawChat) {      if let Some(jid) = &*open_chats.chat_view().read() {          if let Some((index, _jid, entry)) = open_chats.chats().write().shift_remove_full(jid) { -            let new_jid = <ArcStore<filamento::chat::Chat> as Clone>::clone(&chat.chat) +            let new_jid = chat.chat.get().unwrap()                  .correspondent()                  .read()                  .clone(); @@ -28,7 +28,7 @@ pub fn open_chat(open_chats: Store<OpenChatsPanel>, chat: MacawChat) {                  .insert_before(index, new_jid.clone(), chat);              *open_chats.chat_view().write() = Some(new_jid);          } else { -            let new_jid = <ArcStore<filamento::chat::Chat> as Clone>::clone(&chat.chat) +            let new_jid = chat.chat.get().unwrap()                  .correspondent()                  .read()                  .clone(); @@ -36,7 +36,7 @@ pub fn open_chat(open_chats: Store<OpenChatsPanel>, chat: MacawChat) {              *open_chats.chat_view().write() = Some(new_jid);          }      } else { -        let new_jid = <ArcStore<filamento::chat::Chat> as Clone>::clone(&chat.chat) +        let new_jid = chat.chat.get().unwrap()              .correspondent()              .read()              .clone(); @@ -50,14 +50,14 @@ impl OpenChatsPanel {          if let Some(jid) = &mut self.chat_view {              debug!("a chat was already open");              if let Some((index, _jid, entry)) = self.chats.shift_remove_full(jid) { -                let new_jid = <ArcStore<filamento::chat::Chat> as Clone>::clone(&chat.chat) +                let new_jid = chat.chat.get().unwrap()                      .correspondent()                      .read()                      .clone();                  self.chats.insert_before(index, new_jid.clone(), chat);                  *&mut self.chat_view = Some(new_jid);              } else { -                let new_jid = <ArcStore<filamento::chat::Chat> as Clone>::clone(&chat.chat) +                let new_jid = chat.chat.get().unwrap()                      .correspondent()                      .read()                      .clone(); @@ -65,7 +65,7 @@ impl OpenChatsPanel {                  *&mut self.chat_view = Some(new_jid);              }          } else { -            let new_jid = <ArcStore<filamento::chat::Chat> as Clone>::clone(&chat.chat) +            let new_jid = chat.chat.get().unwrap()                  .correspondent()                  .read()                  .clone(); diff --git a/src/user.rs b/src/user.rs index d92ba4f..2dd0cb2 100644 --- a/src/user.rs +++ b/src/user.rs @@ -8,14 +8,19 @@ use leptos::prelude::*;  use crate::{client::Client, roster::{Roster, RosterStoreFields}}; +#[derive(Clone)] +pub struct GotUser(User); +  async fn get_user(jid: BareJID) -> ArcStore<User> { -    let client: Client = use_context().expect("no client in context"); -    ArcStore::new(client.get_user(jid).await.unwrap()) +    // let client: Client = use_context().expect("no client in context"); +    // ArcStore::new(client.get_user(jid).await.unwrap()) +    let GotUser(user) = use_context().expect("no user in context"); +    ArcStore::new(user)  } -#[derive(Clone)] +#[derive(Clone, Copy)]  pub struct MacawUser { -    pub user: ArcStore<User>, +    pub user: LocalResource<ArcStore<User>>,  }  impl MacawUser { @@ -25,23 +30,15 @@ impl MacawUser {          let query_client: QueryClient = expect_context();          let jid = user.jid.clone(); -        let user_store = query_client.subscribe_value_local(get_user, move || jid.clone()); -        if let Some(user_store) = user_store.get() { -            user_store.set(user); -            Self { user: user_store } -        } else { -            let jid = user.jid.clone(); -            let user_store = ArcStore::new(user); -            query_client.set_query_local(get_user, jid, user_store.clone()); -            Self { -                user: user_store, -            } +        provide_context(GotUser(user)); +        Self { +            user: query_client.local_resource(get_user, move || jid.clone())          }      }  }  impl Deref for MacawUser { -    type Target = ArcStore<User>; +    type Target = LocalResource<ArcStore<User>>;      fn deref(&self) -> &Self::Target {          &self.user diff --git a/src/views/macaw/open_chats_panel.rs b/src/views/macaw/open_chats_panel.rs index 062c786..9bad14b 100644 --- a/src/views/macaw/open_chats_panel.rs +++ b/src/views/macaw/open_chats_panel.rs @@ -57,9 +57,7 @@ mod open_chat {      #[component]      pub fn OpenChatView(chat: MacawChat) -> impl IntoView { -        let chat_chat: Store<Chat> = -            <ArcStore<filamento::chat::Chat> as Clone>::clone(&chat.chat).into(); -        let chat_jid = move || chat_chat.correspondent().get(); +        let chat_jid = move || chat.chat.get().unwrap().correspondent().get();          view! {              <div class="open-chat-view">  | 
