feature #3009 - restyled chat screen
Signed-off-by: Julien Eluard <julien.eluard@gmail.com>
This commit is contained in:
parent
c3449a3a65
commit
86df18d764
|
@ -294,6 +294,7 @@
|
||||||
(fn [cofx [chat]]
|
(fn [cofx [chat]]
|
||||||
(models/update-chat cofx chat)))
|
(models/update-chat cofx chat)))
|
||||||
|
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:remove-chat
|
:remove-chat
|
||||||
[re-frame/trim-v]
|
[re-frame/trim-v]
|
||||||
|
@ -325,3 +326,24 @@
|
||||||
:content (i18n/label (if group? :t/delete-group-chat-confirmation :t/delete-chat-confirmation))
|
:content (i18n/label (if group? :t/delete-group-chat-confirmation :t/delete-chat-confirmation))
|
||||||
:confirm-button-text (i18n/label :t/delete)
|
:confirm-button-text (i18n/label :t/delete)
|
||||||
:on-accept #(re-frame/dispatch [:delete-chat chat-id])}}))
|
:on-accept #(re-frame/dispatch [:delete-chat chat-id])}}))
|
||||||
|
|
||||||
|
(defn remove-chats [db chat-id]
|
||||||
|
(let [chat (get-in db [:chats chat-id])]
|
||||||
|
{:db (-> db
|
||||||
|
(update :chats dissoc chat-id)
|
||||||
|
(update :deleted-chats (fnil conj #{}) chat-id))
|
||||||
|
:delete-chat chat
|
||||||
|
:delete-chat-messages chat}))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:remove-chat
|
||||||
|
[re-frame/trim-v]
|
||||||
|
(fn [{:keys [db]} [chat-id]]
|
||||||
|
(remove-chats db chat-id)))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:remove-chat-and-navigate-home
|
||||||
|
[re-frame/trim-v]
|
||||||
|
(fn [{:keys [db]} [chat-id]]
|
||||||
|
(merge (remove-chats db chat-id)
|
||||||
|
{:dispatch [:navigation-replace :home]})))
|
|
@ -4,6 +4,11 @@
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.chat.styles.screen :as style]
|
[status-im.chat.styles.screen :as style]
|
||||||
|
[status-im.utils.platform :as platform]
|
||||||
|
[status-im.chat.views.toolbar-content :as toolbar-content]
|
||||||
|
[status-im.chat.views.message.message :as message]
|
||||||
|
[status-im.chat.views.message.datemark :as message-datemark]
|
||||||
|
[status-im.chat.views.input.input :as input]
|
||||||
[status-im.chat.views.actions :as actions]
|
[status-im.chat.views.actions :as actions]
|
||||||
[status-im.chat.views.bottom-info :as bottom-info]
|
[status-im.chat.views.bottom-info :as bottom-info]
|
||||||
[status-im.chat.views.message.datemark :as message-datemark]
|
[status-im.chat.views.message.datemark :as message-datemark]
|
||||||
|
@ -17,7 +22,17 @@
|
||||||
[status-im.ui.components.status-bar.view :as status-bar]
|
[status-im.ui.components.status-bar.view :as status-bar]
|
||||||
[status-im.ui.components.connectivity.view :as connectivity]
|
[status-im.ui.components.connectivity.view :as connectivity]
|
||||||
[status-im.ui.components.toolbar.view :as toolbar]
|
[status-im.ui.components.toolbar.view :as toolbar]
|
||||||
[status-im.utils.platform :as platform]))
|
[status-im.ui.components.animation :as animation]
|
||||||
|
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||||
|
[status-im.ui.components.colors :as colors]))
|
||||||
|
|
||||||
|
(defn toolbar-action [chat-id chat-name group-chat public?]
|
||||||
|
[react/touchable-highlight
|
||||||
|
{:on-press #(list-selection/show {:title chat-name
|
||||||
|
:options (actions/actions chat-id group-chat public?)})
|
||||||
|
:accessibility-label :chat-menu}
|
||||||
|
[react/view style/action
|
||||||
|
[vector-icons/icon :icons/dots-horizontal]]])
|
||||||
|
|
||||||
(defview add-contact-bar []
|
(defview add-contact-bar []
|
||||||
(letsubs [chat-id [:get-current-chat-id]
|
(letsubs [chat-id [:get-current-chat-id]
|
||||||
|
@ -38,7 +53,7 @@
|
||||||
{:keys [group-chat name chat-id]} [:get-current-chat]]
|
{:keys [group-chat name chat-id]} [:get-current-chat]]
|
||||||
[react/view
|
[react/view
|
||||||
[status-bar/status-bar]
|
[status-bar/status-bar]
|
||||||
[toolbar/toolbar {}
|
[toolbar/platform-agnostic-toolbar {}
|
||||||
toolbar/default-nav-back
|
toolbar/default-nav-back
|
||||||
[toolbar-content/toolbar-content-view]
|
[toolbar-content/toolbar-content-view]
|
||||||
[toolbar/actions [{:icon :icons/options
|
[toolbar/actions [{:icon :icons/options
|
||||||
|
@ -78,16 +93,20 @@
|
||||||
(defview messages-view [group-chat]
|
(defview messages-view [group-chat]
|
||||||
(letsubs [messages [:get-current-chat-messages]
|
(letsubs [messages [:get-current-chat-messages]
|
||||||
current-public-key [:get-current-public-key]]
|
current-public-key [:get-current-public-key]]
|
||||||
[list/flat-list {:data messages
|
(if (empty? messages)
|
||||||
:render-fn (fn [{:keys [message-id] :as message}]
|
[react/view style/empty-chat-container
|
||||||
^{:key message-id}
|
[react/text {:style style/empty-chat-text}
|
||||||
[message-row {:group-chat group-chat
|
(i18n/label :t/empty-chat-description)]]
|
||||||
:current-public-key current-public-key
|
[list/flat-list {:data messages
|
||||||
:row message}])
|
:render-fn (fn [{:keys [message-id] :as message}]
|
||||||
:inverted true
|
^{:key message-id}
|
||||||
:onEndReached #(re-frame/dispatch [:load-more-messages])
|
[message-row {:group-chat group-chat
|
||||||
:enableEmptySections true
|
:current-public-key current-public-key
|
||||||
:keyboardShouldPersistTaps (if platform/android? :always :handled)}]))
|
:row message}])
|
||||||
|
:inverted true
|
||||||
|
:onEndReached #(re-frame/dispatch [:load-more-messages])
|
||||||
|
:enableEmptySections true
|
||||||
|
:keyboardShouldPersistTaps (if platform/android? :always :handled)}])))
|
||||||
|
|
||||||
(defview chat []
|
(defview chat []
|
||||||
(letsubs [{:keys [group-chat public? input-text]} [:get-current-chat]
|
(letsubs [{:keys [group-chat public? input-text]} [:get-current-chat]
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
(ns status-im.chat.styles.message.message
|
(ns status-im.chat.styles.message.message
|
||||||
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
|
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
|
||||||
(:require [status-im.ui.components.styles :as styles]
|
(:require [status-im.ui.components.styles :as styles]
|
||||||
|
[status-im.ui.components.colors :as colors]
|
||||||
[status-im.constants :as constants]))
|
[status-im.constants :as constants]))
|
||||||
|
|
||||||
|
(def photo-size 36)
|
||||||
|
|
||||||
(defstyle style-message-text
|
(defstyle style-message-text
|
||||||
{:font-size 15
|
{:font-size 15
|
||||||
:color styles/text1-color
|
:color styles/text1-color
|
||||||
|
@ -24,15 +27,6 @@
|
||||||
same-direction? 16
|
same-direction? 16
|
||||||
:else 24))
|
:else 24))
|
||||||
|
|
||||||
(defn last-message-padding
|
|
||||||
[{:keys [last? typing]}]
|
|
||||||
(when (and last? (not typing))
|
|
||||||
{:padding-bottom 16}))
|
|
||||||
|
|
||||||
(def message-datemark
|
|
||||||
{:margin-top 10
|
|
||||||
:height 34})
|
|
||||||
|
|
||||||
(def message-empty-spacing
|
(def message-empty-spacing
|
||||||
{:height 16})
|
{:height 16})
|
||||||
|
|
||||||
|
@ -40,6 +34,11 @@
|
||||||
{:padding-right 10
|
{:padding-right 10
|
||||||
:padding-left 10})
|
:padding-left 10})
|
||||||
|
|
||||||
|
(defn last-message-padding
|
||||||
|
[{:keys [last? typing]}]
|
||||||
|
(when (and last? (not typing))
|
||||||
|
{:padding-bottom 16}))
|
||||||
|
|
||||||
(defn message-body
|
(defn message-body
|
||||||
[{:keys [outgoing] :as message}]
|
[{:keys [outgoing] :as message}]
|
||||||
(let [align (if outgoing :flex-end :flex-start)
|
(let [align (if outgoing :flex-end :flex-start)
|
||||||
|
@ -49,8 +48,7 @@
|
||||||
:width 260
|
:width 260
|
||||||
:padding-top (message-padding-top message)
|
:padding-top (message-padding-top message)
|
||||||
:align-self align
|
:align-self align
|
||||||
:align-items align}
|
:align-items align})))
|
||||||
(last-message-padding message))))
|
|
||||||
|
|
||||||
(def selected-message
|
(def selected-message
|
||||||
{:margin-top 18
|
{:margin-top 18
|
||||||
|
@ -58,11 +56,12 @@
|
||||||
:font-size 12
|
:font-size 12
|
||||||
:color styles/text2-color})
|
:color styles/text2-color})
|
||||||
|
|
||||||
(def group-message-wrapper
|
(defn group-message-wrapper [message]
|
||||||
{:flex-direction :column})
|
(merge {:flex-direction :column}
|
||||||
|
(last-message-padding message)))
|
||||||
|
|
||||||
(defn group-message-view
|
(defn group-message-view
|
||||||
[{:keys [outgoing] :as message}]
|
[outgoing]
|
||||||
(let [align (if outgoing :flex-end :flex-start)]
|
(let [align (if outgoing :flex-end :flex-start)]
|
||||||
{:flex-direction :column
|
{:flex-direction :column
|
||||||
:width 260
|
:width 260
|
||||||
|
@ -70,14 +69,18 @@
|
||||||
:padding-right 10
|
:padding-right 10
|
||||||
:align-items align}))
|
:align-items align}))
|
||||||
|
|
||||||
|
(def delivery-status
|
||||||
|
{:align-self :flex-end
|
||||||
|
:padding-right 56})
|
||||||
|
|
||||||
(def message-author
|
(def message-author
|
||||||
{:width 36
|
{:width photo-size
|
||||||
:align-self :flex-start})
|
:align-self :flex-start})
|
||||||
|
|
||||||
(def photo
|
(def photo
|
||||||
{:border-radius 18
|
{:border-radius (/ photo-size 2)
|
||||||
:width 36
|
:width photo-size
|
||||||
:height 36})
|
:height photo-size})
|
||||||
|
|
||||||
(def delivery-view
|
(def delivery-view
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
|
@ -255,3 +258,10 @@
|
||||||
{:background-color styles/color-white
|
{:background-color styles/color-white
|
||||||
:margin-bottom margin
|
:margin-bottom margin
|
||||||
:elevation (if on-top? 6 5)})
|
:elevation (if on-top? 6 5)})
|
||||||
|
|
||||||
|
(def message-author-name
|
||||||
|
{:font-size 12
|
||||||
|
:letter-spacing -0.2
|
||||||
|
:padding-bottom 4
|
||||||
|
:color colors/gray})
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im.chat.styles.screen
|
(ns status-im.chat.styles.screen
|
||||||
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
|
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
|
||||||
(:require [status-im.ui.components.styles :as component.styles]))
|
(:require [status-im.ui.components.styles :as component.styles]
|
||||||
|
[status-im.ui.components.colors :as colors]))
|
||||||
|
|
||||||
(def chat-view
|
(def chat-view
|
||||||
{:flex 1
|
{:flex 1
|
||||||
|
@ -37,6 +38,10 @@
|
||||||
:width 8
|
:width 8
|
||||||
:height 14})
|
:height 14})
|
||||||
|
|
||||||
|
(def chat-toolbar-contents
|
||||||
|
{:flex-direction :row
|
||||||
|
:flex 1})
|
||||||
|
|
||||||
(defnstyle chat-name-view [show-actions]
|
(defnstyle chat-name-view [show-actions]
|
||||||
{:flex 1
|
{:flex 1
|
||||||
:justify-content :center
|
:justify-content :center
|
||||||
|
@ -200,3 +205,17 @@
|
||||||
(defn message-view-animated [opacity]
|
(defn message-view-animated [opacity]
|
||||||
{:opacity opacity
|
{:opacity opacity
|
||||||
:flex 1})
|
:flex 1})
|
||||||
|
|
||||||
|
(def empty-chat-container
|
||||||
|
{:flex 1
|
||||||
|
:flex-direction :row
|
||||||
|
:justify-content :center
|
||||||
|
:align-items :center
|
||||||
|
:padding-vertical 50
|
||||||
|
:margin-right 6})
|
||||||
|
|
||||||
|
(def empty-chat-text
|
||||||
|
{:color colors/gray
|
||||||
|
:font-size 14
|
||||||
|
:line-height 20
|
||||||
|
:letter-spacing -0.2})
|
|
@ -130,23 +130,25 @@
|
||||||
(->> message-datemark-groups
|
(->> message-datemark-groups
|
||||||
(mapcat (fn [[datemark messages]]
|
(mapcat (fn [[datemark messages]]
|
||||||
(let [prepared-messages (into []
|
(let [prepared-messages (into []
|
||||||
(map (fn [{:keys [message-id] :as message} previous-message]
|
(map (fn [previous-message
|
||||||
|
{:keys [message-id] :as message}
|
||||||
|
next-message]
|
||||||
(assoc message
|
(assoc message
|
||||||
:same-author? (= (:from message)
|
:same-author? (= (:from message)
|
||||||
(:from previous-message))
|
(:from previous-message))
|
||||||
:same-direction? (= (:outgoing message)
|
:same-direction? (= (:outgoing message)
|
||||||
(:outgoing previous-message))
|
(:outgoing previous-message))
|
||||||
:last? (= message-id
|
:last-by-same-author? (not= (:from message)
|
||||||
last-message-id)
|
(:from next-message))
|
||||||
:last-outgoing? (= message-id
|
:last? (= message-id
|
||||||
last-outgoing-message-id)))
|
last-message-id)
|
||||||
|
:last-outgoing? (= message-id
|
||||||
|
last-outgoing-message-id)))
|
||||||
|
(concat (rest messages) '(nil))
|
||||||
messages
|
messages
|
||||||
(concat (rest messages) '(nil))))]
|
(concat '(nil) (butlast messages))))]
|
||||||
(conj prepared-messages {:type :datemark
|
(conj prepared-messages {:type :datemark
|
||||||
:value datemark}))))))
|
:value datemark}))))))))
|
||||||
;; when no messages are in chat, we need to at least fake-out today's datemark
|
|
||||||
(list {:type :datemark
|
|
||||||
:value (i18n/label :t/datetime-today)})))
|
|
||||||
|
|
||||||
(reg-sub
|
(reg-sub
|
||||||
:get-current-chat-messages
|
:get-current-chat-messages
|
||||||
|
|
|
@ -24,14 +24,6 @@
|
||||||
|
|
||||||
(def window-width (:width (react/get-dimensions "window")))
|
(def window-width (:width (react/get-dimensions "window")))
|
||||||
|
|
||||||
(defview message-author-name [{:keys [outgoing from username] :as message}]
|
|
||||||
(letsubs [current-account [:get-current-account]
|
|
||||||
incoming-name [:contact-name-by-identity from]]
|
|
||||||
(when-let [name (if outgoing
|
|
||||||
(:name current-account)
|
|
||||||
(or incoming-name username (gfycat/generate-gfy from)))]
|
|
||||||
[react/text {:style style/author} name])))
|
|
||||||
|
|
||||||
(defview message-content-status []
|
(defview message-content-status []
|
||||||
(letsubs [{:keys [chat-id group-id name color public-key]} [:get-current-chat]
|
(letsubs [{:keys [chat-id group-id name color public-key]} [:get-current-chat]
|
||||||
members [:current-chat-contacts]]
|
members [:current-chat-contacts]]
|
||||||
|
@ -89,7 +81,6 @@
|
||||||
(defn message-view
|
(defn message-view
|
||||||
[{:keys [group-chat] :as message} content]
|
[{:keys [group-chat] :as message} content]
|
||||||
[react/view (style/message-view message)
|
[react/view (style/message-view message)
|
||||||
(when group-chat [message-author-name message])
|
|
||||||
content])
|
content])
|
||||||
|
|
||||||
(def replacements
|
(def replacements
|
||||||
|
@ -266,24 +257,31 @@
|
||||||
(letsubs [{:keys [photo-path]} [:get-current-account]]
|
(letsubs [{:keys [photo-path]} [:get-current-account]]
|
||||||
(photo from photo-path)))
|
(photo from photo-path)))
|
||||||
|
|
||||||
|
(defview message-author-name [from]
|
||||||
|
(letsubs [username [:contact-name-by-identity from]]
|
||||||
|
[react/text {:style style/message-author-name} username]))
|
||||||
|
|
||||||
(defn message-body
|
(defn message-body
|
||||||
[{:keys [last-outgoing? message-type same-author? from outgoing group-chat] :as message} content]
|
[{:keys [last-outgoing? last-by-same-author? message-type same-author? from outgoing group-chat] :as message} content]
|
||||||
[react/view style/group-message-wrapper
|
[react/view (style/group-message-wrapper message)
|
||||||
[react/view (style/message-body message)
|
[react/view (style/message-body message)
|
||||||
[react/view style/message-author
|
[react/view style/message-author
|
||||||
(when-not same-author?
|
(when last-by-same-author?
|
||||||
(if outgoing
|
(if outgoing
|
||||||
[my-photo from]
|
[my-photo from]
|
||||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:show-profile from])}
|
[react/touchable-highlight {:on-press #(re-frame/dispatch [:show-profile from])}
|
||||||
[react/view
|
[react/view
|
||||||
[member-photo from]]]))]
|
[member-photo from]]]))]
|
||||||
[react/view (style/group-message-view message)
|
[react/view (style/group-message-view outgoing)
|
||||||
content
|
(when-not same-author?
|
||||||
(when last-outgoing?
|
[message-author-name from])
|
||||||
(if (or (= (keyword message-type) :group-user-message)
|
content]]
|
||||||
group-chat)
|
(when last-outgoing?
|
||||||
[group-message-delivery-status message]
|
[react/view style/delivery-status
|
||||||
[message-delivery-status message]))]]])
|
(if (or (= (keyword message-type) :group-user-message)
|
||||||
|
group-chat)
|
||||||
|
[group-message-delivery-status message]
|
||||||
|
[message-delivery-status message])])])
|
||||||
|
|
||||||
(defn message-container-animation-logic [{:keys [to-value val callback]}]
|
(defn message-container-animation-logic [{:keys [to-value val callback]}]
|
||||||
(fn [_]
|
(fn [_]
|
||||||
|
|
|
@ -191,6 +191,7 @@
|
||||||
:topic-format "Wrong format [a-z0-9\\-]+"
|
:topic-format "Wrong format [a-z0-9\\-]+"
|
||||||
:public-group-topic "Topic"
|
:public-group-topic "Topic"
|
||||||
:set-a-topic "Set a topic"
|
:set-a-topic "Set a topic"
|
||||||
|
:empty-chat-description "There are no messages \nin this chat yet"
|
||||||
|
|
||||||
;;discover
|
;;discover
|
||||||
:discover "Discover"
|
:discover "Discover"
|
||||||
|
|
|
@ -123,6 +123,19 @@
|
||||||
[react/view components.styles/flex]
|
[react/view components.styles/flex]
|
||||||
action-items]))
|
action-items]))
|
||||||
|
|
||||||
|
(defn platform-agnostic-toolbar
|
||||||
|
([props nav-item content-item] (platform-agnostic-toolbar props nav-item content-item [actions [{:image :blank}]]))
|
||||||
|
([{:keys [background-color style flat?]}
|
||||||
|
nav-item
|
||||||
|
content-item
|
||||||
|
action-items]
|
||||||
|
[react/view {:style (merge (styles/toolbar background-color flat?) style)}
|
||||||
|
(when nav-item
|
||||||
|
[react/view {:style (styles/toolbar-nav-actions-container 0)}
|
||||||
|
nav-item])
|
||||||
|
content-item
|
||||||
|
action-items]))
|
||||||
|
|
||||||
(defn simple-toolbar
|
(defn simple-toolbar
|
||||||
"A simple toolbar composed of a nav-back item and a single line title."
|
"A simple toolbar composed of a nav-back item and a single line title."
|
||||||
([] (simple-toolbar nil))
|
([] (simple-toolbar nil))
|
||||||
|
|
|
@ -114,8 +114,12 @@
|
||||||
|
|
||||||
(reg-sub :contact-name-by-identity
|
(reg-sub :contact-name-by-identity
|
||||||
:<- [:get-contacts]
|
:<- [:get-contacts]
|
||||||
(fn [contacts [_ identity]]
|
:<- [:get-current-account]
|
||||||
(:name (contacts identity))))
|
(fn [[contacts current-account] [_ identity]]
|
||||||
|
(let [me? (= (:public-key current-account) identity)]
|
||||||
|
(if me?
|
||||||
|
(:name current-account)
|
||||||
|
(:name (contacts identity))))))
|
||||||
|
|
||||||
(defn chat-contacts [[chat contacts] [_ fn]]
|
(defn chat-contacts [[chat contacts] [_ fn]]
|
||||||
(when chat
|
(when chat
|
||||||
|
|
Loading…
Reference in New Issue