[7785] fix - Implement the correct list item layout in chats list

Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
bitsikka 2019-08-30 00:39:45 +05:45 committed by Andrey Shovkoplyas
parent 12c08b1398
commit df3473dbef
No known key found for this signature in database
GPG Key ID: EAAB7C8622D860A4
7 changed files with 138 additions and 196 deletions

View File

@ -715,6 +715,16 @@
(fn [{:keys [unviewed-messages-count]}] (fn [{:keys [unviewed-messages-count]}]
unviewed-messages-count)) unviewed-messages-count))
(re-frame/reg-sub
:chats/last-message-content
(fn [[_ chat-id]]
(re-frame/subscribe [:chats/chat chat-id]))
(fn [{:keys [last-message-content last-message-content-type timestamp last-message-timestamp]}]
{:content last-message-content
:content-type last-message-content-type
:last-message-timestamp last-message-timestamp
:timestamp timestamp}))
(re-frame/reg-sub (re-frame/reg-sub
:chats/photo-path :chats/photo-path
:<- [:contacts/contacts] :<- [:contacts/contacts]

View File

@ -41,10 +41,9 @@
:border-radius 32})) :border-radius 32}))
(def default-chat-icon-text (def default-chat-icon-text
{:color colors/white {:color (colors/alpha colors/white 0.7)
:font-size 20 :typography :title-bold
:font-weight "700" :line-height 21})
:opacity 0.8})
(def message-status-icon-text (def message-status-icon-text
{:margin-top -2 {:margin-top -2

View File

@ -67,8 +67,9 @@
:else [icon])]) :else [icon])])
(defn- title-row [{:keys [title title-color-override title-prefix title-prefix-width (defn- title-row [{:keys [title title-color-override title-prefix
title-prefix-height title-row-accessory]} title-prefix-width title-prefix-height
title-accessibility-label title-row-accessory]}
type icon? disabled? theme subtitle content accessories] type icon? disabled? theme subtitle content accessories]
[react/view styles/title-row-container [react/view styles/title-row-container
(when title-prefix (when title-prefix
@ -77,9 +78,9 @@
(= "main-icons" (namespace title-prefix))) (= "main-icons" (namespace title-prefix)))
[icons/icon title-prefix [icons/icon title-prefix
(merge (merge
{:color colors/gray {:color colors/gray
:width 16 :width 16
:height 16 :height 16
:container-style :container-style
(styles/title-prefix-icon-container (styles/title-prefix-icon-container
title-prefix-height title-prefix-width)} title-prefix-height title-prefix-width)}
@ -109,13 +110,17 @@
(cond (cond
(or (string? title) (keyword? title) (number? title)) (or (string? title) (keyword? title) (number? title))
[react/text {:number-of-lines 1 [react/text
:ellipsize-mode :tail (merge
:style {:number-of-lines 1
(styles/title :ellipsize-mode :tail
type theme icon? title-prefix subtitle :style
content title-row-accessory disabled? (styles/title
title-color-override)} type theme icon? title-prefix subtitle
content title-row-accessory disabled?
title-color-override)}
(when title-accessibility-label
{:accessibility-label title-accessibility-label}))
(stringify title)] (stringify title)]
(vector? title) (vector? title)
@ -288,6 +293,11 @@
;; title-color-override ;; title-color-override
;; colors/color - only occasionally needed, self-explanatory ;; colors/color - only occasionally needed, self-explanatory
;; title-accessibility-label
;; :accessibility-label for title text component
;; sometimes needed for title - e.g. chat-list-item
;; makes sense since `title` is the key element of a list item
;; title-row-accessory ;; title-row-accessory
;; component - especially made for chat list item, but may serve other ;; component - especially made for chat list item, but may serve other
;; purpose in the unlikely future. Wrapper already has 2px :margin-top ;; purpose in the unlikely future. Wrapper already has 2px :margin-top
@ -334,9 +344,9 @@
[{:keys [type theme container-margin-top container-margin-bottom [{:keys [type theme container-margin-top container-margin-bottom
icon title-prefix title-prefix-width title-prefix-height icon title-prefix title-prefix-width title-prefix-height
title title-color-override title-row-accessory title title-color-override title-row-accessory
subtitle subtitle-max-lines subtitle-row-accessory title-accessibility-label subtitle subtitle-max-lines
content accessories on-press on-long-press subtitle-row-accessory content accessories on-press
error accessibility-label disabled?] on-long-press error accessibility-label disabled?]
:or {type :default :or {type :default
theme :default theme :default
disabled? false disabled? false
@ -344,12 +354,13 @@
container-margin-bottom 0 container-margin-bottom 0
subtitle-max-lines 1}}] subtitle-max-lines 1}}]
(let [title-row-elements (let [title-row-elements
{:title title {:title title
:title-color-override title-color-override :title-color-override title-color-override
:title-prefix title-prefix :title-accessibility-label title-accessibility-label
:title-prefix-width title-prefix-width :title-prefix title-prefix
:title-prefix-height title-prefix-height :title-prefix-width title-prefix-width
:title-row-accessory title-row-accessory} :title-prefix-height title-prefix-height
:title-row-accessory title-row-accessory}
subtitle-row-elements subtitle-row-elements
{:subtitle subtitle {:subtitle subtitle
:subtitle-max-lines subtitle-max-lines :subtitle-max-lines subtitle-max-lines

View File

@ -1,8 +1,7 @@
(ns status-im.ui.screens.home.styles (ns status-im.ui.screens.home.styles
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]]) (:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
(:require [status-im.ui.components.colors :as colors] (:require [status-im.ui.components.colors :as colors]
[status-im.utils.platform :as platform] [status-im.utils.platform :as platform]))
[status-im.ui.components.bottom-bar.styles :as tabs.styles]))
(defn toolbar [] (defn toolbar []
{:background-color colors/white}) {:background-color colors/white})
@ -12,83 +11,14 @@
(defstyle sync-info {:margin-horizontal 15}) (defstyle sync-info {:margin-horizontal 15})
(defstyle chat-container
{:flex-direction :row
:android {:height 76}
:ios {:height 74}
:desktop {:height 74}
:overflow :hidden})
(defstyle chat-icon-container
{:padding-top 18
:padding-bottom 18
:padding-left 12
:padding-right 20
:width 72
:android {:height 76}
:ios {:height 74}
:desktop {:height 74}})
(defstyle chat-info-container
{:margin-bottom 13
:justify-content :space-between
:flex 1
:flex-direction :column
:android {:margin-top 16}
:ios {:margin-top 14}
:desktop {:margin-top 14}})
(defstyle chat-options-container
{:padding-top 10})
(defstyle item-upper-container
{:flex 1
:flex-direction :row
:padding-right 16})
(defstyle item-lower-container
{:flex 1
:flex-direction :row
:justify-content :space-between
:padding-right 16
:android {:margin-top 4}
:ios {:margin-top 6}
:desktop {:margin-top 6}})
(def message-status-container
{:flex-direction :row
:align-items :center})
(def name-view
{:flex-direction :row
:flex 1
:margin-right 4})
(defstyle name-text
{:color colors/text
:android {:font-size 16
:height 26}
:ios {:font-size 17
:height 26}
:desktop {:font-size 17
:height 26}})
(defstyle private-group-icon-container
{:align-items :center
:justify-content :center
:margin-right 6})
(defstyle public-group-icon-container
{:align-items :center
:justify-content :center
:margin-right 6})
(def last-message-container (def last-message-container
{:flex-shrink 1}) {:flex-shrink 1})
(def last-message-text (def last-message-text
{:color colors/text-gray {:flex 1
:max-height 24}) :align-self :stretch
:line-height 22
:color colors/gray})
(def search-input-height 56) (def search-input-height 56)
@ -133,10 +63,12 @@
:height 16}) :height 16})
(defstyle datetime-text (defstyle datetime-text
{:color colors/text-gray {:color colors/text-gray
:android {:font-size 12} :font-size 10
:desktop {:font-size 14} :text-align :right
:ios {:font-size 12}}) :letter-spacing 0.4
:align-items :center
:line-height 12})
(defstyle new-messages-text (defstyle new-messages-text
{:left 0 {:left 0
@ -189,10 +121,7 @@
{:position :absolute {:position :absolute
:z-index 2 :z-index 2
:align-items :center :align-items :center
:bottom (+ tabs.styles/tabs-diff (cond :bottom 16
platform/ios? 16
platform/android? 0
platform/desktop? 6))
:left (- (/ home-width 2) 20) :left (- (/ home-width 2) 20)
:width 40 :width 40
:height 40}) :height 40})

View File

@ -11,6 +11,7 @@
[status-im.ui.components.toolbar.view :as toolbar] [status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.screens.home.styles :as styles] [status-im.ui.screens.home.styles :as styles]
[status-im.ui.screens.home.filter.views :as filter.views] [status-im.ui.screens.home.filter.views :as filter.views]
[status-im.utils.platform :as platform]
[status-im.utils.utils :as utils] [status-im.utils.utils :as utils]
[status-im.ui.components.bottom-bar.styles :as tabs.styles] [status-im.ui.components.bottom-bar.styles :as tabs.styles]
[status-im.ui.screens.home.views.inner-item :as inner-item] [status-im.ui.screens.home.views.inner-item :as inner-item]
@ -93,16 +94,15 @@
false)})) false)}))
[list/flat-list {:data all-home-items [list/flat-list {:data all-home-items
:key-fn first :key-fn first
:footer [react/view :header [react/view {:height 4 :flex 1}]
{:style {:height tabs.styles/tabs-diff :footer [react/view {:height 4 :flex 1}]
:align-self :stretch}}]
:on-scroll-begin-drag :on-scroll-begin-drag
(fn [e] (fn [e]
(reset! scrolling-from-top? (reset! scrolling-from-top?
;; check if scrolling up from top of list ;; check if scrolling up from top of list
(zero? (.-y (.-contentOffset (.-nativeEvent e)))))) (zero? (.-y (.-contentOffset (.-nativeEvent e))))))
:render-fn :render-fn
(fn [home-item] (fn [home-item _]
[inner-item/home-list-item home-item])}] [inner-item/home-list-item home-item])}]
(when (:to-hide? @search-input-state) (when (:to-hide? @search-input-state)
[react/view {:width 1 [react/view {:width 1
@ -128,7 +128,10 @@
(let [home-width (if (> window-width constants/two-pane-min-width) (let [home-width (if (> window-width constants/two-pane-min-width)
(max constants/left-pane-min-width (/ window-width 3)) (max constants/left-pane-min-width (/ window-width 3))
window-width)] window-width)]
[react/view (merge {:flex 1 :width home-width} [react/view (merge {:flex 1
:width home-width}
(when platform/ios?
{:margin-bottom tabs.styles/tabs-diff})
(when two-pane-ui-enabled? (when two-pane-ui-enabled?
{:border-right-width 1 :border-right-color colors/black-transparent})) {:border-right-width 1 :border-right-color colors/black-transparent}))
[status-bar/status-bar {:type :main}] [status-bar/status-bar {:type :main}]

View File

@ -14,7 +14,8 @@
[status-im.ui.screens.home.styles :as styles] [status-im.ui.screens.home.styles :as styles]
[status-im.utils.contenthash :as contenthash] [status-im.utils.contenthash :as contenthash]
[status-im.utils.core :as utils] [status-im.utils.core :as utils]
[status-im.utils.datetime :as time]) [status-im.utils.datetime :as time]
[status-im.ui.components.list-item.views :as list-item])
(:require-macros [status-im.utils.views :refer [defview letsubs]])) (:require-macros [status-im.utils.views :refer [defview letsubs]]))
(defview command-short-preview [message] (defview command-short-preview [message]
@ -23,43 +24,46 @@
(when-let [command (commands-receiving/lookup-command-by-ref message id->command)] (when-let [command (commands-receiving/lookup-command-by-ref message id->command)]
(commands/generate-short-preview command (commands/add-chat-contacts contacts message))))) (commands/generate-short-preview command (commands/add-chat-contacts contacts message)))))
(defn message-content-text [{:keys [content content-type] :as message}] (defview message-content-text [chat-id]
[react/view styles/last-message-container (letsubs [{:keys [content content-type] :as message} [:chats/last-message-content chat-id]]
(cond [react/view styles/last-message-container
(cond
(not (and content content-type)) (not (and content content-type))
[react/text {:style styles/last-message-text [react/text {:style styles/last-message-text
:accessibility-label :no-messages-text} :accessibility-label :no-messages-text}
(i18n/label :t/no-messages)] (i18n/label :t/no-messages)]
(= constants/content-type-command content-type) (= constants/content-type-command content-type)
[command-short-preview message] [command-short-preview message]
(= constants/content-type-sticker content-type) (= constants/content-type-sticker content-type)
[react/image {:style {:margin 2 :width 30 :height 30} [react/image {:style {:margin 1 :width 20 :height 20}
:source {:uri (contenthash/url (:hash content))}}] :source {:uri (contenthash/url (:hash content))}}]
(string/blank? (:text content)) (string/blank? (:text content))
[react/text {:style styles/last-message-text} [react/text {:style styles/last-message-text}
""] ""]
(:text content) (:text content)
[react/text {:style styles/last-message-text [react/text {:style styles/last-message-text
:number-of-lines 1 :number-of-lines 1
:accessibility-label :chat-message-text} :accessibility-label :chat-message-text}
(:text content)] (:text content)]
:else :else
[react/text {:style styles/last-message-text [react/text {:style styles/last-message-text
:number-of-lines 1 :number-of-lines 1
:accessibility-label :chat-message-text} :accessibility-label :chat-message-text}
content])]) content])]))
(defn message-timestamp [timestamp] (defview message-timestamp [chat-id]
(when timestamp (letsubs [{:keys [last-message-timestamp timestamp]} [:chats/last-message-content chat-id]]
[react/text {:style styles/datetime-text (let [ts (if (pos? last-message-timestamp) last-message-timestamp timestamp)]
:accessibility-label :last-message-time-text} (when ts
(time/to-short-str timestamp)])) [react/text {:style styles/datetime-text
:accessibility-label :last-message-time-text}
(string/upper-case (time/to-short-str ts))]))))
(defview unviewed-indicator [chat-id] (defview unviewed-indicator [chat-id]
(letsubs [unviewed-messages-count [:chats/unviewed-messages-count chat-id]] (letsubs [unviewed-messages-count [:chats/unviewed-messages-count chat-id]]
@ -68,54 +72,36 @@
:accessibility-label :unread-messages-count-text} :accessibility-label :unread-messages-count-text}
unviewed-messages-count]))) unviewed-messages-count])))
(defn chat-list-item-name [chat-name group-chat? public? public-key]
(let [private-group? (and group-chat? (not public?))
public-group? (and group-chat? public?)]
[react/view styles/name-view
(when public-group?
[react/view styles/public-group-icon-container
[vector-icons/tiny-icon :tiny-icons/tiny-public {:color colors/gray}]])
(when private-group?
[react/view styles/private-group-icon-container
[vector-icons/tiny-icon :tiny-icons/tiny-group {:color colors/gray}]])
[react/view {:flex-shrink 1
:align-items :center
:justify-content :center}
[react/text {:style styles/name-text
:number-of-lines 1
:accessibility-label :chat-name-text}
chat-name]]]))
(defn home-list-item [[home-item-id home-item]] (defn home-list-item [[home-item-id home-item]]
(let [{:keys [chat-id chat-name (let [{:keys
name color online [chat-id chat-name name
group-chat public? color online group-chat
public-key contact public? public-key
last-message-timestamp contact]} home-item
timestamp private-group? (and group-chat (not public?))
last-message-content public-group? (and group-chat public?)
last-message-content-type]} home-item truncated-chat-name (utils/truncate-str chat-name 30)
truncated-chat-name (utils/truncate-str chat-name 30) chat-actions (cond
chat-actions (cond (and group-chat public?) :public-chat-actions
(and group-chat public?) :public-chat-actions (and group-chat (not public?)) :group-chat-actions
(and group-chat (not public?)) :group-chat-actions :else :private-chat-actions)]
:else :private-chat-actions)] [list-item/list-item
[react/touchable-highlight {:on-press #(do {:icon [chat-icon.screen/chat-icon-view-chat-list
(re-frame/dispatch [:chat.ui/navigate-to-chat chat-id]) contact group-chat truncated-chat-name color online false]
(re-frame/dispatch [:chat.ui/mark-messages-seen :chat])) :title-prefix (cond
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet chat-actions {:chat-id chat-id}])} private-group? :main-icons/tiny-group
[react/view styles/chat-container public-group? :main-icons/tiny-public
[react/view styles/chat-icon-container :else nil)
[chat-icon.screen/chat-icon-view-chat-list contact group-chat truncated-chat-name color online false]] :title truncated-chat-name
[react/view styles/chat-info-container :title-accessibility-label :chat-name-text
[react/view styles/item-upper-container :title-row-accessory [message-timestamp chat-id]
[chat-list-item-name truncated-chat-name group-chat public? public-key] :subtitle
[react/view styles/message-status-container (let [{:keys [tribute-status tribute-label]} (:tribute-to-talk contact)]
[message-timestamp (if (pos? last-message-timestamp) last-message-timestamp timestamp)]]] (if (not (#{:require :pending} tribute-status))
[react/view styles/item-lower-container [message-content-text chat-id]
(let [{:keys [tribute-status tribute-label]} (:tribute-to-talk contact)] tribute-label))
(if (not (#{:require :pending} tribute-status)) :subtitle-row-accessory [unviewed-indicator chat-id]
[message-content-text {:content last-message-content :on-press #(do
:content-type last-message-content-type}] (re-frame/dispatch [:chat.ui/navigate-to-chat chat-id])
[react/text {:style styles/last-message-text} tribute-label])) (re-frame/dispatch [:chat.ui/mark-messages-seen :chat]))
[unviewed-indicator chat-id]]]]])) :on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet chat-actions {:chat-id chat-id}])}]))

