diff options
| -rw-r--r-- | src/lib.rs | 256 | 
1 files changed, 128 insertions, 128 deletions
@@ -412,33 +412,32 @@ pub struct OpenChatsPanel {      chats: IndexMap<JID, MacawChat>,  } -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) -                .correspondent() -                .read() +pub fn open_chat(open_chats: RwSignal<OpenChatsPanel>, chat: MacawChat) { +    if let Some(jid) = &open_chats.read().chat_view { +        if let Some((index, _jid, entry)) = open_chats.write().chats.shift_remove_full(jid) { +            let new_jid = <ArcRwSignal<filamento::chat::Chat> as Clone>::clone(&chat.chat) +                .read().correspondent                  .clone();              open_chats -                .chats()                  .write() +                .chats                  .insert_before(index, new_jid.clone(), chat); -            *open_chats.chat_view().write() = Some(new_jid); +            open_chats.write().chat_view = Some(new_jid);          } else { -            let new_jid = <ArcStore<filamento::chat::Chat> as Clone>::clone(&chat.chat) -                .correspondent() +            let new_jid = <ArcRwSignal<filamento::chat::Chat> as Clone>::clone(&chat.chat)                  .read() +                .correspondent                  .clone(); -            open_chats.chats().write().insert(new_jid.clone(), chat); -            *open_chats.chat_view().write() = Some(new_jid); +            open_chats.write().chats.insert(new_jid.clone(), chat); +            open_chats.write().chat_view = Some(new_jid);          }      } else { -        let new_jid = <ArcStore<filamento::chat::Chat> as Clone>::clone(&chat.chat) -            .correspondent() +        let new_jid = <ArcRwSignal<filamento::chat::Chat> as Clone>::clone(&chat.chat)              .read() +            .correspondent              .clone(); -        open_chats.chats().write().insert(new_jid.clone(), chat); -        *open_chats.chat_view().write() = Some(new_jid); +        open_chats.write().chats.insert(new_jid.clone(), chat); +        open_chats.write().chat_view = Some(new_jid);      }  } @@ -447,24 +446,24 @@ 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) -                    .correspondent() +                let new_jid = <ArcRwSignal<filamento::chat::Chat> as Clone>::clone(&chat.chat)                      .read() +                    .correspondent                      .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) -                    .correspondent() +                let new_jid = <ArcRwSignal<filamento::chat::Chat> as Clone>::clone(&chat.chat)                      .read() +                    .correspondent                      .clone();                  self.chats.insert(new_jid.clone(), chat);                  *&mut self.chat_view = Some(new_jid);              }          } else { -            let new_jid = <ArcStore<filamento::chat::Chat> as Clone>::clone(&chat.chat) -                .correspondent() +            let new_jid = <ArcRwSignal<filamento::chat::Chat> as Clone>::clone(&chat.chat)                  .read() +                .correspondent                  .clone();              self.chats.insert(new_jid.clone(), chat);              *&mut self.chat_view = Some(new_jid); @@ -604,23 +603,23 @@ fn Macaw(  ) -> impl IntoView {      provide_context(client); -    let roster = Store::new(Roster::new()); +    let roster = RwSignal::new(Roster::new());      provide_context(roster);      let message_subscriptions = RwSignal::new(MessageSubscriptions::new());      provide_context(message_subscriptions); -    let messages_store: StateStore<Uuid, ArcStore<Message>> = StateStore::new(); +    let messages_store: StateStore<Uuid, ArcRwSignal<Message>> = StateStore::new();      provide_context(messages_store); -    let chats_store: StateStore<JID, ArcStore<Chat>> = StateStore::new(); +    let chats_store: StateStore<JID, ArcRwSignal<Chat>> = StateStore::new();      provide_context(chats_store); -    let users_store: StateStore<JID, ArcStore<User>> = StateStore::new(); +    let users_store: StateStore<JID, ArcRwSignal<User>> = StateStore::new();      provide_context(users_store); -    let open_chats = Store::new(OpenChatsPanel::default()); +    let open_chats = RwSignal::new(OpenChatsPanel::default());      provide_context(open_chats); -    let user_presences = Store::new(UserPresences::new()); +    let user_presences = RwSignal::new(UserPresences::new());      provide_context(user_presences);      // TODO: get cached contacts on login before getting the updated contacts @@ -638,14 +637,15 @@ fn Macaw(                              )                          })                          .collect(); -                    roster.contacts().set(contacts); +                    roster.write().contacts = contacts;                  }                  UpdateMessage::Offline(offline) => {                      // when offline, will no longer receive updated user presences, consider everybody offline.                      user_presences.write().clear();                  }                  UpdateMessage::RosterUpdate(contact, user) => { -                    roster.contacts().update(|roster| { +                    roster.update(|roster| { +                        let roster = &mut roster.contacts;                          if let Some(macaw_contact) = roster.get_mut(&contact.user_jid) {                              macaw_contact.set(contact);                          } else { @@ -656,7 +656,8 @@ fn Macaw(                      });                  }                  UpdateMessage::RosterDelete(jid) => { -                    roster.contacts().update(|roster| { +                    roster.update(|roster| { +                        let roster = &mut roster.contacts;                          roster.remove(&jid);                      });                  } @@ -688,9 +689,8 @@ fn Macaw(                  }                  UpdateMessage::MessageDelivery { id, chat, delivery } => {                      messages_store.modify(&id, |message| { -                        <ArcStore<filamento::chat::Message> as Clone>::clone(&message) -                            .delivery() -                            .set(Some(delivery)) +                        <ArcRwSignal<filamento::chat::Message> as Clone>::clone(&message) +                            .update(|message| message.delivery = Some(delivery))                      });                  }                  UpdateMessage::SubscriptionRequest(jid) => {} @@ -779,7 +779,7 @@ pub fn Sidebar() -> impl IntoView {  #[component]  pub fn OpenChatsPanelView() -> impl IntoView { -    let open_chats: Store<OpenChatsPanel> = use_context().expect("no open chats panel in context"); +    let open_chats: RwSignal<OpenChatsPanel> = use_context().expect("no open chats panel in context");      // TODO: tabs      // view! { @@ -802,8 +802,8 @@ pub fn OpenChatsPanelView() -> impl IntoView {      view! {          <div class="open-chat-views">              {move || { -                if let Some(open_chat) = open_chats.chat_view().get() { -                    if let Some(open_chat) = open_chats.chats().read().get(&open_chat) { +                if let Some(open_chat) = &open_chats.read().chat_view { +                    if let Some(open_chat) = open_chats.read().chats.get(open_chat) {                          view! { <OpenChatView chat=open_chat.clone() /> }.into_any()                      } else {                          view! {}.into_any() @@ -818,9 +818,9 @@ pub fn OpenChatsPanelView() -> impl IntoView {  #[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_chat: RwSignal<Chat> = +        <ArcRwSignal<filamento::chat::Chat> as Clone>::clone(&chat.chat).into(); +    let chat_jid = move || chat_chat.read().correspondent.clone();      view! {          <div class="open-chat-view"> @@ -841,9 +841,9 @@ pub fn show_to_icon(show: Show) -> Icon {  }  #[component] -pub fn AvatarWithPresence(user: Store<User>) -> impl IntoView { +pub fn AvatarWithPresence(user: RwSignal<User>) -> impl IntoView {      let avatar = LocalResource::new(move || get_avatar(user)); -    let user_presences: Store<UserPresences> = use_context().expect("no user presences in context"); +    let user_presences: RwSignal<UserPresences> = use_context().expect("no user presences in context");      let presence = move || user_presences.write().get_user_presences(&user.read().jid).read().presence();      let show_icon = move || presence().map(|(_, presence)| {          match presence.presence { @@ -874,9 +874,9 @@ pub fn AvatarWithPresence(user: Store<User>) -> impl IntoView {  #[component]  pub fn ChatViewHeader(chat: MacawChat) -> impl IntoView { -    let chat_user = <ArcStore<filamento::user::User> as Clone>::clone(&chat.user).into(); +    let chat_user = <ArcRwSignal<filamento::user::User> as Clone>::clone(&chat.user).into();      let name = move || get_name(chat_user); -    let jid = move || chat_user.jid().read().to_string(); +    let jid = move || chat_user.with(|user| user.jid.to_string());      view! {          <div class="chat-view-header panel"> @@ -892,10 +892,10 @@ pub fn ChatViewHeader(chat: MacawChat) -> impl IntoView {  #[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 chat_chat: RwSignal<Chat> = +        <ArcRwSignal<filamento::chat::Chat> as Clone>::clone(&chat.chat).into(); +    let chat_user: RwSignal<User> = +        <ArcRwSignal<filamento::user::User> as Clone>::clone(&chat.user).into();      let load_set_messages = set_messages.clone();      let load_messages = LocalResource::new(move || { @@ -903,7 +903,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_untracked()) +                .get_messages_with_users(chat_chat.with(|chat| chat.correspondent.clone()))                  .await                  .map_err(|e| e.to_string());              match messages { @@ -937,39 +937,39 @@ 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_untracked()); +                .subscribe_chat(chat_chat.with(|chat| chat.correspondent.clone()));              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) -                        .timestamp() +                    if <ArcRwSignal<filamento::chat::Message> as Clone>::clone(&last.message)                          .read_untracked() -                        < *<ArcStore<filamento::chat::Message> as Clone>::clone(&new_message) -                            .timestamp() +                        .timestamp +                        < <ArcRwSignal<filamento::chat::Message> as Clone>::clone(&new_message)                              .read_untracked() +                            .timestamp                      {                          messages.insert( -                            <ArcStore<filamento::chat::Message> as Clone>::clone( +                            <ArcRwSignal<filamento::chat::Message> as Clone>::clone(                                  &new_message.message,                              ) -                            .id() -                            .get_untracked(), +                            .get_untracked() +                            .id,                              new_message,                          );                          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) -                                .timestamp() +                            <ArcRwSignal<filamento::chat::Message> as Clone>::clone(&value.message)                                  .read_untracked() +                                .timestamp                                  .cmp( -                                    &<ArcStore<filamento::chat::Message> as Clone>::clone( +                                    &<ArcRwSignal<filamento::chat::Message> as Clone>::clone(                                          &new_message.message,                                      ) -                                    .timestamp() -                                    .read_untracked(), +                                    .read_untracked() +                                    .timestamp                                  )                          }) {                              Ok(i) => i, @@ -978,20 +978,20 @@ 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( +                            <ArcRwSignal<filamento::chat::Message> as Clone>::clone(                                  &new_message.message,                              ) -                            .id() -                            .get_untracked(), +                            .get_untracked() +                            .id,                              new_message,                          );                          debug!("set the new message in message buffer");                      }                  } else {                      messages.insert( -                        <ArcStore<filamento::chat::Message> as Clone>::clone(&new_message.message) -                            .id() -                            .get_untracked(), +                        <ArcRwSignal<filamento::chat::Message> as Clone>::clone(&new_message.message) +                            .get_untracked() +                            .id,                          new_message,                      );                      debug!("set the new message in message buffer"); @@ -1003,7 +1003,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()); +                .unsubscribe_chat(sub_id, chat_chat.with(|chat| chat.correspondent.clone()));          }      }); @@ -1015,9 +1015,9 @@ pub fn MessageHistoryBuffer(chat: MacawChat) -> impl IntoView {              .into_iter()              .map(|(id, message)| {                  let message_timestamp = -                    <ArcStore<filamento::chat::Message> as Clone>::clone(&message.message) -                        .timestamp() +                    <ArcRwSignal<filamento::chat::Message> as Clone>::clone(&message.message)                          .read() +                        .timestamp                          .naive_local();                  // if message_timestamp.date() > last_timestamp.date() {                  //     messages_view = messages_view.push(date(message_timestamp.date())); @@ -1030,9 +1030,9 @@ pub fn MessageHistoryBuffer(chat: MacawChat) -> impl IntoView {                      false                  };                  last_user = Some( -                    <ArcStore<filamento::chat::Message> as Clone>::clone(&message.message) -                        .from() -                        .get(), +                    <ArcRwSignal<filamento::chat::Message> as Clone>::clone(&message.message) +                        .get() +                        .from                  );                  last_timestamp = message_timestamp;                  (id, (message, major, false)) @@ -1177,9 +1177,9 @@ pub fn Delivery(delivery: Delivery) -> impl IntoView {  #[component]  pub fn Message(message: MacawMessage, major: bool, r#final: bool) -> impl IntoView { -    let message_message: Store<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 message_message: RwSignal<Message> = +        <ArcRwSignal<filamento::chat::Message> as Clone>::clone(&message.message).into(); +    let message_user = <ArcRwSignal<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); @@ -1197,23 +1197,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.with(|message| message.timestamp).format("%H:%M").to_string()}</div>                      </div>                      <div class="message-text"> -                        {move || message_message.body().read().body.clone()} +                        {move || message_message.with(|message| message.body.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.with(|message| message.delivery).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.with(|message| message.timestamp).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.with(|message| message.body.body.clone())}</div> +                <div class="right message-delivery">{move || message_message.with(|message| message.delivery).map(|delivery| view! { <Delivery delivery /> } ) }</div>              </div>          }.into_any()      } @@ -1547,24 +1547,24 @@ impl<K: Eq + std::hash::Hash + Send + Sync + 'static, V: Send + Sync + 'static>  #[derive(Clone)]  struct MacawChat { -    chat: StateListener<JID, ArcStore<Chat>>, -    user: StateListener<JID, ArcStore<User>>, +    chat: StateListener<JID, ArcRwSignal<Chat>>, +    user: StateListener<JID, ArcRwSignal<User>>,  }  impl MacawChat {      fn got_chat_and_user(chat: Chat, user: User) -> Self { -        let chat_state_store: StateStore<JID, ArcStore<Chat>> = +        let chat_state_store: StateStore<JID, ArcRwSignal<Chat>> =              use_context().expect("no chat state store"); -        let user_state_store: StateStore<JID, ArcStore<User>> = +        let user_state_store: StateStore<JID, ArcRwSignal<User>> =              use_context().expect("no user state store"); -        let user = user_state_store.store(user.jid.clone(), ArcStore::new(user)); -        let chat = chat_state_store.store(chat.correspondent.clone(), ArcStore::new(chat)); +        let user = user_state_store.store(user.jid.clone(), ArcRwSignal::new(user)); +        let chat = chat_state_store.store(chat.correspondent.clone(), ArcRwSignal::new(chat));          Self { chat, user }      }  }  impl Deref for MacawChat { -    type Target = StateListener<JID, ArcStore<Chat>>; +    type Target = StateListener<JID, ArcRwSignal<Chat>>;      fn deref(&self) -> &Self::Target {          &self.chat @@ -1579,24 +1579,24 @@ impl DerefMut for MacawChat {  #[derive(Clone)]  struct MacawMessage { -    message: StateListener<Uuid, ArcStore<Message>>, -    user: StateListener<JID, ArcStore<User>>, +    message: StateListener<Uuid, ArcRwSignal<Message>>, +    user: StateListener<JID, ArcRwSignal<User>>,  }  impl MacawMessage {      fn got_message_and_user(message: Message, user: User) -> Self { -        let message_state_store: StateStore<Uuid, ArcStore<Message>> = +        let message_state_store: StateStore<Uuid, ArcRwSignal<Message>> =              use_context().expect("no message state store"); -        let user_state_store: StateStore<JID, ArcStore<User>> = +        let user_state_store: StateStore<JID, ArcRwSignal<User>> =              use_context().expect("no user state store"); -        let message = message_state_store.store(message.id, ArcStore::new(message)); -        let user = user_state_store.store(user.jid.clone(), ArcStore::new(user)); +        let message = message_state_store.store(message.id, ArcRwSignal::new(message)); +        let user = user_state_store.store(user.jid.clone(), ArcRwSignal::new(user));          Self { message, user }      }  }  impl Deref for MacawMessage { -    type Target = StateListener<Uuid, ArcStore<Message>>; +    type Target = StateListener<Uuid, ArcRwSignal<Message>>;      fn deref(&self) -> &Self::Target {          &self.message @@ -1610,11 +1610,11 @@ impl DerefMut for MacawMessage {  }  struct MacawUser { -    user: StateListener<JID, Store<User>>, +    user: StateListener<JID, RwSignal<User>>,  }  impl Deref for MacawUser { -    type Target = StateListener<JID, Store<User>>; +    type Target = StateListener<JID, RwSignal<User>>;      fn deref(&self) -> &Self::Target {          &self.user @@ -1629,22 +1629,22 @@ impl DerefMut for MacawUser {  #[derive(Clone)]  struct MacawContact { -    contact: Store<Contact>, -    user: StateListener<JID, ArcStore<User>>, +    contact: RwSignal<Contact>, +    user: StateListener<JID, ArcRwSignal<User>>,  }  impl MacawContact {      fn got_contact_and_user(contact: Contact, user: User) -> Self { -        let contact = Store::new(contact); -        let user_state_store: StateStore<JID, ArcStore<User>> = +        let contact = RwSignal::new(contact); +        let user_state_store: StateStore<JID, ArcRwSignal<User>> =              use_context().expect("no user state store"); -        let user = user_state_store.store(user.jid.clone(), ArcStore::new(user)); +        let user = user_state_store.store(user.jid.clone(), ArcRwSignal::new(user));          Self { contact, user }      }  }  impl Deref for MacawContact { -    type Target = Store<Contact>; +    type Target = RwSignal<Contact>;      fn deref(&self) -> &Self::Target {          &self.contact @@ -1739,14 +1739,14 @@ fn ChatsList() -> impl IntoView {  #[component]  fn RosterList() -> impl IntoView { -    let roster: Store<Roster> = use_context().expect("no roster in context"); +    let roster: RwSignal<Roster> = use_context().expect("no roster in context");      // TODO: filter new messages signal      view! {          <div class="roster-list panel">              <h2>Roster</h2>              <div class="roster-list-roster"> -                <For each=move || roster.contacts().get() key=|contact| contact.0.clone() let(contact)> +                <For each=move || roster.get().contacts key=|contact| contact.0.clone() let(contact)>                      <RosterListItem contact=contact.1 />                  </For>              </div> @@ -1756,18 +1756,18 @@ fn RosterList() -> impl IntoView {  #[component]  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 contact_contact: RwSignal<Contact> = contact.contact; +    let contact_user: RwSignal<User> = +        <ArcRwSignal<filamento::user::User> as Clone>::clone(&contact.user).into();      let name = move || get_name(contact_user); -    let open_chats: Store<OpenChatsPanel> = +    let open_chats: RwSignal<OpenChatsPanel> =          use_context().expect("no open chats panel store in context");      // 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.with(|user| user.jid.clone()),          have_chatted: false,      };      let chat = MacawChat::got_chat_and_user(chat, contact_user.get()); @@ -1778,16 +1778,16 @@ fn RosterListItem(contact: MacawContact) -> impl IntoView {      };      let open = move || { -        if let Some(open_chat) = &*open_chats.chat_view().read() { +        if let Some(open_chat) = &open_chats.read().chat_view {              debug!("got open chat: {:?}", open_chat); -            if *open_chat == *contact_user.jid().read() { +            if contact_user.with(|user| user.jid == *open_chat) {                  return Open::Focused;              }          }          if let Some(_backgrounded_chat) = open_chats -            .chats()              .read() -            .get(contact_user.jid().read().deref()) +            .chats +            .get(&contact_user.read().jid)          {              return Open::Open;          } @@ -1806,7 +1806,7 @@ fn RosterListItem(contact: MacawContact) -> impl IntoView {      }  } -pub async fn get_avatar(user: Store<User>) -> String { +pub async fn get_avatar(user: RwSignal<User>) -> String {      if let Some(avatar) = &user.read().avatar {          let client = use_context::<Client>().expect("client not in context");          if let Some(data) = client.file_store.get_src(avatar).await { @@ -1821,11 +1821,11 @@ pub async fn get_avatar(user: Store<User>) -> String {      }  } -pub fn get_name(user: Store<User>) -> String { -    let roster: Store<Roster> = use_context().expect("no roster in context"); +pub fn get_name(user: RwSignal<User>) -> String { +    let roster: RwSignal<Roster> = use_context().expect("no roster in context");      if let Some(name) = roster -        .contacts()          .read() +        .contacts          .get(&user.read().jid)          .map(|contact| contact.read().name.clone())          .unwrap_or_default() @@ -1867,14 +1867,14 @@ impl Open {  #[component]  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 chat_chat: RwSignal<Chat> = <ArcRwSignal<Chat> as Clone>::clone(&chat.chat).into(); +    let chat_user: RwSignal<User> = +        <ArcRwSignal<filamento::user::User> as Clone>::clone(&chat.user).into();      let name = move || get_name(chat_user);      // TODO: store fine-grained reactivity      let latest_message_body = move || message.get().body.body; -    let open_chats: Store<OpenChatsPanel> = +    let open_chats: RwSignal<OpenChatsPanel> =          use_context().expect("no open chats panel store in context");      let open_chat = move |_| { @@ -1883,16 +1883,16 @@ fn ChatsListItem(chat: MacawChat, message: MacawMessage) -> impl IntoView {      };      let open = move || { -        if let Some(open_chat) = &*open_chats.chat_view().read() { +        if let Some(open_chat) = &open_chats.read().chat_view {              debug!("got open chat: {:?}", open_chat); -            if *open_chat == *chat_chat.correspondent().read() { +            if chat_chat.with(|chat| chat.correspondent == *open_chat) {                  return Open::Focused;              }          }          if let Some(_backgrounded_chat) = open_chats -            .chats()              .read() -            .get(chat_chat.correspondent().read().deref()) +            .chats +            .get(&chat_chat.read().correspondent)          {              return Open::Open;          }  | 
