date indicators in chat (fixes #282)

This commit is contained in:
Alexander Pantyuhov 2016-10-04 23:58:33 +03:00
parent d5de7f4af6
commit dcd711f5c2
10 changed files with 113 additions and 43 deletions

View File

@ -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})]))

View File

@ -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

View File

@ -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]
(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]))))
(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 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'
:group-chat group-chat
:messages-count (count messages)})
(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)
:row row
:index index}))
:renderScrollComponent #(invertible-scroll-view (js->clj %))
:onEndReached (when-not loaded? #(dispatch [:load-more-messages]))
:enableEmptySections true

View File

@ -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})

View File

@ -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}]

View File

@ -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)]

View File

@ -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)))]]])

View File

@ -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

View File

@ -49,6 +49,7 @@
:datetime-multiple "s"
:datetime-ago "ago"
:datetime-yesterday "yesterday"
:datetime-today "today"
;profile
:profile "Profile"

View File

@ -18,18 +18,25 @@
(def time-zone-offset (hours (- (/ (.getTimezoneOffset (js/Date.)) 60))))
(defn to-short-str [ms]
(let [date (from-long ms)
local (plus date time-zone-offset)
today-date (t/today)
today (date-time (t/year today-date)
(t/month today-date)
(t/day today-date))
yesterday (plus today (days -1))]
(cond
(before? local yesterday) (unparse (formatter "dd MMM") local)
(before? local today) (label :t/datetime-yesterday)
:else (unparse (formatters :hour-minute) local))))
(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)
today (date-time (t/year today-date)
(t/month today-date)
(t/day today-date))
yesterday (plus today (days -1))]
(cond
(before? local yesterday) (unparse (formatter "dd MMM") local)
(before? local today) (label :t/datetime-yesterday)
: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))]