View File

@ -23,6 +23,7 @@
[status-im.ui.screens.profile.components.views :as profile.components] [status-im.ui.screens.profile.components.views :as profile.components]
[status-im.ui.screens.profile.user.styles :as styles] [status-im.ui.screens.profile.user.styles :as styles]
[status-im.utils.identicon :as identicon] [status-im.utils.identicon :as identicon]
[status-im.utils.platform :as platform]
[status-im.utils.universal-links.core :as universal-links])) [status-im.utils.universal-links.core :as universal-links]))
(views/defview share-chat-key [] (views/defview share-chat-key []
@ -198,8 +199,11 @@
content (flat-list-content content (flat-list-content
preferred-name registrar tribute-to-talk preferred-name registrar tribute-to-talk
active-contacts-count show-backup-seed?)] active-contacts-count show-backup-seed?)]
[react/safe-area-view {:style {:flex 1 [react/safe-area-view
:margin-bottom tabs.styles/tabs-diff}} {:style
(merge {:flex 1}
(when platform/ios?
{:margin-bottom tabs.styles/tabs-diff}))}
[status-bar/status-bar {:type :main}] [status-bar/status-bar {:type :main}]
[large-toolbar/minimized-toolbar [large-toolbar/minimized-toolbar
(header-in-toolbar multiaccount) (header-in-toolbar multiaccount)