diff options
| author | 2025-05-08 03:31:04 +0100 | |
|---|---|---|
| committer | 2025-05-08 03:31:04 +0100 | |
| commit | 0d8855bee79cc493f40b5092434bce724a3adb55 (patch) | |
| tree | 649d94bc850f9682fb7a96de5d3a2c87aa43ceff /src | |
| parent | 01bf0c11eaea7c3d8b12712143569b3931a5ae33 (diff) | |
| download | macaw-web-0d8855bee79cc493f40b5092434bce724a3adb55.tar.gz macaw-web-0d8855bee79cc493f40b5092434bce724a3adb55.tar.bz2 macaw-web-0d8855bee79cc493f40b5092434bce724a3adb55.zip  | |
feat/fix: highlight open chat in chats list, clear message composer on new chat opened
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 70 | 
1 files changed, 68 insertions, 2 deletions
@@ -169,7 +169,7 @@ fn LoginPage(set_app: WriteSignal<AppState>, set_client: RwSignal<Option<(Client          <div class="center fill">              <div id="login-form" class="panel">                  <div id="hero"> -                    <img src="/assets/icon.png" /> +                    <img src="/assets/macaw-icon.png" />                      <h1>Macaw Instant Messenger</h1>                  </div>                  {error_message} @@ -464,12 +464,33 @@ fn Macaw(      });      view! { +        <Dock />          <ChatsList />          <OpenChatsPanelView />      }  }  #[component] +pub fn Dock() -> impl IntoView { +    view! { +        <div class="dock panel"> +            <div class="shortcuts"> +                <div class="roster-tab dock-icon"> +                    <img src="/assets/caw.png" /> +                </div> +                <div class="chats-tab dock-icon"> +                    <img src="/assets/bubble.png" /> +                </div> +            </div> +            <div class="pins"> +            </div> +            <div class="personal"> +            </div> +        </div> +    } +} + +#[component]  pub fn OpenChatsPanelView() -> impl IntoView {      let open_chats: Store<OpenChatsPanel> = use_context().expect("no open chats panel in context"); @@ -805,6 +826,8 @@ pub fn ChatViewMessageComposer(chat: JID) -> impl IntoView {      let _focus = Effect::new(move |_| {          if let Some(input) = message_input.get() {              let _ = input.focus(); +            // TODO: set the last draft +            input.set_text_content(Some(""));              // input.style("height: 0");              // let height = input.scroll_height();              // input.style(format!("height: {}px", height)); @@ -1258,8 +1281,36 @@ pub fn get_name(user: Store<User>) -> String {      }  } +pub enum Open { +    /// Currently on screen +    Focused, +    /// Open in background somewhere (e.g. in another chat tab) +    Open, +    /// Closed +    Closed, +} + +impl Open { +    pub fn is_focused(&self) -> bool { +        match self { +            Open::Focused => true, +            Open::Open => false, +            Open::Closed => false, +        } +    } + +    pub fn is_open(&self) -> bool { +        match self { +            Open::Focused => true, +            Open::Open => true, +            Open::Closed => false, +        } +    } +} +  #[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 avatar = LocalResource::new(move || get_avatar(chat_user));      let name = move || get_name(chat_user); @@ -1273,8 +1324,23 @@ fn ChatsListItem(chat: MacawChat, message: MacawMessage) -> impl IntoView {          open_chats.update(|open_chats| open_chats.open(chat.clone()));      }; +    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() { +                return Open::Focused +            } +        } +        if let Some(_backgrounded_chat) = open_chats.chats().read().get(chat_chat.correspondent().read().deref()) { +            return Open::Open +        }  +        Open::Closed +    }; +    let focused =move || open().is_focused(); +    let open=move || open().is_open(); +      view! { -        <div class="chats-list-item" on:click=open_chat> +        <div class="chats-list-item" class:open=move || open() class:focused=move || focused() on:click=open_chat>              <Transition fallback=|| view! { <img class="avatar" src=NO_AVATAR /> } >                  <img class="avatar" src=move || avatar.read().as_deref().map(|avatar| avatar.clone()).unwrap_or_default() />              </Transition>  | 
