Merge pull request #323 from status-im/bug/#282
Date indicators in chat (#282)
Former-commit-id: 03c4295dd7
This commit is contained in:
commit
474d4faf25
|
@ -4,6 +4,7 @@
|
|||
[status-im.data-store.messages :as messages]
|
||||
[status-im.chat.utils :as cu]
|
||||
[status-im.commands.utils :refer [generate-hiccup]]
|
||||
[status-im.utils.random :as random]
|
||||
[status-im.constants :refer [content-type-command-request]]
|
||||
[cljs.reader :refer [read-string]]
|
||||
[status-im.data-store.chats :as chats]))
|
||||
|
@ -24,7 +25,7 @@
|
|||
(:public-key (accounts current-account-id)))
|
||||
|
||||
(defn receive-message
|
||||
[db [_ {:keys [from group-id chat-id message-id] :as message}]]
|
||||
[db [_ {:keys [from group-id chat-id message-id timestamp] :as message}]]
|
||||
(let [same-message (messages/get-by-id message-id)
|
||||
current-identity (get-current-identity db)
|
||||
chat-id' (or group-id chat-id from)
|
||||
|
@ -39,7 +40,7 @@
|
|||
(cu/check-author-direction previous-message)
|
||||
(check-preview))
|
||||
:chat-id chat-id'
|
||||
:timestamp (.getTime (js/Date.)))]
|
||||
:timestamp (or timestamp (random/timestamp)))]
|
||||
(store-message message')
|
||||
(when-not exists?
|
||||
(dispatch [:add-chat chat-id' (when group-chat? {:group-chat true})]))
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
{:message-id (random/id)
|
||||
:from identity
|
||||
:to chat-id
|
||||
:timestamp (time/now-ms)
|
||||
:content (assoc content :preview preview-string)
|
||||
:content-type content-type-command
|
||||
:outgoing true
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
[status-im.components.invertible-scroll-view :refer [invertible-scroll-view]]
|
||||
[status-im.components.toolbar.view :refer [toolbar]]
|
||||
[status-im.chat.views.message :refer [chat-message]]
|
||||
[status-im.chat.views.datemark :refer [chat-datemark]]
|
||||
[status-im.chat.views.suggestions :refer [suggestion-container]]
|
||||
[status-im.chat.views.response :refer [response-view]]
|
||||
[status-im.chat.views.new-message :refer [chat-message-new]]
|
||||
|
@ -26,7 +27,8 @@
|
|||
[status-im.chat.views.bottom-info :refer [bottom-info-view]]
|
||||
[status-im.i18n :refer [label label-pluralize]]
|
||||
[status-im.components.animation :as anim]
|
||||
[status-im.constants :refer [console-chat-id]]
|
||||
[status-im.constants :refer [console-chat-id
|
||||
content-type-status]]
|
||||
[reagent.core :as r]
|
||||
[clojure.string :as str]
|
||||
[cljs-time.core :as t]))
|
||||
|
@ -66,13 +68,19 @@
|
|||
(for [member ["Geoff" "Justas"]]
|
||||
^{:key member} [typing member])])
|
||||
|
||||
(defn message-row [{:keys [contact-by-identity group-chat messages-count]}]
|
||||
(fn [row _ idx]
|
||||
(defmulti message-row (fn [{{:keys [type]} :row}] type))
|
||||
|
||||
(defmethod message-row :datemark
|
||||
[{{:keys [value]} :row}]
|
||||
(list-item [chat-datemark value]))
|
||||
|
||||
(defmethod message-row :default
|
||||
[{:keys [contact-by-identity group-chat messages-count row index]}]
|
||||
(let [message (-> row
|
||||
(add-message-color contact-by-identity)
|
||||
(assoc :group-chat group-chat)
|
||||
(assoc :last-message (= (js/parseInt idx) (dec messages-count))))]
|
||||
(list-item [chat-message message]))))
|
||||
(assoc :last-message (= (js/parseInt index) (dec messages-count))))]
|
||||
(list-item [chat-message message])))
|
||||
|
||||
(defn online-text [contact chat-id]
|
||||
(cond
|
||||
|
@ -134,14 +142,31 @@
|
|||
:custom-action [toolbar-action]
|
||||
:style (get-in platform-specific [:component-styles :toolbar])}]])
|
||||
|
||||
(defn messages-with-timemarks [all-messages]
|
||||
(let [messages (->> all-messages
|
||||
(map #(assoc % :datemark (time/day-relative (:timestamp %))))
|
||||
(group-by :datemark)
|
||||
(map (fn [[k v]] [v {:type :datemark :value k}]))
|
||||
(flatten))
|
||||
remove-last? (some (fn [{:keys [content-type]}]
|
||||
(= content-type content-type-status))
|
||||
messages)]
|
||||
(if remove-last?
|
||||
(drop-last messages)
|
||||
messages)))
|
||||
|
||||
(defview messages-view [group-chat]
|
||||
[messages [:chat :messages]
|
||||
contacts [:chat :contacts]
|
||||
loaded? [:all-messages-loaded?]]
|
||||
(let [contacts' (contacts-by-identity contacts)]
|
||||
[list-view {:renderRow (message-row {:contact-by-identity contacts'
|
||||
(let [contacts' (contacts-by-identity contacts)
|
||||
messages (messages-with-timemarks messages)]
|
||||
[list-view {:renderRow (fn [row _ index]
|
||||
(message-row {:contact-by-identity contacts'
|
||||
:group-chat group-chat
|
||||
:messages-count (count messages)})
|
||||
:messages-count (count messages)
|
||||
:row row
|
||||
:index index}))
|
||||
:renderScrollComponent #(invertible-scroll-view (js->clj %))
|
||||
:onEndReached (when-not loaded? #(dispatch [:load-more-messages]))
|
||||
:enableEmptySections true
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
(ns status-im.chat.styles.datemark)
|
||||
|
||||
(def datemark-wrapper
|
||||
{:flex 1
|
||||
:flex-direction :column
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(def datemark
|
||||
{:flex 1
|
||||
:flex-direction :column
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:background-color "#bbc4cb33"
|
||||
:padding-left 12
|
||||
:padding-right 12
|
||||
:margin-top 8
|
||||
:margin-bottom 8
|
||||
:border-radius 12
|
||||
:height 24})
|
||||
|
||||
(def datemark-text
|
||||
{:color "#838c93"
|
||||
:font-size 12})
|
|
@ -36,9 +36,13 @@
|
|||
(when (and last-message (not typing))
|
||||
{:paddingBottom 20}))
|
||||
|
||||
(def message-datemark
|
||||
{:margin-top 10
|
||||
:margin-bottom -4})
|
||||
|
||||
(def message-body-base
|
||||
{:paddingRight 8
|
||||
:paddingLeft 8})
|
||||
{:padding-right 8
|
||||
:padding-left 8})
|
||||
|
||||
(defn message-body
|
||||
[{:keys [outgoing] :as message}]
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
[status-im.constants :refer [response-suggesstion-resize-duration]]
|
||||
[status-im.chat.constants :as c]
|
||||
[status-im.chat.views.plain-message :as plain-message]
|
||||
[status-im.chat.views.command :as command]))
|
||||
[status-im.chat.views.command :as command]
|
||||
[status-im.constants :refer [content-type-status]]
|
||||
[status-im.utils.datetime :as time]))
|
||||
|
||||
(register-sub :chat-properties
|
||||
(fn [db [_ properties]]
|
||||
|
@ -29,7 +31,6 @@
|
|||
(get-in [:chats (:current-chat-id @db) k])
|
||||
(reaction))))
|
||||
|
||||
|
||||
(register-sub :get-chat-messages
|
||||
(fn [db _]
|
||||
(let [chat-id (:current-chat-id @db)]
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
(ns status-im.chat.views.datemark
|
||||
(:require [re-frame.core :refer [subscribe dispatch]]
|
||||
[status-im.components.react :refer [view
|
||||
text]]
|
||||
[clojure.string :as str]
|
||||
[status-im.i18n :refer [label]]
|
||||
[status-im.chat.styles.datemark :as st]))
|
||||
|
||||
(defn chat-datemark [value]
|
||||
[view st/datemark-wrapper
|
||||
[view st/datemark
|
||||
[text {:style st/datemark-text}
|
||||
(str/capitalize (or value (label :t/datetime-today)))]]])
|
|
@ -13,6 +13,7 @@
|
|||
[status-im.chat.views.request-message :refer [message-content-command-request]]
|
||||
[status-im.chat.styles.message :as st]
|
||||
[status-im.chat.styles.command-pill :as pill-st]
|
||||
[status-im.chat.views.datemark :refer [chat-datemark]]
|
||||
[status-im.models.commands :refer [parse-command-message-content
|
||||
parse-command-request]]
|
||||
[status-im.resources :as res]
|
||||
|
@ -24,13 +25,6 @@
|
|||
[status-im.utils.identicon :refer [identicon]]
|
||||
[status-im.chat.utils :as cu]))
|
||||
|
||||
(defn message-date [timestamp]
|
||||
[view {}
|
||||
[view st/message-date-container
|
||||
[text {:style st/message-date-text
|
||||
:font :default}
|
||||
(time/to-short-str timestamp)]]])
|
||||
|
||||
(defn contact-photo [photo-path]
|
||||
[view st/contact-photo-container
|
||||
[image {:source (if (s/blank? photo-path)
|
||||
|
@ -45,7 +39,7 @@
|
|||
[view st/online-dot-right]]))
|
||||
|
||||
(defview message-content-status
|
||||
[{:keys [from content]}]
|
||||
[{:keys [from content datemark]}]
|
||||
[{chat-name :name} [:get-chat-by-id from]
|
||||
photo-path [:chat-photo from]]
|
||||
[view st/status-container
|
||||
|
@ -57,7 +51,9 @@
|
|||
(or chat-name from)]
|
||||
[text {:style st/status-text
|
||||
:font :default}
|
||||
content]])
|
||||
content]
|
||||
[view st/message-datemark
|
||||
[chat-datemark datemark]]])
|
||||
|
||||
(defn message-content-audio [_]
|
||||
[view st/audio-container
|
||||
|
@ -295,11 +291,8 @@
|
|||
:from from
|
||||
:message-id message-id}])))
|
||||
:reagent-render
|
||||
(fn [{:keys [outgoing timestamp new-day group-chat] :as message}]
|
||||
(fn [{:keys [outgoing group-chat] :as message}]
|
||||
[message-container message
|
||||
;; TODO there is no new-day info in message
|
||||
(when new-day
|
||||
[message-date timestamp])
|
||||
[view
|
||||
(let [incoming-group (and group-chat (not outgoing))]
|
||||
[message-content
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
:datetime-multiple "s"
|
||||
:datetime-ago "ago"
|
||||
:datetime-yesterday "yesterday"
|
||||
:datetime-today "today"
|
||||
|
||||
;profile
|
||||
:profile "Profile"
|
||||
|
|
|
@ -18,7 +18,10 @@
|
|||
|
||||
(def time-zone-offset (hours (- (/ (.getTimezoneOffset (js/Date.)) 60))))
|
||||
|
||||
(defn to-short-str [ms]
|
||||
(defn to-short-str
|
||||
([ms]
|
||||
(to-short-str ms #(unparse (formatters :hour-minute) %)))
|
||||
([ms today-format-fn]
|
||||
(let [date (from-long ms)
|
||||
local (plus date time-zone-offset)
|
||||
today-date (t/today)
|
||||
|
@ -29,7 +32,11 @@
|
|||
(cond
|
||||
(before? local yesterday) (unparse (formatter "dd MMM") local)
|
||||
(before? local today) (label :t/datetime-yesterday)
|
||||
:else (unparse (formatters :hour-minute) local))))
|
||||
:else (today-format-fn local)))))
|
||||
|
||||
(defn day-relative [ms]
|
||||
(when (> ms 0)
|
||||
(to-short-str ms #(label :t/datetime-today))))
|
||||
|
||||
(defn format-time-ago [diff unit]
|
||||
(let [name (label-pluralize diff (:name unit))]
|
||||
|
|
Loading…
Reference in New Issue