Add icons & mentions/unread counts to community list

This commit is contained in:
Andrea Maria Piana 2022-11-14 16:37:00 +00:00
parent 48f86ff862
commit c7ac53fdd0
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
8 changed files with 251 additions and 80 deletions

View File

@ -6,10 +6,49 @@
[quo2.components.counter.counter :as counter]
[quo2.components.icon :as icons]
[quo2.components.community.style :as style]
[react-native.fast-image :as fast-image]
[react-native.core :as rn]))
(defn communities-list-view-item [props {:keys [name locked? status notifications
tokens background-color]}]
(defn community-icon-view [community-icon]
[rn/view {:width 32
:height 32}
[fast-image/fast-image {:source {:uri community-icon}
:style {:height 32
:border-radius 16
:width 32}}]])
(defn notification-view [{:keys [muted?
unread-messages?
unread-mentions-count]}]
(cond
muted?
[icons/icon :i/muted {:container-style {:align-items :center
:justify-content :center}
:resize-mode :center
:size 20
:color (colors/theme-colors
colors/neutral-40
colors/neutral-50)}]
(pos? unread-mentions-count)
[counter/counter {:type :default} unread-mentions-count]
unread-messages?
[rn/view {:style {:width 8
:height 8
:border-radius 4
:background-color (colors/theme-colors
colors/neutral-40
colors/neutral-60)}}]))
(defn communities-list-view-item [props {:keys [name
locked?
status
muted?
unread-messages?
unread-mentions-count
community-icon
tokens
background-color]}]
[rn/view {:style (merge (style/community-card 16)
{:margin-bottom 12
:margin-horizontal 20})}
@ -24,8 +63,8 @@
:padding-vertical 8
:background-color background-color}
[rn/view]
;;TODO new pure component based on quo2 should be implemented without status-im usage
;[communities.icon/community-icon-redesign community 32]]
(when community-icon
[community-icon-view community-icon])
[rn/view {:flex 1
:margin-horizontal 12}
[text/text {:weight :semi-bold
@ -33,7 +72,7 @@
:accessibility-label :community-name-text
:number-of-lines 1
:ellipsize-mode :tail
:style {:color (when (= notifications :muted)
:style {:color (when muted?
(colors/theme-colors
colors/neutral-40
colors/neutral-60))}}
@ -42,28 +81,18 @@
(if (= status :gated)
[community-view/permission-tag-container {:locked? locked?
:tokens tokens}]
(cond
(= notifications :unread-messages-count)
[rn/view {:style {:width 8
:height 8
:border-radius 4
:background-color (colors/theme-colors
colors/neutral-40
colors/neutral-60)}}]
[notification-view {:muted? muted?
:unread-mentions-count unread-mentions-count
:unread-messages? unread-messages?}])]]]])
(= notifications :unread-mentions-count)
[counter/counter {:type :default} 5]
(= notifications :muted)
[icons/icon :i/muted {:container-style {:align-items :center
:justify-content :center}
:resize-mode :center
:size 20
:color (colors/theme-colors
colors/neutral-40
colors/neutral-50)}]))]]]])
(defn communities-membership-list-item [props {:keys [name status tokens locked?]}]
(defn communities-membership-list-item [props {:keys [name
muted?
unread-messages?
unread-mentions-count
status
community-icon
tokens
locked?]}]
[rn/view {:margin-bottom 20}
[rn/touchable-highlight (merge {:underlay-color colors/primary-50-opa-5
:style {:border-radius 12}}
@ -72,8 +101,9 @@
[rn/view {:flex-direction :row
:border-radius 16
:align-items :center}
;;TODO new pure component based on quo2 should be implemented without status-im usage
;[communities.icon/community-icon-redesign community 32]
(when community-icon
[community-icon-view community-icon])
[rn/view {:flex 1
:margin-left 12
:justify-content :center}
@ -84,8 +114,12 @@
:weight :semi-bold
:size :paragraph-1}
name]]
(when (= status :gated)
[rn/view {:justify-content :center
:margin-right 12}
:margin-right 16}
(if (= status :gated)
[community-view/permission-tag-container {:locked? locked?
:tokens tokens}]])]]]])
:tokens tokens}]
[notification-view {:muted? muted?
:unread-mentions-count unread-mentions-count
:unread-messages? unread-messages?}])]]]]])

