ISSUE #3083] Adapted chat menu to latest mockups

Signed-off-by: Julien Eluard <julien.eluard@gmail.com>
This commit is contained in:
Julien Eluard 2018-02-13 15:41:45 +01:00
parent b228883de5
commit 058e6c5412
No known key found for this signature in database
GPG Key ID: 6FD7DB5437FCBEF6
8 changed files with 78 additions and 224 deletions

View File

@ -2,9 +2,7 @@
(:require [clojure.set :as set]
[cljs.core.async :as async]
[re-frame.core :as re-frame]
[taoensso.timbre :as log]
[status-im.utils.handlers :as handlers]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.async :as async-utils]
[status-im.chat.models :as model]
[status-im.chat.console :as console-chat]
@ -13,14 +11,12 @@
[status-im.data-store.contacts :as contacts-store]
[status-im.data-store.chats :as chats-store]
[status-im.data-store.contacts :as contacts-store]
[status-im.data-store.requests :as requests-store]
[status-im.data-store.messages :as messages-store]
[status-im.data-store.pending-messages :as pending-messages-store]
[status-im.ui.screens.navigation :as navigation]
[status-im.protocol.core :as protocol]
[status-im.constants :as const]
[status-im.ui.components.list-selection :as list-selection]
[status-im.chat.events.input :as input-events]
status-im.chat.events.commands
status-im.chat.events.requests
status-im.chat.events.animation
@ -119,12 +115,6 @@
;;;; Handlers
(handlers/register-handler-db
:set-layout-height
[re-frame/trim-v]
(fn [db [height]]
(assoc db :layout-height height)))
(handlers/register-handler-db
:set-chat-ui-props
[re-frame/trim-v]

View File

@ -2,37 +2,22 @@
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.i18n :as i18n]
[status-im.chat.styles.screen :as style]
[status-im.utils.datetime :as time]
[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.bottom-info :as bottom-info]
[status-im.i18n :as i18n]
[status-im.ui.components.react :as react]
[status-im.chat.views.message.datemark :as message-datemark]
[status-im.chat.views.message.message :as message]
[status-im.chat.views.input.input :as input]
[status-im.chat.views.toolbar-content :as toolbar-content]
[status-im.ui.components.animation :as animation]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.list-selection :as list-selection]
[status-im.ui.components.react :as react]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.components.chat-icon.screen :as chat-icon-screen]
[status-im.ui.components.sync-state.offline :as offline]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.animation :as animation]))
(defview chat-icon []
(letsubs [{:keys [chat-id group-chat name]} [:get-current-chat]]
[chat-icon-screen/chat-icon-view-action chat-id group-chat name true]))
(defn- toolbar-action [show-actions?]
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:set-chat-ui-props {:show-actions? (not show-actions?)}])
:accessibility-label :chat-menu}
[react/view style/action
(if show-actions?
[vector-icons/icon :icons/dropdown-up]
[chat-icon])]])
[status-im.utils.platform :as platform]))
(defview add-contact-bar []
(letsubs [chat-id [:get-current-chat-id]
@ -44,20 +29,26 @@
[react/text {:style style/add-contact-text}
(i18n/label :t/add-to-contacts)]]])))
(defn- on-options [chat-id chat-name group-chat?]
(list-selection/show {:title chat-name
:options (actions/actions group-chat? chat-id)}))
(defview chat-toolbar []
(letsubs [show-actions? [:get-current-chat-ui-prop :show-actions?]
accounts [:get-accounts]
creating? [:get :accounts/creating-account?]]
(letsubs [accounts [:get-accounts]
creating? [:get :accounts/creating-account?]
{:keys [group-chat name chat-id]} [:get-current-chat]]
[react/view
[status-bar/status-bar]
[toolbar/toolbar {}
(when-not (or show-actions? creating?)
(when-not creating?
(if (empty? accounts)
[toolbar/nav-clear-text {:handler #(re-frame/dispatch [:navigate-to-modal :recover-modal])}
(i18n/label :t/recover)]
toolbar/default-nav-back))
[toolbar-content/toolbar-content-view]
[toolbar-action show-actions?]]
[toolbar/actions [{:icon :icons/options
:icon-opts {:color :black}
:handler #(on-options chat-id name group-chat)}]]]
[add-contact-bar]]))
(defmulti message-row (fn [{{:keys [type]} :row}] type))
@ -72,13 +63,12 @@
:group-chat group-chat
:current-public-key current-public-key)])
(defview messages-view-animation [message-view]
;; smooths out appearance of message-view
(letsubs [opacity (animation/create-value 0)
duration (if platform/android? 100 200)
timeout (if platform/android? 50 0)]
{:component-did-mount (fn [component]
{:component-did-mount (fn [_]
(animation/start
(animation/anim-sequence
[(animation/anim-delay timeout)
@ -106,24 +96,16 @@
(defview chat []
(letsubs [{:keys [group-chat input-text]} [:get-current-chat]
show-actions? [:get-current-chat-ui-prop :show-actions?]
show-bottom-info? [:get-current-chat-ui-prop :show-bottom-info?]
show-emoji? [:get-current-chat-ui-prop :show-emoji?]
layout-height [:get :layout-height]
current-view [:get :view-id]]
{:component-will-unmount #(re-frame/dispatch [:set-chat-ui-props {:show-emoji? false}])}
[react/view {:style style/chat-view
:on-layout (fn [event]
(let [height (.. event -nativeEvent -layout -height)]
(when (not= height layout-height)
(re-frame/dispatch [:set-layout-height height]))))}
[react/view {:style style/chat-view}
[chat-toolbar]
(when (= :chat current-view)
[messages-view-animation
[messages-view group-chat]])
[input/container {:text-empty? (string/blank? input-text)}]
(when show-actions?
[actions/actions-view])
(when show-bottom-info?
[bottom-info/bottom-info-view])
[offline/offline-view {:top (get platform/platform-specific :status-bar-default-height)}]]))

View File

@ -111,13 +111,6 @@
:color component.styles/text2-color
:font-size 12})
(def actions-overlay
{:position :absolute
:top 0
:bottom 0
:left 0
:right 0})
(def typing-all
{:marginBottom 20})
@ -129,12 +122,6 @@
:alignItems :flex-start
:alignSelf :flex-start})
(def typing-background
{:borderRadius 14
:padding 12
:height 38
:backgroundColor component.styles/selected-message-color})
(def typing-text
{:marginTop -2
:fontSize 12

View File

@ -1,133 +1,30 @@
(ns status-im.chat.views.actions
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.chat.styles.screen :as styles]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[status-im.ui.components.react :as react]
[status-im.i18n :as i18n]
[status-im.utils.platform :as platform])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
(:require [re-frame.core :as re-frame]
[status-im.i18n :as i18n]))
(defview menu-item-icon-profile []
[chat-id [:chat :chat-id]
group-chat [:chat :group-chat]
name [:chat :name]
color [:chat :color]]
;; TODO stub data ('online' property)
[chat-icon.screen/chat-icon-view-menu-item chat-id group-chat name color true])
(defn view-profile [chat-id group?]
{:label (i18n/label :t/view-profile)
:action #(re-frame/dispatch [ (if group? :show-group-chat-profile :show-profile) chat-id])})
(defn- members-text [members]
(str (string/join ", " (map :name members))
" "
(i18n/label :t/and-you)))
(defn item-members [members]
{:title (i18n/label :t/members-title)
:subtitle (members-text members)
:icon :menu_group
:icon-opts {:width 25
:height 19}
;; TODO not implemented: action Members
:handler nil})
(defn item-user [chat-id]
{:title (i18n/label :t/profile)
:custom-icon [menu-item-icon-profile]
:icon :menu_group
:icon-style {:width 25
:height 19}
:handler #(re-frame/dispatch [:show-profile chat-id])})
(defn item-delete [chat-id]
{:title (i18n/label :t/delete-chat)
:icon :search_gray_copy
:icon-style {:width 17
:height 17}
(defn delete-chat [chat-id]
{:label (i18n/label :t/delete-chat)
;; TODO(jeluard) Refactor this or Jan will have an heart attack
:handler #(do (re-frame/dispatch [:remove-chat chat-id])
(re-frame/dispatch [:navigation-replace :home]))})
:action #(do (re-frame/dispatch [:remove-chat chat-id])
(re-frame/dispatch [:navigation-replace :home]))})
(def item-notifications
{:title (i18n/label :t/notifications-title)
:subtitle (i18n/label :t/not-implemented)
;;:subtitle "Chat muted"
:icon :muted
:icon-style {:width 18
:height 21}
;; TODO not implemented: action Notifications
:handler nil})
(defn leave-group-chat [chat-id]
{:label (i18n/label :t/leave-group-chat)
:action #(re-frame/dispatch [:leave-group-chat chat-id])})
(def item-settings
{:title (i18n/label :t/settings)
:icon :settings
:icon-style {:width 20
:height 13}
:accessibility-label :settings
:handler #(re-frame/dispatch [:show-group-chat-settings])})
(defn- user-chat-actions [chat-id group?]
[(view-profile chat-id group?)
(delete-chat chat-id)])
(defn group-chat-items [members public?]
(into (if public? [] [(item-members members)])
[item-notifications
item-settings]))
(defn- group-chat-actions [chat-id]
(into (user-chat-actions chat-id true)
[(leave-group-chat chat-id)]))
(defn user-chat-items [chat-id]
[(item-user chat-id)
(item-delete chat-id)
item-notifications])
(defn overlay [{:keys [on-click-outside]} items]
[react/view styles/actions-overlay
[react/touchable-highlight {:on-press on-click-outside
:style styles/overlay-highlight}
[react/view nil]]
items])
(defn action-view [{:keys [react/icon-style
icon
custom-icon
handler
title
subtitle
accessibility-label]
:or {accessibility-label :action}}]
[react/touchable-highlight {:on-press (fn []
(re-frame/dispatch [:set-chat-ui-props {:show-actions? false}])
(when handler
(handler)))}
[react/view {:accessibility-label accessibility-label
:style styles/action-icon-row}
[react/view styles/action-icon-view
(or custom-icon
[react/icon icon icon-style])]
[react/view styles/action-view
[react/text {:style styles/action-title
:number-of-lines 1
:font :medium}
title]
(when-let [subtitle subtitle]
[react/text {:style styles/action-subtitle
:number-of-lines 1
:font :default}
subtitle])]]])
(defview actions-list-view []
(letsubs [group-chat [:chat :group-chat]
chat-id [:chat :chat-id]
public? [:chat :public?]
members [:current-chat-contacts]
status-bar-height (get platform/platform-specific :status-bar-default-height)]
(when-let [actions (if group-chat
(group-chat-items members public?)
(user-chat-items chat-id))]
[react/view (merge
(styles/actions-wrapper status-bar-height)
styles/actions-list-view)
[react/view styles/actions-separator]
[react/view styles/actions-view
(for [action actions]
(if action
^{:key action} [action-view action]))]])))
(defn actions-view []
[overlay {:on-click-outside #(re-frame/dispatch [:set-chat-ui-props {:show-actions? false}])}
[actions-list-view]])
(defn actions [group-chat? chat-id]
(if group-chat?
(group-chat-actions chat-id)
(user-chat-actions chat-id false)))

View File

@ -1,33 +1,29 @@
(ns status-im.chat.views.toolbar-content
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [re-frame.core :refer [subscribe dispatch]]
[clojure.string :as str]
(:require [clojure.string :as string]
[cljs-time.core :as t]
[status-im.ui.components.react :refer [view
text
icon]]
[status-im.i18n :refer [get-contact-translated
label
label-pluralize]]
[status-im.ui.components.react :as react]
[status-im.i18n :as i18n]
[status-im.chat.styles.screen :as st]
[status-im.utils.datetime :as time]
[status-im.utils.platform :refer [platform-specific]]
[status-im.utils.gfycat.core :refer [generate-gfy]]
[status-im.constants :refer [console-chat-id]]))
(defn online-text [contact chat-id]
(defn- online-text [contact chat-id]
(cond
(= console-chat-id chat-id) (label :t/available)
(= console-chat-id chat-id) (i18n/label :t/available)
contact (let [last-online (get contact :last-online)
last-online-date (time/to-date last-online)
now-date (t/now)]
(if (and (pos? last-online)
(<= last-online-date now-date))
(time/time-ago last-online-date)
(label :t/active-unknown)))
:else (label :t/active-unknown)))
(i18n/label :t/active-unknown)))
:else (i18n/label :t/active-unknown)))
(defn in-progress-text [{:keys [highestBlock currentBlock startBlock]}]
(defn- in-progress-text [{:keys [highestBlock currentBlock startBlock]}]
(let [total (- highestBlock startBlock)
ready (- currentBlock startBlock)
percentage (if (zero? ready)
@ -36,29 +32,29 @@
(* 100)
(.round js/Math)))]
(str (label :t/sync-in-progress) " " percentage "% " currentBlock)))
(str (i18n/label :t/sync-in-progress) " " percentage "% " currentBlock)))
(defview last-activity [{:keys [online-text sync-state]}]
[state [:get :sync-data]]
[text {:style st/last-activity-text}
[react/text {:style st/last-activity-text}
(case sync-state
:in-progress (in-progress-text state)
:synced (label :t/sync-synced)
:synced (i18n/label :t/sync-synced)
online-text)])
(defn group-last-activity [{:keys [contacts sync-state public?]}]
(defn- group-last-activity [{:keys [contacts sync-state public?]}]
(if (or (= sync-state :in-progress)
(= sync-state :synced))
[last-activity {:sync-state sync-state}]
(if public?
[view {:flex-direction :row}
[text (label :t/public-group-status)]]
[view {:flex-direction :row}
[text {:style st/members}
[react/view {:flex-direction :row}
[react/text (i18n/label :t/public-group-status)]]
[react/view {:flex-direction :row}
[react/text {:style st/members}
(if public?
(label :t/public-group-status)
(i18n/label :t/public-group-status)
(let [cnt (inc (count contacts))]
(label-pluralize cnt :t/members-active)))]])))
(i18n/label-pluralize cnt :t/members-active)))]])))
(defview toolbar-content-view []
(letsubs [group-chat [:chat :group-chat]
@ -72,16 +68,16 @@
contact [:get-in [:contacts/contacts @chat-id]]
sync-state [:sync-state]
creating? [:get :accounts/creating-account?]]
[view (st/chat-name-view (or (empty? accounts)
show-actions?
creating?))
(let [chat-name (if (str/blank? name)
[react/view (st/chat-name-view (or (empty? accounts)
show-actions?
creating?))
(let [chat-name (if (string/blank? name)
(generate-gfy public-key)
(or (get-contact-translated chat-id :name name)
(label :t/chat-name)))]
[text {:style st/chat-name-text
:number-of-lines 1
:font :toolbar-title}
(or (i18n/get-contact-translated chat-id :name name)
(i18n/label :t/chat-name)))]
[react/text {:style st/chat-name-text
:number-of-lines 1
:font :toolbar-title}
(if public?
(str "#" chat-name)
chat-name)])

View File

@ -86,6 +86,7 @@
;;profile
:profile "Profile"
:view-profile "View profile"
:edit-profile "Edit profile"
:main-currency "Main currency"
:message "Message"
@ -203,6 +204,7 @@
:clear-history "Clear history"
:mute-notifications "Mute notifications"
:leave-chat "Leave chat"
:leave-group-chat "Leave group chat"
:chat-settings "Chat settings"
:edit "Edit"
:add-members "Add members"

View File

@ -198,7 +198,7 @@
(> 100 timeout))
(reset! loading false)
(utils/set-timeout (fn []
(reset! loading false))
(reset! loading false))
timeout)))}
(if (and (not enabled?) @loading)
(or preview

View File

@ -132,9 +132,9 @@
;;;; Handlers
(register-handler-fx
:show-group-chat-settings
(fn [{{:keys [current-chat-id] :as db} :db} _]
{:db (assoc db :new-chat-name (get-in db [:chats current-chat-id :name])
:show-group-chat-profile
(fn [{db :db} [_ chat-id]]
{:db (assoc db :new-chat-name (get-in db [:chats chat-id :name])
:group/group-type :chat-group)
:dispatch [:navigate-to :chat-group-settings]}))