View File

@ -8,7 +8,7 @@
[quo2.foundations.colors :as colors]
[quo2.components.community.discover-card :as discover-card]
[quo2.components.navigation.top-nav :as topnav]
[status-im.utils.handlers :refer [<sub >evt]]
[status-im.utils.re-frame :as rf]
[status-im.i18n.i18n :as i18n]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.react :as rn]
@ -18,26 +18,24 @@
(def selected-tab (reagent/atom :joined))
(defn plus-button []
(let [logging-in? (<sub [:multiaccounts/login])]
(let [logging-in? (rf/sub [:multiaccounts/login])]
[components.plus-button/plus-button
{:on-press (when-not logging-in?
#(re-frame/dispatch [:bottom-sheet/show-sheet :add-new {}]))
:loading logging-in?
:accessibility-label :new-chat-button}]))
(defn render-fn [community-item]
(defn render-fn [id]
(let [community-item (rf/sub [:communities/home-item id])]
[community-list-view/communities-membership-list-item
{:on-press (fn []
(>evt [:communities/load-category-states (:id community-item)])
(>evt [:dismiss-keyboard])
(>evt [:navigate-to :community {:community-id (:id community-item)}]))
:on-long-press #(>evt [:bottom-sheet/show-sheet
(rf/dispatch [:communities/load-category-states id])
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:navigate-to :community {:community-id id}]))
:on-long-press #(rf/dispatch [:bottom-sheet/show-sheet
{:content (fn []
[community/community-actions community-item])}])}
community-item])
(defn community-list-key-fn [item]
(:id item))
community-item]))
(defn get-item-layout-js [_ index]
#js {:length 64 :offset (* 64 index) :index index})
@ -55,18 +53,19 @@
{:id :pending :label (i18n/label :t/pending) :accessibility-label :pending-tab}
{:id :opened :label (i18n/label :t/opened) :accessibility-label :opened-tab}]}]])
(defn communities-list [communities]
(defn communities-list [community-ids]
[list/flat-list
{:key-fn community-list-key-fn
{:key-fn identity
:getItemLayout get-item-layout-js
:keyboard-should-persist-taps :always
:shows-horizontal-scroll-indicator false
:data communities
:data community-ids
:render-fn render-fn}])
(defn segments-community-lists [communities]
(let [tab @selected-tab]
[rn/view {:style {:padding-left 20
:padding-right 8
:padding-vertical 12}}
(case tab
:joined
@ -96,13 +95,13 @@
[plus-button]])
(defn discover-card []
[discover-card/discover-card {:on-press #(>evt [:navigate-to :discover-communities])
[discover-card/discover-card {:on-press #(rf/dispatch [:navigate-to :discover-communities])
:title (i18n/label :t/discover)
:description (i18n/label :t/whats-trending)
:accessibility-label :communities-home-discover-card}])
(defn communities-home []
(let [communities (<sub [:communities/communities])]
(let [communities (rf/sub [:communities/community-ids])]
[rn/view {:flex 1}
[topnav/top-nav {:type :default}]
[title-column]
@ -119,5 +118,3 @@
colors/neutral-5
colors/neutral-95)}}
[communities-home]])])

View File

@ -2,24 +2,9 @@
(:require [quo.react-native :as rn]
[quo.previews.preview :as preview]
[reagent.core :as reagent]
[status-im.constants :as constants]
[quo.design-system.colors :as quo.colors]
[quo2.foundations.colors :as colors]
[quo2.components.community.community-list-view :as community-list-view]
[status-im.i18n.i18n :as i18n]
[status-im.react-native.resources :as resources]))
(def community-data
{:id constants/status-community-id
:name "Status"
:description "Status is a secure messaging app, crypto wallet and web3 browser built with the state of the art technology"
:cover (resources/get-image :community-cover)
:community-icon (resources/get-image :status-logo)
:color (rand-nth quo.colors/chat-colors)
:tokens [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}]
:tags [{:id 1 :tag-label (i18n/label :t/music) :resource (resources/get-image :music)}
{:id 2 :tag-label (i18n/label :t/lifestyle) :resource (resources/get-image :lifestyle)}
{:id 3 :tag-label (i18n/label :t/podcasts) :resource (resources/get-image :podcasts)}]})
[status-im.ui2.screens.quo2-preview.community.data :as data]))
(def descriptor [{:label "Notifications:"
:key :notifications
@ -56,8 +41,15 @@
[preview/customizer state descriptor]]
[rn/view {:padding-vertical 60
:justify-content :center}
[community-list-view/communities-list-view-item {} (merge @state
community-data)]]]])))
[community-list-view/communities-list-view-item {} (cond-> (merge @state data/community)
(= :muted (:notifications @state))
(assoc :muted? true)
(= :unread-mentions-count (:notifications @state))
(assoc :unread-mentions-count 5)
(= :unread-messages-count (:notifications @state))
(assoc :unread-messages? true))]]]])))
(defn preview-community-list-view []
[rn/view {:background-color (colors/theme-colors colors/neutral-5
@ -67,4 +59,3 @@
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -0,0 +1,61 @@
(ns status-im.ui2.screens.quo2-preview.community.community-membership-list-view
(:require [quo.react-native :as rn]
[quo.previews.preview :as preview]
[reagent.core :as reagent]
[quo2.foundations.colors :as colors]
[status-im.ui2.screens.quo2-preview.community.data :as data]
[quo2.components.community.community-list-view :as community-list-view]))
(def descriptor [{:label "Notifications:"
:key :notifications
:type :select
:options [{:key :muted
:value "Muted"}
{:key :unread-mentions-count
:value "Mention counts"}
{:key :unread-messages-count
:value "Unread messages"}]}
{:label "Status:"
:key :status
:type :select
:options [{:key :gated
:value "Gated"}
{:key :open
:value "Open"}]}
{:label "Locked:"
:key :locked?
:type :boolean}])
(defn cool-preview []
(let [notifications (reagent/atom (:notifications nil))
state (reagent/atom {:locked? true
:notifications nil
:status (if notifications
:gated
:open)})]
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:padding-bottom 150}
[rn/view {:flex 1
:padding 16}
[preview/customizer state descriptor]]
[rn/view {:padding-vertical 60
:justify-content :center}
[community-list-view/communities-membership-list-item {} (cond-> (merge @state data/community)
(= :muted (:notifications @state))
(assoc :muted? true)
(= :unread-mentions-count (:notifications @state))
(assoc :unread-mentions-count 5)
(= :unread-messages-count (:notifications @state))
(assoc :unread-messages? true))]]]])))
(defn preview-community-list-view []
[rn/view {:background-color (colors/theme-colors colors/neutral-5
colors/neutral-95)
:flex 1}
[rn/flat-list {:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -0,0 +1,18 @@
(ns status-im.ui2.screens.quo2-preview.community.data
(:require
[quo.design-system.colors :as quo.colors]
[status-im.i18n.i18n :as i18n]
[status-im.react-native.resources :as resources]))
(def thumbnail "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII")
(def community
{:id "0xsomeid"
:name "Status"
:description "Status is a secure messaging app, crypto wallet and web3 browser built with the state of the art technology"
:community-icon thumbnail
:color (rand-nth quo.colors/chat-colors)
:tokens [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}]
:tags [{:id 1 :tag-label (i18n/label :t/music) :resource (resources/get-image :music)}
{:id 2 :tag-label (i18n/label :t/lifestyle) :resource (resources/get-image :lifestyle)}
{:id 3 :tag-label (i18n/label :t/podcasts) :resource (resources/get-image :podcasts)}]})

View File

@ -16,6 +16,7 @@
[status-im.ui2.screens.quo2-preview.counter.counter :as counter]
[status-im.ui2.screens.quo2-preview.community.community-card-view :as community-card]
[status-im.ui2.screens.quo2-preview.community.community-list-view :as community-list-view]
[status-im.ui2.screens.quo2-preview.community.community-membership-list-view :as community-membership-list-view]
[status-im.ui2.screens.quo2-preview.community.discover-card :as discover-card]
[status-im.ui2.screens.quo2-preview.dividers.divider-label :as divider-label]
[status-im.ui2.screens.quo2-preview.dividers.new-messages :as new-messages]
@ -86,6 +87,9 @@
{:name :community-list-view
:insets {:top false}
:component community-list-view/preview-community-list-view}
{:name :community-membership-list-view
:insets {:top false}
:component community-membership-list-view/preview-community-list-view}
{:name :discover-card
:insets {:top false}
:component discover-card/preview-discoverd-card}]

View File

@ -99,6 +99,29 @@
(string/includes? (string/lower-case (str name)) search-filter))))
(vals communities))))
(re-frame/reg-sub
:communities/community-ids
:<- [:communities/communities]
(fn [communities]
(map :id communities)))
(defn community->home-item [community counts]
{:name (:name community)
:muted? (:muted community)
:unread-messages? (pos? (:unviewed-messages-count counts))
:unread-mentions-count (:unviewed-mentions-count counts)
:community-icon (get-in community [:images :thumbnail :uri])})
(re-frame/reg-sub
:communities/home-item
(fn [[_ community-id]]
[(re-frame/subscribe [:raw-communities])
(re-frame/subscribe [:communities/unviewed-counts community-id])])
(fn [[communities counts] [_ identity]]
(community->home-item
(get communities identity)
counts)))
(re-frame/reg-sub
:communities/edited-community
:<- [:communities]
@ -123,17 +146,20 @@
0
chats)))
(re-frame/reg-sub
:communities/unviewed-counts
(fn [[_ community-id]]
[(re-frame/subscribe [:chats/by-community-id community-id])])
(fn [[chats]]
(defn calculate-unviewed-counts [chats]
(reduce (fn [acc {:keys [unviewed-mentions-count unviewed-messages-count]}]
{:unviewed-messages-count (+ (:unviewed-messages-count acc) (or unviewed-messages-count 0))
:unviewed-mentions-count (+ (:unviewed-mentions-count acc) (or unviewed-mentions-count 0))})
{:unviewed-messages-count 0
:unviewed-mentions-count 0}
chats)))
chats))
(re-frame/reg-sub
:communities/unviewed-counts
(fn [[_ community-id]]
[(re-frame/subscribe [:chats/by-community-id community-id])])
(fn [[chats]]
(calculate-unviewed-counts chats)))
(re-frame/reg-sub
:communities/requests-to-join-for-community

View File

@ -0,0 +1,40 @@
(ns status-im2.subs.communities-test
(:require [cljs.test :refer [deftest is testing]]
[status-im2.subs.communities :as subs]))
(deftest community->home-item-test
(testing "has unread messages"
(is (= {:name "name-1"
:muted? true
:unread-messages? true
:unread-mentions-count 5
:community-icon "icon-1"}
(subs/community->home-item
{:name "name-1"
:muted true
:images {:thumbnail {:uri "icon-1"}}}
{:unviewed-messages-count 1
:unviewed-mentions-count 5}))))
(testing "no unread messages"
(is (= {:name "name-2"
:muted? false
:unread-messages? false
:unread-mentions-count 5
:community-icon "icon-2"}
(subs/community->home-item
{:name "name-2"
:muted false
:images {:thumbnail {:uri "icon-2"}}}
{:unviewed-messages-count 0
:unviewed-mentions-count 5})))))
(deftest calculate-unviewed-counts-test
(let [chats [{:unviewed-messages-count 1
:unviewed-mentions-count 2}
{:unviewed-messages-count 3
:unviewed-mentions-count 0}
{:unviewed-messages-count 2
:unviewed-mentions-count 1}]]
(is (= {:unviewed-messages-count 6
:unviewed-mentions-count 3}
(subs/calculate-unviewed-counts chats)))))