feature #3011 - reworked group chat profile and refactored common profile elements

Signed-off-by: Goran Jovic <goranjovic@gmail.com>
This commit is contained in:
Goran Jovic 2018-02-18 11:55:50 +01:00
parent 80b1edfff6
commit b5b3ad204d
No known key found for this signature in database
GPG Key ID: A778DE3CD7D2D10D
36 changed files with 778 additions and 934 deletions

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path fill="#000000" d="M7.00001034,5 C7.004297,3.34182361 8.34093668,2 10,2 L14,2 C15.6555111,2 16.9973018,3.34290405 16.9999959,5 L18.5454545,5 C19.9047426,5 21,6.12948418 21,7.5 C21,8.87051582 19.9047426,10 18.5454545,10 L5.45454545,10 C4.09525738,10 3,8.87051582 3,7.5 C3,6.12948418 4.09525738,5 5.45454545,5 L7.0000096,5 Z M14.9999879,5 C14.9973085,4.44655807 14.5500233,4 14,4 L10,4 C9.44811686,4 9.00424986,4.44383154 9.00003034,5 L14.9999888,5 Z M12,13.5857864 L13.2928932,12.2928932 C13.6834175,11.9023689 14.3165825,11.9023689 14.7071068,12.2928932 C15.0976311,12.6834175 15.0976311,13.3165825 14.7071068,13.7071068 L13.4142136,15 L14.7071068,16.2928932 C15.0976311,16.6834175 15.0976311,17.3165825 14.7071068,17.7071068 C14.3165825,18.0976311 13.6834175,18.0976311 13.2928932,17.7071068 L12,16.4142136 L10.7071068,17.7071068 C10.3165825,18.0976311 9.68341751,18.0976311 9.29289322,17.7071068 C8.90236893,17.3165825 8.90236893,16.6834175 9.29289322,16.2928932 L10.5857864,15 L9.29289322,13.7071068 C8.90236893,13.3165825 8.90236893,12.6834175 9.29289322,12.2928932 C9.68341751,11.9023689 10.3165825,11.9023689 10.7071068,12.2928932 L12,13.5857864 Z M17,12 C17,11.4477153 17.4477153,11 18,11 C18.5522847,11 19,11.4477153 19,12 L19,19.998 C19,21.604 17.953,23 16.4985,23 L7.5,23 C6.047,23 5,21.604 5,20 L5,12 C5,11.4477153 5.44771525,11 6,11 C6.55228475,11 7,11.4477153 7,12 L7,20 C7,20.604 7.297,21 7.5,21 L16.4985,21 C16.703,21 17,20.604 17,19.998 L17,12 Z M18.5454545,8 C18.7861665,8 19,7.77948418 19,7.5 C19,7.22051582 18.7861665,7 18.5454545,7 L5.45454545,7 C5.21383352,7 5,7.22051582 5,7.5 C5,7.77948418 5.21383352,8 5.45454545,8 L18.5454545,8 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -21,6 +21,7 @@
:error "Error" :error "Error"
:unknown-status-go-error "Unknown status-go error" :unknown-status-go-error "Unknown status-go error"
:node-unavailable "No ethereum node running" :node-unavailable "No ethereum node running"
:add "Add"
:yes "Yes" :yes "Yes"
:no "No" :no "No"
@ -212,12 +213,20 @@
:leave-confirmation "Leave?" :leave-confirmation "Leave?"
:clear "Clear" :clear "Clear"
:clear-history "Clear history" :clear-history "Clear history"
:clear-history-title "Clear history?"
:clear-group-history-confirmation "Are you sure you want to clear this group's chat history?"
:clear-history-confirmation "Clear history?" :clear-history-confirmation "Clear history?"
:clear-group-history-confirmation "Are you sure you want to clear history in this group chat?" :clear-history-action "Clear"
:mute-notifications "Mute notifications" :mute-notifications "Mute notifications"
:leave-group-action "Leave"
:leave-group-title "Leave?"
:leave-group-confirmation "Are you sure you want to leave this group?"
:leave-chat "Leave chat" :leave-chat "Leave chat"
:leave-group-chat-confirmation "Are you sure you want to leave this group?" :leave-group-chat-confirmation "Are you sure you want to leave this group?"
:leave-group-chat "Leave group chat" :leave-group-chat "Leave group chat"
:leave-group "Leave group"
:remove-from-chat "Remove from chat"
:delete-chat-title "Delete chat?"
:leave-public-chat "Leave public chat" :leave-public-chat "Leave public chat"
:chat-settings "Chat settings" :chat-settings "Chat settings"
:edit "Edit" :edit "Edit"

View File

@ -150,7 +150,7 @@
:online-dot-right styles/online-dot-right-profile :online-dot-right styles/online-dot-right-profile
:size size :size size
:chat-icon styles/chat-icon-profile :chat-icon styles/chat-icon-profile
:default-chat-icon (styles/default-chat-icon-profile color) :default-chat-icon (styles/default-chat-icon-profile color size)
:default-chat-icon-text styles/default-chat-icon-text}] :default-chat-icon-text styles/default-chat-icon-text}]
[react/view (:container styles) [react/view (:container styles)
(when edit? (when edit?

View File

@ -17,11 +17,11 @@
:height 40 :height 40
:border-radius 20})) :border-radius 20}))
(defn default-chat-icon-profile [color] (defn default-chat-icon-profile [color size]
(merge (default-chat-icon color) (merge (default-chat-icon color)
{:width 64 {:width size
:height 64 :height size
:border-radius 32})) :border-radius (/ size 2)}))
(defn default-chat-icon-view-action [color] (defn default-chat-icon-view-action [color]
(merge (default-chat-icon color) (merge (default-chat-icon color)

View File

@ -9,8 +9,8 @@
(def gray "#939ba1") ;; Used as a background for a light foreground and as section header and secondary text color (def gray "#939ba1") ;; Used as a background for a light foreground and as section header and secondary text color
(def gray-light "#e8ebec") ;; Used as divider color (def gray-light "#e8ebec") ;; Used as divider color
(def gray-lighter "#eef2f5") ;; Used as a background or shadow (def gray-lighter "#eef2f5") ;; Used as a background or shadow
(def blue "#4360df") ;; Used as main wallet color, and ios home add button (def blue "#4360df") ;; Used as main wallet color
(def blue-transparent "rgba(67, 96, 223, 0.10)") ;; Used as shadow on ios home add button (def blue-transparent "rgba(67, 96, 223, 0.10)") ;;used as shadow for blue elements
(def red "#ff2d55") ;; Used to highlight errors or "dangerous" actions (def red "#ff2d55") ;; Used to highlight errors or "dangerous" actions
(def text-light-gray "#212121") ;; Used for labels (home items) (def text-light-gray "#212121") ;; Used for labels (home items)

View File

@ -25,7 +25,7 @@
[react/text {:style styles/info-text} [react/text {:style styles/info-text}
info])]])) info])]]))
(defn contact-view [{:keys [style contact extended? on-press extend-options info show-forward?]}] (defn contact-view [{:keys [style contact extended? on-press extend-options extend-title info show-forward?]}]
[react/touchable-highlight (when-not extended? [react/touchable-highlight (when-not extended?
{:on-press (when on-press #(on-press contact))}) {:on-press (when on-press #(on-press contact))})
[react/view styles/contact-container [react/view styles/contact-container
@ -35,7 +35,8 @@
[vector-icons/icon :icons/forward]]) [vector-icons/icon :icons/forward]])
(when (and extended? (not (empty? extend-options))) (when (and extended? (not (empty? extend-options)))
[react/view styles/more-btn-container [react/view styles/more-btn-container
[react/touchable-highlight {:on-press #(list-selection/show {:options extend-options})} [react/touchable-highlight {:on-press #(list-selection/show {:options extend-options
:title extend-title})}
[react/view styles/more-btn [react/view styles/more-btn
[vector-icons/icon :icons/options {:accessibility-label :options}]]]])]]) [vector-icons/icon :icons/options {:accessibility-label :options}]]]])]])

View File

@ -1,8 +1,8 @@
(ns status-im.ui.components.contact.styles (ns status-im.ui.components.contact.styles
(:require-macros [status-im.utils.styles :refer [defstyle]]) (:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
(:require [status-im.ui.components.colors :as colors] (:require [status-im.ui.components.styles :as common]
[status-im.ui.components.styles :as common] [status-im.utils.platform]
[status-im.utils.platform])) [status-im.ui.components.colors :as colors]))
(defstyle contact-inner-container (defstyle contact-inner-container
{:flex 1 {:flex 1
@ -48,3 +48,13 @@
(def more-btn (def more-btn
{:padding 16}) {:padding 16})
(def toggle-container
{:width 56
:height 56
:alignItems :center
:justifyContent :center})
(def check-icon
{:width 16
:height 16})

View File

@ -47,6 +47,7 @@
:icons/browse (slurp/slurp-svg "./resources/icons/browse.svg") :icons/browse (slurp/slurp-svg "./resources/icons/browse.svg")
:icons/close (slurp/slurp-svg "./resources/icons/close.svg") :icons/close (slurp/slurp-svg "./resources/icons/close.svg")
:icons/copy-from (slurp/slurp-svg "./resources/icons/copy_from.svg") :icons/copy-from (slurp/slurp-svg "./resources/icons/copy_from.svg")
:icons/delete (slurp/slurp-svg "./resources/icons/delete.svg")
:icons/dots-horizontal (slurp/slurp-svg "./resources/icons/dots_horizontal.svg") :icons/dots-horizontal (slurp/slurp-svg "./resources/icons/dots_horizontal.svg")
:icons/dots-vertical (slurp/slurp-svg "./resources/icons/dots_vertical.svg") :icons/dots-vertical (slurp/slurp-svg "./resources/icons/dots_vertical.svg")
:icons/exclamation_mark (slurp/slurp-svg "./resources/icons/exclamation_mark.svg") :icons/exclamation_mark (slurp/slurp-svg "./resources/icons/exclamation_mark.svg")

View File

@ -44,7 +44,9 @@
(def icon-wrapper-size (+ icon-size (* 2 8))) (def icon-wrapper-size (+ icon-size (* 2 8)))
(def item-icon-wrapper (def item-icon-wrapper
{:align-items :center {:width icon-wrapper-size
:height icon-wrapper-size
:align-items :center
:justify-content :center}) :justify-content :center})
(def item-icon (def item-icon
@ -95,6 +97,21 @@
:ios {:margin-top 10 :ios {:margin-top 10
:margin-bottom 2}}) :margin-bottom 2}})
(def action-list
{:background-color colors/blue})
(def action
{:background-color colors/white-transparent
:border-radius 50})
(def action-label
{:color colors/white})
(def action-separator
{:height 1
:background-color colors/white-light-transparent
:margin-left 70})
(def list-with-label-wrapper (def list-with-label-wrapper
{:margin-top 26 {:margin-top 26
:margin-horizontal 16}) :margin-horizontal 16})

View File

@ -170,6 +170,28 @@
:renderSectionHeader (wrap-render-section-header-fn render-section-header-fn)} :renderSectionHeader (wrap-render-section-header-fn render-section-header-fn)}
(when platform/ios? {:SectionSeparatorComponent (fn [] (reagent/as-element section-separator))}))]) (when platform/ios? {:SectionSeparatorComponent (fn [] (reagent/as-element section-separator))}))])
(defn- render-action [{:keys [label icon action]}
{:keys [action-style action-label-style icon-opts]}]
[react/touchable-highlight {:on-press action}
[react/view
[item
[item-icon {:icon icon
:style (merge styles/action action-style)
:icon-opts (merge {:color :white} icon-opts)}]
[item-primary-only {:style (merge styles/action-label action-label-style)}
label]
item-icon-forward]]])
(defn action-list [actions {:keys [container-style action-separator-style] :as styles}]
[react/view (merge styles/action-list container-style)
[flat-list
{:separator (when platform/ios?
[react/view (merge styles/action-separator
action-separator-style)])
:data actions
:render-fn #(render-action % styles)}]])
(defn list-with-label [{:keys [style]} label list] (defn list-with-label [{:keys [style]} label list]
[react/view (merge styles/list-with-label-wrapper style) [react/view (merge styles/list-with-label-wrapper style)
[react/text {:style styles/label} [react/text {:style styles/label}

View File

@ -74,10 +74,11 @@
;; Actions ;; Actions
(defn text-action [{:keys [style handler disabled?]} title] (defn text-action [{:keys [style handler disabled? uppercase?]} title]
[react/text {:style (merge styles/item styles/item-text style [react/text {:style (merge styles/item styles/item-text style
(when disabled? styles/toolbar-text-action-disabled)) (when disabled? styles/toolbar-text-action-disabled))
:on-press (when-not disabled? handler)} :on-press (when-not disabled? handler)
:uppercase? uppercase?}
title]) title])
(def blank-action [react/view {:style (merge styles/item styles/toolbar-action)}]) (def blank-action [react/view {:style (merge styles/item styles/toolbar-action)}])

View File

@ -148,6 +148,8 @@
:my-profile/profile :my-profile/profile
:my-profile/default-name :my-profile/default-name
:my-profile/editing? :my-profile/editing?
:group-chat-profile/profile
:group-chat-profile/editing?
:networks/selected-network :networks/selected-network
:networks/networks :networks/networks
:node/after-start :node/after-start

View File

@ -8,7 +8,8 @@
[status-im.ui.components.status-bar.view :refer [status-bar]] [status-im.ui.components.status-bar.view :refer [status-bar]]
[status-im.ui.components.toolbar.view :as toolbar] [status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.screens.group.styles :as styles] [status-im.ui.screens.group.styles :as styles]
[status-im.ui.screens.contacts.styles :as contacts.styles])) [status-im.ui.screens.contacts.styles :as contacts.styles]
[status-im.ui.components.styles :as components.styles]))
(defn- on-toggle [checked? whisper-identity] (defn- on-toggle [checked? whisper-identity]
(let [action (if checked? :deselect-contact :select-contact)] (let [action (if checked? :deselect-contact :select-contact)]
@ -29,7 +30,9 @@
toolbar/default-nav-back toolbar/default-nav-back
[toolbar/content-title title] [toolbar/content-title title]
(when (pos? count) (when (pos? count)
[toolbar/text-action {:handler handler} [toolbar/text-action {:handler handler
:uppercase? components.styles/uppercase?
:style styles/toggle-list-action}
label])]) label])])
(defn toggle-list [contacts render-function] (defn toggle-list [contacts render-function]
@ -67,9 +70,23 @@
(:name group)] (:name group)]
[toggle-list contacts group-toggle-contact]])) [toggle-list contacts group-toggle-contact]]))
(defn toggle-participants-handler []
(re-frame/dispatch [:add-new-group-chat-participants])
(re-frame/dispatch [:navigate-back]))
(defn add-participants-toggle-list-toolbar [selected-contacts-count]
[toolbar/toolbar {}
toolbar/default-nav-back
[toolbar/content-title (i18n/label :t/add-members)]
(when (pos? selected-contacts-count)
[toolbar/text-action {:handler toggle-participants-handler
:uppercase? components.styles/uppercase?
:style styles/toggle-list-action}
(i18n/label :t/add)])])
(defview add-participants-toggle-list [] (defview add-participants-toggle-list []
(letsubs [contacts [:all-new-contacts] (letsubs [contacts [:all-new-contacts]
chat-name [:chat :name] chat-name [:chat :name]
selected-contacts-count [:selected-participants-count]] selected-contacts-count [:selected-participants-count]]
[react/keyboard-avoiding-view {:style styles/group-container} [react/keyboard-avoiding-view {:style styles/group-container}
[status-bar] [status-bar]
@ -77,6 +94,6 @@
:handler #(do :handler #(do
(re-frame/dispatch [:add-new-group-chat-participants]) (re-frame/dispatch [:add-new-group-chat-participants])
(re-frame/dispatch [:navigate-back])) (re-frame/dispatch [:navigate-back]))
:label (i18n/label :t/save)} :label (i18n/label :t/add)}
chat-name] chat-name]
[toggle-list contacts group-toggle-participant]])) [toggle-list contacts group-toggle-participant]]))

View File

@ -135,7 +135,7 @@
(fn [{db :db} [_ chat-id]] (fn [{db :db} [_ chat-id]]
{:db (assoc db :new-chat-name (get-in db [:chats chat-id :name]) {:db (assoc db :new-chat-name (get-in db [:chats chat-id :name])
:group/group-type :chat-group) :group/group-type :chat-group)
:dispatch [:navigate-to :chat-group-settings]})) :dispatch [:navigate-to :group-chat-profile]}))
(handlers/register-handler-fx (handlers/register-handler-fx
:add-new-group-chat-participants :add-new-group-chat-participants
@ -162,8 +162,8 @@
(select-keys db [:current-chat-id :contacts/contacts]))})) (select-keys db [:current-chat-id :contacts/contacts]))}))
(handlers/register-handler-fx (handlers/register-handler-fx
:set-chat-name :set-group-chat-name
(fn [{{:keys [current-chat-id new-chat-name] :as db} :db} _] (fn [{{:keys [current-chat-id] :as db} :db} [_ new-chat-name]]
{:db (assoc-in db [:chats current-chat-id :name] new-chat-name) {:db (assoc-in db [:chats current-chat-id :name] new-chat-name)
::save-chat-property [current-chat-id :name new-chat-name]})) ::save-chat-property [current-chat-id :name new-chat-name]}))

View File

@ -1,65 +0,0 @@
(ns status-im.ui.screens.group.chat-settings.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [re-frame.core :refer [dispatch]]
[status-im.ui.components.contact.contact :refer [contact-view]]
[status-im.ui.components.common.common :as common]
[status-im.ui.components.react :refer [view scroll-view keyboard-avoiding-view]]
[status-im.ui.components.sticky-button :refer [sticky-button]]
[status-im.ui.screens.group.styles :as styles]
[status-im.ui.screens.group.views :refer [group-toolbar group-chat-settings-btns
group-name-view add-btn more-btn]]
[status-im.ui.screens.group.db :as v]
[status-im.i18n :refer [label]]
[cljs.spec.alpha :as spec]))
(def ^:const contacts-limit 3)
(defview chat-group-contacts-view [admin?]
(letsubs [contacts [:current-chat-contacts]]
(let [limited-contacts (take contacts-limit contacts)
contacts-count (count contacts)]
[view
(when (and admin? (pos? contacts-count))
[common/list-separator])
[view
(doall
(map (fn [row]
^{:key row}
[view
[contact-view
{:contact row
:extend-options [{:action #(dispatch [:remove-group-chat-participants #{(:whisper-identity row)}])
:label (label :t/remove)}]
:extended? admin?}]
(when-not (= row (last limited-contacts))
[common/list-separator])])
limited-contacts))]
(when (< contacts-limit contacts-count)
[more-btn contacts-limit contacts-count #(dispatch [:navigate-to :edit-chat-group-contact-list])])])))
(defview chat-group-members []
(letsubs [current-pk [:get :current-public-key]
group-admin [:chat :group-admin]]
(let [admin? (= current-pk group-admin)]
[view
(when admin?
[add-btn #(dispatch [:navigate-to :add-participants-toggle-list])])
[chat-group-contacts-view admin?]])))
(defview chat-group-settings []
(letsubs [new-chat-name [:get :new-chat-name]
chat-name [:chat :name]
type [:get-group-type]]
(let [save-btn-enabled? (and (spec/valid? ::v/name new-chat-name)
(not= new-chat-name chat-name))]
[keyboard-avoiding-view {:style styles/group-container}
[view {:flex 1}
[group-toolbar type true]
[scroll-view
[group-name-view]
[chat-group-members]
[view styles/separator]
[group-chat-settings-btns]]]
(when save-btn-enabled?
[sticky-button (label :t/save) #(dispatch [:set-chat-name])
true])])))

View File

@ -34,20 +34,6 @@
:accessibility-label :remove-button :accessibility-label :remove-button
:label (i18n/label :t/remove-from-group)}])) :label (i18n/label :t/remove-from-group)}]))
(defview edit-chat-group-contact-list []
(letsubs [chat-name [:chat :name]
contacts [:current-chat-contacts]
current-pk [:get :current-public-key]
group-admin [:chat :group-admin]]
(let [admin? (= current-pk group-admin)]
[react/view styles/group-container
[status-bar]
[toolbar/simple-toolbar chat-name]
[contacts-list
contacts
admin?
chat-extended-options]])))
(defview contacts-list-view [group-id] (defview contacts-list-view [group-id]
(letsubs [contacts [:all-added-group-contacts group-id]] (letsubs [contacts [:all-added-group-contacts group-id]]
[contacts-list [contacts-list

View File

@ -170,3 +170,9 @@
(def list-view-container (def list-view-container
{:flex 1 {:flex 1
:margin-top 10}) :margin-top 10})
(defstyle toggle-list-action
{:font-size 14
:android {:font-weight "500"}})

View File

@ -1,25 +1,17 @@
(ns status-im.ui.screens.group.views (ns status-im.ui.screens.group.views
(:require-macros [status-im.utils.views :refer [defview letsubs]]) (:require-macros [status-im.utils.views :as views])
(:require [cljs.spec.alpha :as spec] (:require [cljs.spec.alpha :as spec]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[status-im.i18n :as i18n] [status-im.i18n :as i18n]
[status-im.ui.screens.contacts.styles :as cstyles]
[status-im.ui.components.common.common :as common]
[status-im.ui.components.action-button.action-button :refer [action-button action-separator]]
[status-im.ui.components.react :as react] [status-im.ui.components.react :as react]
[status-im.ui.components.icons.vector-icons :as vi]
[status-im.ui.components.list.views :as list] [status-im.ui.components.list.views :as list]
[status-im.ui.components.text-input-with-label.view :refer [text-input-with-label]]
[status-im.ui.components.status-bar.view :as status-bar] [status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.components.styles :as components.styles]
[status-im.ui.components.toolbar.view :as toolbar] [status-im.ui.components.toolbar.view :as toolbar]
[status-im.utils.platform :as platform :refer [platform-specific ios?]] [status-im.utils.platform :as platform]
[status-im.ui.components.sticky-button :refer [sticky-button]] [status-im.ui.components.contact.contact :as contact]
[status-im.ui.components.contact.contact :refer [contact-view]]
[status-im.ui.screens.add-new.styles :as add-new.styles] [status-im.ui.screens.add-new.styles :as add-new.styles]
[status-im.ui.screens.group.styles :as styles] [status-im.ui.screens.group.styles :as styles]
[status-im.ui.screens.group.db :as v] [status-im.ui.screens.group.db :as v]))
[status-im.utils.utils :as utils]))
(defn group-toolbar [group-type edit?] (defn group-toolbar [group-type edit?]
[react/view [react/view
@ -30,8 +22,8 @@
(if edit? :t/edit-group :t/new-group) (if edit? :t/edit-group :t/new-group)
(if edit? :t/chat-settings :t/group-chat)))]]) (if edit? :t/chat-settings :t/group-chat)))]])
(defview group-name-view [] (views/defview group-name-view []
(letsubs [new-group-name [:get :new-chat-name]] (views/letsubs [new-group-name [:get :new-chat-name]]
[react/view add-new.styles/input-container [react/view add-new.styles/input-container
[react/text-input [react/text-input
{:auto-focus true {:auto-focus true
@ -40,107 +32,8 @@
:placeholder (i18n/label :t/set-a-topic) :placeholder (i18n/label :t/set-a-topic)
:style add-new.styles/input}]])) :style add-new.styles/input}]]))
(defn add-btn [on-press]
[action-button {:label (i18n/label :t/add-members)
:icon :icons/add
:icon-opts {:color :blue}
:on-press on-press}])
(defn delete-btn [on-press]
[react/view styles/settings-group-container
[react/touchable-highlight {:on-press on-press}
[react/view styles/settings-group-item
[react/view styles/delete-icon-container
[vi/icon :icons/close {:color :red}]]
[react/view styles/settings-group-text-container
[react/text {:style styles/delete-group-text}
(i18n/label :t/delete-group)]
[react/text {:style styles/delete-group-prompt-text}
(i18n/label :t/delete-group-prompt)]]]]])
(defn group-chat-settings-btns []
[react/view styles/settings-group-container
[react/view {:opacity 0.4}
[react/touchable-highlight {:on-press #()}
[react/view styles/settings-group-item
[react/view styles/settings-icon-container
[vi/icon :icons/speaker {:color :blue}]]
[react/view styles/settings-group-text-container
[react/text {:style styles/settings-group-text}
(i18n/label :t/mute-notifications)]]]]]
[action-separator]
[action-button {:label (i18n/label :t/clear-history)
:icon :icons/close
:icon-opts {:color :blue}
:on-press #(re-frame/dispatch [:clear-history])}]
[action-separator]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:leave-group-chat])}
[react/view styles/settings-group-item
[react/view styles/delete-icon-container
[vi/icon :icons/arrow-right {:color :red}]]
[react/view styles/settings-group-text-container
[react/text {:style styles/delete-group-text}
(i18n/label :t/leave-chat)]]]]])
(defn more-btn [contacts-limit contacts-count on-press]
[react/view
[common/list-separator]
[react/view cstyles/show-all
[react/touchable-highlight {:on-press on-press}
[react/view
[react/text {:style cstyles/show-all-text
:uppercase? (components.styles/uppercase?)
:font (if ios? :default :medium)}
(str (- contacts-count contacts-limit) " " (i18n/label :t/more))]]]]])
(def ^:const contacts-limit 3)
(defview group-contacts-view [group]
(letsubs [contacts [:all-added-group-contacts-with-limit (:group-id group) contacts-limit]
contacts-count [:all-added-group-contacts-count (:group-id group)]]
[react/view
(when (pos? contacts-count)
[common/list-separator])
[react/view
(doall
(map (fn [row]
^{:key row}
[react/view
[contact-view
{:contact row
:extend-options [{:action #(re-frame/dispatch [:remove-contact-from-group
(:whisper-identity row)
(:group-id group)])
:label (i18n/label :t/remove-from-group)}]
:extended? true}]
(when-not (= row (last contacts))
[common/list-separator])])
contacts))]
(when (< contacts-limit contacts-count)
[more-btn contacts-limit contacts-count #(re-frame/dispatch [:navigate-to :edit-group-contact-list])])]))
(defview edit-contact-group []
(letsubs [{:keys [group group-type]} [:get-screen-params]]
(let [group-name (:name group)
save-btn-enabled? (and (spec/valid? ::v/name group-name)
(not= group-name (:name group)))]
[react/keyboard-avoiding-view {:style styles/group-container}
[group-toolbar group-type true]
[group-name-view]
[react/view styles/list-view-container
[add-btn #(re-frame/dispatch [:navigate-to :add-contacts-toggle-list])]
[group-contacts-view group]
[react/view styles/separator]
[delete-btn #(utils/show-confirmation
(str (i18n/label :t/delete-group) "?") (i18n/label :t/delete-group-confirmation) (i18n/label :t/delete)
(fn[]
(re-frame/dispatch [:delete-contact-group])
(re-frame/dispatch [:navigate-to-clean :contact-list])))]]
(when save-btn-enabled?
[sticky-button (i18n/label :t/save) #(re-frame/dispatch [:set-contact-group-name])])])))
(defn- render-contact [contact] (defn- render-contact [contact]
[contact-view {:contact contact :style styles/contact}]) [contact/contact-view {:contact contact :style styles/contact}])
(defn- toolbar [group-name save-btn-enabled?] (defn- toolbar [group-name save-btn-enabled?]
[toolbar/toolbar {} [toolbar/toolbar {}
@ -155,9 +48,9 @@
[toolbar/text-action {:handler handler} [toolbar/text-action {:handler handler}
(i18n/label :t/create)])))]) (i18n/label :t/create)])))])
(defview new-group [] (views/defview new-group []
(letsubs [contacts [:selected-group-contacts] (views/letsubs [contacts [:selected-group-contacts]
group-name [:get :new-chat-name]] group-name [:get :new-chat-name]]
(let [save-btn-enabled? (and (spec/valid? ::v/name group-name) (pos? (count contacts)))] (let [save-btn-enabled? (and (spec/valid? ::v/name group-name) (pos? (count contacts)))]
[react/keyboard-avoiding-view (merge {:behavior :padding} [react/keyboard-avoiding-view (merge {:behavior :padding}
styles/group-container) styles/group-container)

View File

@ -7,9 +7,9 @@
[status-im.ui.components.status-bar.view :as status-bar.view] [status-im.ui.components.status-bar.view :as status-bar.view]
[status-im.ui.components.styles :as common.styles] [status-im.ui.components.styles :as common.styles]
[status-im.ui.screens.home.views :as home] [status-im.ui.screens.home.views :as home]
[status-im.ui.screens.profile.views :as profile]
[status-im.ui.screens.wallet.views :as wallet] [status-im.ui.screens.wallet.views :as wallet]
[status-im.ui.screens.main-tabs.styles :as styles])) [status-im.ui.screens.main-tabs.styles :as styles]
[status-im.ui.screens.profile.user.views :as profile.user]))
(def tabs-list-data (def tabs-list-data
[{:view-id :home [{:view-id :home
@ -75,7 +75,7 @@
{:enabled? (= :my-profile view-id) {:enabled? (= :my-profile view-id)
:preview [react/view {}]} :preview [react/view {}]}
[react/navigation-wrapper [react/navigation-wrapper
{:component profile/my-profile {:component profile.user/my-profile
:views :my-profile :views :my-profile
:current-view view-id}]] :current-view view-id}]]
[tabs view-id]]])) [tabs view-id]]]))

View File

@ -0,0 +1,89 @@
(ns status-im.ui.screens.profile.components.styles
(:require-macros [status-im.utils.styles :refer [defstyle]])
(:require [status-im.ui.components.styles :as styles]
[status-im.ui.components.colors :as colors]))
;; profile header elements
(def profile-header-display
{:flex-direction :column
:justify-content :center
:align-items :center})
(def profile-header-edit
{:flex-direction :column
:justify-content :center})
(defstyle profile-name-text
{:padding-vertical 14
:font-size 15
:text-align :center
:ios {:letter-spacing -0.2}
:android {:color colors/black}})
(defstyle profile-name-input-text
{:font-size 15
:text-align :center
:flex 1
:ios {:letter-spacing -0.2
:height 46
:border-bottom-width 1
:border-bottom-color colors/gray-light}
:android {:color colors/black
:border-bottom-width 2
:border-bottom-color colors/blue}})
(def profile-header-name-container
{:flex 1
:justify-content :center})
;; settings items elements
(def settings-item-separator
{:margin-left 16})
(defstyle settings-item
{:padding-horizontal 16
:flex-direction :row
:align-items :center
:background-color colors/white
:height 52})
(defstyle settings-item-text
{:flex 1
:flex-wrap :nowrap
:font-size 15
:ios {:letter-spacing -0.2}
:android {:color colors/black}})
(def settings-item-value
{:flex 2
:flex-wrap :nowrap
:text-align :right
:padding-right 10
:font-size 15
:color colors/gray})
(defstyle settings-title
{:color colors/gray
:margin-left 16
:margin-top 18
:font-size 14
:ios {:letter-spacing -0.2}})
;; shared profile styles
(def modal-menu
{:align-items :center})
(def profile
{:flex 1
:background-color colors/white
:flex-direction :column})
(def profile-form
{:background-color colors/white
:padding 16})
(defstyle profile-info-container
{:background-color colors/white})

View File

@ -0,0 +1,77 @@
(ns status-im.ui.screens.profile.components.views
(:require [status-im.ui.components.react :as react]
[re-frame.core :as re-frame]
[status-im.ui.components.list-selection :as list-selection]
[status-im.i18n :as i18n]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[status-im.ui.screens.profile.components.styles :as styles]
[status-im.ui.components.common.common :as common]
[status-im.ui.components.styles :as components.styles]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.colors :as colors]
[clojure.string :as string]))
;; profile header elements
(defn profile-name-input [name on-change-text-event]
[react/view
[react/text-input
{:style styles/profile-name-input-text
:placeholder ""
:default-value name
:auto-focus true
:on-change-text #(when on-change-text-event
(re-frame/dispatch [on-change-text-event %]))}]])
(defn show-profile-icon-actions [options]
(when (seq options)
(list-selection/show {:title (i18n/label :t/image-source-title)
:options options})))
(defn profile-header-display [{:keys [name] :as contact}]
[react/view styles/profile-header-display
[chat-icon.screen/my-profile-icon {:account contact
:edit? false}]
[react/view styles/profile-header-name-container
[react/text {:style styles/profile-name-text
:number-of-lines 1}
name]]])
(defn profile-header-edit [{:keys [name] :as contact}
icon-options on-change-text-event allow-icon-change?]
[react/view styles/profile-header-edit
[react/touchable-highlight {:on-press #(show-profile-icon-actions icon-options)}
[react/view styles/modal-menu
[chat-icon.screen/my-profile-icon {:account contact
:edit? allow-icon-change?}]]]
[react/view styles/profile-header-name-container
[profile-name-input name on-change-text-event]]])
(defn profile-header [contact editing? allow-icon-change? options on-change-text-event]
(if editing?
[profile-header-edit contact options on-change-text-event allow-icon-change?]
[profile-header-display contact]))
;; settings items elements
(defn settings-item-separator []
[common/separator styles/settings-item-separator])
(defn settings-title [title]
[react/text {:style styles/settings-title}
title])
(defn settings-item [label-kw value action-fn active?]
[react/touchable-highlight
{:on-press action-fn
:disabled (not active?)}
[react/view styles/settings-item
[react/text {:style styles/settings-item-text}
(i18n/label label-kw)]
(when-not (string/blank? value)
[react/text {:style styles/settings-item-value
:number-of-lines 1
:uppercase? components.styles/uppercase?}
value])
(when active?
[vector-icons/icon :icons/forward {:color colors/gray}])]])

View File

@ -0,0 +1,40 @@
(ns status-im.ui.screens.profile.contact.styles
(:require-macros [status-im.utils.styles :refer [defstyle]])
(:require [status-im.ui.components.colors :as colors]))
(def network-info {:background-color :white})
(defstyle profile-setting-item
{:flex-direction :row
:align-items :center
:padding-left 16
:ios {:height 73}
:android {:height 72}})
(defn profile-info-text-container [options]
{:flex 1
:padding-right (if options 16 40)})
(defstyle profile-info-title
{:color colors/gray
:margin-left 16
:font-size 14
:ios {:letter-spacing -0.2}})
(defstyle profile-setting-spacing
{:ios {:height 10}
:android {:height 7}})
(defstyle profile-setting-text
{:ios {:font-size 17
:letter-spacing -0.2}
:android {:font-size 16
:color colors/black}})
(def profile-setting-text-empty
(merge profile-setting-text
{:color colors/gray}))
(def profile-info-item-button
{:padding 16})

View File

@ -0,0 +1,117 @@
(ns status-im.ui.screens.profile.contact.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [status-im.ui.screens.profile.contact.styles :as styles]
[status-im.ui.components.common.common :as common]
[status-im.ui.components.react :as react]
[status-im.ui.screens.profile.components.styles :as profile.components.styles]
[status-im.ui.screens.profile.components.views :as profile.components]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.components.action-button.styles :as action-button.styles]
[status-im.ui.components.action-button.action-button :as action-button]
[status-im.i18n :as i18n]
[re-frame.core :as re-frame]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.toolbar.actions :as actions]
[status-im.ui.components.list-selection :as list-selection]
[status-im.ui.components.icons.vector-icons :as vector-icons]))
(defn profile-contact-toolbar [contact]
[toolbar/toolbar {}
toolbar/default-nav-back
[toolbar/content-title ""]
[toolbar/actions
(when (and (not (:pending? contact))
(not (:unremovable? contact)))
[(actions/opts [{:action #(re-frame/dispatch [:hide-contact contact])
:label (i18n/label :t/remove-from-contacts)}])])]])
(defn network-info []
[react/view styles/network-info
[common/network-info]
[common/separator]])
(defn profile-actions [{:keys [pending? whisper-identity dapp?]} chat-id]
[react/view action-button.styles/actions-list
(if pending?
[action-button/action-button {:label (i18n/label :t/add-to-contacts)
:icon :icons/add
:icon-opts {:color :blue}
:on-press #(re-frame/dispatch [:add-pending-contact chat-id])}]
[action-button/action-button-disabled {:label (i18n/label :t/in-contacts) :icon :icons/ok}])
[action-button/action-separator]
[action-button/action-button {:label (i18n/label :t/start-conversation)
:icon :icons/chats
:icon-opts {:color :blue}
:on-press #(re-frame/dispatch [:start-chat whisper-identity {:navigation-replace? true}])}]
(when-not dapp?
[react/view
[action-button/action-separator]
[action-button/action-button {:label (i18n/label :t/send-transaction)
:icon :icons/arrow-right
:icon-opts {:color :blue}
:on-press #(re-frame/dispatch [:profile/send-transaction chat-id whisper-identity])}]])])
(defn profile-info-item [{:keys [label value options text-mode empty-value? accessibility-label]}]
[react/view styles/profile-setting-item
[react/view (styles/profile-info-text-container options)
[react/text {:style styles/profile-info-title}
label]
[react/view styles/profile-setting-spacing]
[react/text {:style (if empty-value?
styles/profile-setting-text-empty
styles/profile-setting-text)
:number-of-lines 1
:ellipsizeMode text-mode
:accessibility-label accessibility-label}
value]]
(when options
[react/touchable-highlight {:on-press #(list-selection/show {:options options})}
[react/view profile.components.styles/modal-menu
[vector-icons/icon :icons/options {:container-style styles/profile-info-item-button}]]])])
(defn profile-options [text]
(into []
(when text
(list-selection/share-options text))))
(defn profile-info-address-item [address]
[profile-info-item
{:label (i18n/label :t/address)
:action address
:options (profile-options address)
:text-mode :middle
:accessibility-label :profile-address
:value address}])
(defn profile-info-public-key-item [whisper-identity]
[profile-info-item
{:label (i18n/label :t/public-key)
:action whisper-identity
:options (profile-options whisper-identity)
:text-mode :middle
:accessibility-label :profile-public-key
:value whisper-identity}])
(defn profile-info [{:keys [whisper-identity address]}]
[react/view
[profile-info-address-item address]
[profile.components/settings-item-separator]
[profile-info-public-key-item whisper-identity]])
(defview profile []
(letsubs [contact [:contact]
chat-id [:get :current-chat-id]]
[react/view profile.components.styles/profile
[status-bar/status-bar]
[profile-contact-toolbar contact]
[network-info]
[react/scroll-view
[react/view profile.components.styles/profile-form
[profile.components/profile-header contact false false nil nil]]
[common/form-spacer]
[profile-actions contact chat-id]
[common/form-spacer]
[react/view profile.components.styles/profile-info-container
[profile-info contact]
[common/bottom-shadow]]]]))

View File

@ -1,19 +1,14 @@
(ns status-im.ui.screens.profile.events (ns status-im.ui.screens.profile.events
(:require [clojure.spec.alpha :as spec] (:require [clojure.spec.alpha :as spec]
[clojure.string :as string]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[status-im.ui.components.react :refer [show-image-picker]] [status-im.ui.components.react :refer [show-image-picker]]
[status-im.constants :as const]
[status-im.chat.constants :as chat-const] [status-im.chat.constants :as chat-const]
[status-im.ui.screens.profile.db :as db]
[status-im.ui.screens.profile.navigation] [status-im.ui.screens.profile.navigation]
[status-im.ui.screens.accounts.events :as accounts-events] [status-im.ui.screens.accounts.events :as accounts-events]
[status-im.chat.events :as chat-events] [status-im.chat.events :as chat-events]
[status-im.chat.events.input :as input-events] [status-im.chat.events.input :as input-events]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.handlers :as handlers] [status-im.utils.handlers :as handlers]
[status-im.utils.image-processing :refer [img->base64]] [status-im.utils.image-processing :refer [img->base64]]
[status-im.utils.core :as utils]
[taoensso.timbre :as log])) [taoensso.timbre :as log]))
(re-frame/reg-fx (re-frame/reg-fx
@ -42,56 +37,9 @@
(defn get-current-account [{:keys [:accounts/current-account-id] :as db}] (defn get-current-account [{:keys [:accounts/current-account-id] :as db}]
(get-in db [:accounts/accounts current-account-id])) (get-in db [:accounts/accounts current-account-id]))
(handlers/register-handler-fx
:my-profile.drawer/edit-name
(fn [{:keys [db]} _]
(let [{:my-profile/keys [default-name]} db
{:keys [name public-key]} (get-current-account db)]
{:db (cond-> db
(not default-name) (assoc :my-profile/default-name (gfycat/generate-gfy public-key))
:always (assoc-in [:my-profile/drawer :name] name))})))
(handlers/register-handler-fx
:my-profile.drawer/edit-status
(fn [{:keys [db]} _]
(let [{:keys [status]} (get-current-account db)]
{:db (-> db
(assoc-in [:my-profile/drawer :status] status)
(assoc-in [:my-profile/drawer :edit-status?] true))})))
(handlers/register-handler-fx
:my-profile/edit-profile
(fn [{:keys [db]} [_ edit-status?]]
(let [new-db (-> db
(assoc-in [:my-profile/profile :edit-status?] edit-status?)
(update-in [:my-profile/profile]
#(merge (select-keys (get-current-account db) db/account-profile-keys) %)))]
{:db new-db})))
(defn valid-name? [name] (defn valid-name? [name]
(spec/valid? :profile/name name)) (spec/valid? :profile/name name))
(handlers/register-handler-fx
:my-profile.drawer/update-name
(fn [{:keys [db]} [_ name]]
{:db (-> db
(assoc-in [:my-profile/drawer :valid-name?] (valid-name? name))
(assoc-in [:my-profile/drawer :name] name))}))
(handlers/register-handler-fx
:my-profile.drawer/update-status
(fn [{:keys [db]} [_ status]]
(let [linebreak? (string/includes? status "\n")
new-db (if linebreak?
(-> db
(assoc-in [:my-profile/drawer :edit-status?] nil)
(assoc-in [:my-profile/drawer :status] (utils/clean-text status)))
(assoc-in db [:my-profile/drawer :status] status))]
(if linebreak?
{:db new-db
:dispatch [:my-profile.drawer/save-status]}
{:db new-db}))))
(handlers/register-handler-fx (handlers/register-handler-fx
:my-profile/update-name :my-profile/update-name
(fn [{:keys [db]} [_ name]] (fn [{:keys [db]} [_ name]]
@ -99,15 +47,6 @@
(assoc-in [:my-profile/profile :valid-name?] (valid-name? name)) (assoc-in [:my-profile/profile :valid-name?] (valid-name? name))
(assoc-in [:my-profile/profile :name] name))})) (assoc-in [:my-profile/profile :name] name))}))
(handlers/register-handler-fx
:my-profile/update-status
(fn [{:keys [db]} [_ status]]
{:db (if (string/includes? status "\n")
(-> db
(assoc-in [:my-profile/profile :edit-status?] nil)
(assoc-in [:my-profile/profile :status] (utils/clean-text status)))
(assoc-in db [:my-profile/profile :status] status))}))
(handlers/register-handler-fx (handlers/register-handler-fx
:my-profile/update-picture :my-profile/update-picture
(fn [{:keys [db]} [this-event base64-image]] (fn [{:keys [db]} [this-event base64-image]]
@ -132,29 +71,6 @@
(accounts-events/account-update {:name cleaned-name (accounts-events/account-update {:name cleaned-name
:last-updated now}))))) :last-updated now})))))
(defn status-change
"Takes map containing old status and the updated one and if the status has changed
returns the effects neccessary for status broadcasting"
[fx {:keys [old-status status]}]
(if (and status (not= status old-status))
(assoc fx :dispatch-n [[:broadcast-status status]])
fx))
(handlers/register-handler-fx
:my-profile.drawer/save-status
(fn [{:keys [db now]} _]
(let [status (get-in db [:my-profile/drawer :status])
new-fx (clear-profile {:db db})
{:accounts/keys [accounts current-account-id]} db
{old-status :status} (get accounts current-account-id)]
(if (string/blank? status)
new-fx
(-> new-fx
(accounts-events/account-update {:status status
:last-updated now})
(status-change {:old-status old-status
:status status}))))))
(handlers/register-handler-fx (handlers/register-handler-fx
:my-profile/start-editing-profile :my-profile/start-editing-profile
(fn [{:keys [db]} []] (fn [{:keys [db]} []]
@ -163,17 +79,23 @@
(handlers/register-handler-fx (handlers/register-handler-fx
:my-profile/save-profile :my-profile/save-profile
(fn [{:keys [db now]} _] (fn [{:keys [db now]} _]
(let [{:accounts/keys [accounts current-account-id]} db (let [{:keys [photo-path]} (:my-profile/profile db)
{old-status :status} (get accounts current-account-id)
{:keys [status photo-path]} (:my-profile/profile db)
cleaned-name (clean-name db :my-profile/profile) cleaned-name (clean-name db :my-profile/profile)
cleaned-edit (merge {:name cleaned-name cleaned-edit (merge {:name cleaned-name
:status status
:last-updated now} :last-updated now}
(if photo-path (if photo-path
{:photo-path photo-path}))] {:photo-path photo-path}))]
(-> (clear-profile {:db db}) (-> (clear-profile {:db db})
(accounts-events/account-update cleaned-edit) (accounts-events/account-update cleaned-edit)
(status-change {:old-status old-status
:status status})
(update :dispatch-n concat [[:navigate-back]]))))) (update :dispatch-n concat [[:navigate-back]])))))
(handlers/register-handler-fx
:group-chat-profile/start-editing
(fn [{:keys [db]} _]
{:db (assoc db :group-chat-profile/editing? true)}))
(handlers/register-handler-fx
:group-chat-profile/save-profile
(fn [{:keys [db]} _]
(-> {:db db}
(update :db dissoc :group-chat-profile/editing?))))

View File

@ -0,0 +1,21 @@
(ns status-im.ui.screens.profile.group-chat.styles
(:require [status-im.ui.components.colors :as colors]))
(def action-container
{:background-color colors/white
:padding-top 24})
(def action
{:background-color colors/blue-transparent
:border-radius 50})
(def action-label
{:color colors/blue})
(def action-separator
{:height 1
:background-color colors/gray-light
:margin-left 50})
(def action-icon-opts
{:color colors/blue})

View File

@ -0,0 +1,109 @@
(ns status-im.ui.screens.profile.group-chat.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [status-im.ui.screens.profile.group-chat.styles :as styles]
[status-im.ui.components.react :as react]
[status-im.ui.screens.profile.components.styles :as profile.components.styles]
[status-im.ui.screens.profile.components.views :as profile.components]
[status-im.ui.components.contact.contact :as contact]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.styles :as components.styles]
[status-im.ui.components.toolbar.view :as toolbar]
[re-frame.core :as re-frame]
[status-im.ui.components.common.styles :as common.styles]
[status-im.i18n :as i18n]
[status-im.utils.utils :as utils]))
(defn group-chat-profile-toolbar []
[toolbar/toolbar {}
toolbar/default-nav-back
[toolbar/content-title ""]
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:group-chat-profile/start-editing])}
[react/view
[react/text {:style common.styles/label-action-text
:uppercase? components.styles/uppercase?} (i18n/label :t/edit)]]]])
(defn group-chat-profile-edit-toolbar []
[toolbar/toolbar {}
nil
[toolbar/content-title ""]
[toolbar/default-done {:handler #(re-frame/dispatch [:group-chat-profile/save-profile])
:icon :icons/ok
:icon-opts {:color colors/blue}}]])
(defn actions [admin? chat-id]
(concat
(when admin?
[{:label (i18n/label :add-members)
:icon :icons/add
:action #(re-frame/dispatch [:navigate-to :add-participants-toggle-list])}])
[{:label (i18n/label :t/clear-history)
:icon :icons/close
:action #(utils/show-confirmation (i18n/label :t/clear-history-title)
(i18n/label :t/clear-group-history-confirmation)
(i18n/label :t/clear-history-action)
(fn [] (re-frame/dispatch [:clear-history])))}
{:label (i18n/label :t/delete-chat)
:icon :icons/delete
:action #(utils/show-confirmation (i18n/label :t/delete-chat-title)
(i18n/label :t/delete-group-chat-confirmation)
(i18n/label :t/delete)
(fn [] ;; TODO(goranjovic) - fix double dispatch after rebase agains group chat actions
(re-frame/dispatch [:remove-chat chat-id])
(re-frame/dispatch [:navigation-replace :home])))}
{:label (i18n/label :t/leave-group)
:icon :icons/arrow-left
:action #(utils/show-confirmation (i18n/label :t/leave-group-title)
(i18n/label :t/leave-group-confirmation)
(i18n/label :t/leave-group-action)
(fn [] (re-frame/dispatch [:leave-group-chat])))}]))
(defn contact-actions [contact]
[{:action #(re-frame/dispatch [:show-profile (:whisper-identity contact)])
:label (i18n/label :t/view-profile)}
{:action #(re-frame/dispatch [:remove-group-chat-participants #{(:whisper-identity contact)}])
:label (i18n/label :t/remove-from-chat)}])
(defn render-contact [contact admin?]
[react/view
[contact/contact-view
{:contact contact
:extend-options (contact-actions contact)
:extend-title (:name contact)
:extended? admin?}]])
(defview chat-group-contacts-view [admin?]
(letsubs [contacts [:current-chat-contacts]]
[react/view
[list/flat-list {:data contacts
:separator list/default-separator
:render-fn #(render-contact % admin?)}]]))
(defn members-list [admin?]
[react/view
[profile.components/settings-title (i18n/label :t/members-title)]
[chat-group-contacts-view admin?]])
(defview group-chat-profile []
(letsubs [current-chat [:get-current-chat]
editing? [:get :group-chat-profile/editing?]
changed-chat [:get :group-chat-profile/profile]
current-pk [:get :current-public-key]
group-admin [:chat :group-admin]]
(let [shown-chat (merge current-chat changed-chat)
admin? (= current-pk group-admin)]
[react/view profile.components.styles/profile
(if editing?
[group-chat-profile-edit-toolbar]
[group-chat-profile-toolbar])
[react/scroll-view
[react/view profile.components.styles/profile-form
[profile.components/profile-header shown-chat editing? false nil :set-group-chat-name]
[list/action-list (actions admin? (:chat-id current-chat))
{:container-style styles/action-container
:action-style styles/action
:action-label-style styles/action-label
:action-separator-style styles/action-separator
:icon-opts styles/action-icon-opts}]
[members-list admin?]]]])))

View File

@ -1,181 +0,0 @@
(ns status-im.ui.screens.profile.styles
(:require [status-im.ui.components.styles :as styles]
[status-im.ui.components.colors :as colors])
(:require-macros [status-im.utils.styles :refer [defstyle]]))
(def profile
{:flex 1
:background-color colors/white
:flex-direction :column})
(def profile-form
{:background-color colors/white
:padding 16})
(defstyle profile-info-container
{:background-color colors/white})
(def profile-info-item-button
{:padding 16})
(def profile-badge
{:flex-direction :column
:justify-content :center
:align-items :center})
(def profile-badge-edit
{:flex-direction :column
:justify-content :center})
(def modal-menu
{:align-items :center})
(def edit-name-title
{:color colors/gray
:ios {:font-size 13
:letter-spacing -0.1}
:android {:font-size 12}})
(defstyle profile-name-text
{:padding-vertical 14
:font-size 15
:text-align :center
:ios {:letter-spacing -0.2}
:android {:color colors/black}})
(defstyle profile-name-input-text
{:font-size 15
:text-align :center
:flex 1
:ios {:letter-spacing -0.2
:height 46
:border-bottom-width 1
:border-bottom-color styles/color-light-gray3}
:android {:color colors/black
:border-bottom-width 2
:border-bottom-color styles/color-blue4}})
(def profile-badge-name-container
{:flex 1
:justify-content :center})
(def profile-activity-status-container
{:margin-top 4})
(defstyle profile-activity-status-text
{:color colors/gray
:ios {:font-size 14
:line-height 20
:letter-spacing -0.2}
:android {:font-size 15
:line-height 20}})
(defstyle profile-setting-item
{:flex-direction :row
:align-items :center
:padding-left 16
:ios {:height 73}
:android {:height 72}})
(defn profile-info-text-container [options]
{:flex 1
:padding-right (if options 16 40)})
(defstyle profile-settings-title
{:color colors/gray
:margin-left 16
:margin-top 18
:margin-bottom 20
:font-size 14
:ios {:letter-spacing -0.2}})
(defstyle profile-info-title
{:color colors/gray
:margin-left 16
:font-size 14
:ios {:letter-spacing -0.2}})
(defstyle profile-setting-text
{:ios {:font-size 17
:letter-spacing -0.2}
:android {:font-size 16
:color colors/black}})
(defstyle profile-setting-spacing
{:ios {:height 10}
:android {:height 7}})
(def profile-setting-text-empty
(merge profile-setting-text
{:color colors/gray}))
(def settings-item-separator
{:margin-left 16})
(defstyle settings-item
{:padding-horizontal 16
:flex-direction :row
:align-items :center
:background-color colors/white
:height 52})
(defstyle settings-item-text
{:flex 1
:flex-wrap :nowrap
:font-size 15
:ios {:letter-spacing -0.2}
:android {:color colors/black}})
(def settings-item-value
{:flex 2
:flex-wrap :nowrap
:text-align :right
:padding-right 10
:font-size 15
:color colors/gray})
(defstyle logout-text
(merge settings-item-text
{:color colors/red}))
(defstyle profile-name-input
{:color styles/text1-color
:ios {:font-size 17
:padding-bottom 0
:line-height 17
:letter-spacing -0.2}
:android {:font-size 16
:line-height 16
:padding-top 5
:height 30
:padding-bottom 0}})
(def network-info {:background-color :white})
(def share-contact-code
{:margin-horizontal 16
:flex-direction :row
:justify-content :space-between
:align-items :center
:height 42
:border-radius 8
:background-color styles/color-blue4-transparent})
(def share-contact-code-text-container
{:padding-left 16
:padding-bottom 1
:flex 0.9
:flex-direction :row
:justify-content :center
:align-items :center})
(def share-contact-code-text
{:color colors/blue
:font-size 15})
(def share-contact-icon-container
{:border-radius 50
:flex 0.1
:padding-right 5
:align-items :center
:justify-content :center})

View File

@ -1,51 +0,0 @@
(ns status-im.ui.screens.profile.subs
(:require [re-frame.core :refer [reg-sub subscribe]]
[clojure.string :as string]
[status-im.ui.screens.profile.db :refer [account-profile-keys]]))
(defn get-in-profile [profile current-account k]
(or (get profile k)
(get current-account k)))
(reg-sub :my-profile/get
:<- [:get-current-account]
:<- [:get :my-profile/profile]
(fn [[current-account profile] [_ k]]
(get-in-profile profile current-account k)))
(reg-sub :my-profile.drawer/get
:<- [:get-current-account]
:<- [:get :my-profile/drawer]
(fn [[current-account profile] [_ k]]
(get-in-profile profile current-account k)))
(reg-sub :my-profile/valid-name?
:<- [:get :my-profile/profile]
(fn [profile]
(get profile :valid-name? true)))
(reg-sub :my-profile.drawer/valid-name?
:<- [:get :my-profile/drawer]
(fn [profile]
(or (string/blank? (:name profile))
(get profile :valid-name? true))))
(reg-sub :my-profile/changed?
:<- [:get-current-account]
:<- [:get :my-profile/profile]
(fn [[current-account profile]]
(not= (select-keys current-account account-profile-keys)
(select-keys profile account-profile-keys))))
(reg-sub :my-profile.drawer/save-event
:<- [:get-current-account]
:<- [:get :my-profile/drawer]
(fn [[{:keys [name status]} {new-name :name new-status :status}]]
(cond
(and new-name
(not= name new-name))
:my-profile.drawer/save-name
(and status
(not= status new-status))
:my-profile.drawer/save-status)))

View File

@ -0,0 +1,37 @@
(ns status-im.ui.screens.profile.user.styles
(:require-macros [status-im.utils.styles :refer [defstyle]])
(:require [status-im.ui.components.colors :as colors]
[status-im.ui.screens.profile.components.styles :as profile.components.styles]
[status-im.ui.components.styles :as components.styles]))
(def share-contact-code
{:margin-horizontal 16
:flex-direction :row
:justify-content :space-between
:align-items :center
:height 42
:border-radius components.styles/border-radius
:background-color colors/blue-transparent})
(def share-contact-code-text-container
{:padding-left 16
:padding-bottom 1
:flex 0.9
:flex-direction :row
:justify-content :center
:align-items :center})
(def share-contact-code-text
{:color colors/blue
:font-size 15})
(def share-contact-icon-container
{:border-radius 50
:flex 0.1
:padding-right 5
:align-items :center
:justify-content :center})
(defstyle logout-text
(merge profile.components.styles/settings-item-text
{:color colors/red}))

View File

@ -0,0 +1,137 @@
(ns status-im.ui.screens.profile.user.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [status-im.ui.screens.profile.user.styles :as styles]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.react :as react]
[re-frame.core :as re-frame]
[status-im.ui.components.common.styles :as common.styles]
[status-im.ui.components.styles :as components.styles]
[status-im.i18n :as i18n]
[status-im.ui.components.colors :as colors]
[status-im.utils.utils :as utils]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.list-selection :as list-selection]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
[status-im.utils.config :as config]
[status-im.utils.platform :as platform]
[status-im.ui.screens.profile.components.views :as profile.components]
[status-im.ui.screens.profile.components.styles :as profile.components.styles]
[status-im.ui.components.action-button.styles :as action-button.styles]
[status-im.protocol.core :as protocol]))
(defn my-profile-toolbar []
[toolbar/toolbar {}
nil
[toolbar/content-title ""]
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:my-profile/start-editing-profile])}
[react/view
[react/text {:style common.styles/label-action-text
:uppercase? components.styles/uppercase?} (i18n/label :t/edit)]]]])
(defn my-profile-edit-toolbar []
[toolbar/toolbar {}
nil
[toolbar/content-title ""]
[toolbar/default-done {:handler #(re-frame/dispatch [:my-profile/save-profile])
:icon :icons/ok
:icon-opts {:color colors/blue}}]])
(def profile-icon-options
[{:label (i18n/label :t/image-source-gallery)
:action #(re-frame/dispatch [:my-profile/update-picture])}
{:label (i18n/label :t/image-source-make-photo)
:action (fn []
(re-frame/dispatch [:request-permissions
[:camera :write-external-storage]
#(re-frame/dispatch [:navigate-to :profile-photo-capture])
#(utils/show-popup (i18n/label :t/error)
(i18n/label :t/camera-access-error))]))}])
(defn qr-viewer-toolbar [label value]
[toolbar/toolbar {}
[toolbar/default-done {:icon-opts {:color colors/black}}]
[toolbar/content-title label]
[toolbar/actions [{:icon :icons/share
:icon-opts {:color :black}
:handler #(list-selection/open-share {:message value})}]]])
(defview qr-viewer []
(letsubs [{:keys [value contact]} [:get :qr-modal]]
[react/view {:flex-grow 1
:flex-direction :column}
[status-bar/status-bar {:type :modal}]
[qr-viewer-toolbar (:name contact) value]
[qr-code-viewer/qr-code-viewer {}
value (i18n/label :t/qr-code-public-key-hint) (str value)]]))
(defn- show-qr [contact source value]
#(re-frame/dispatch [:navigate-to :profile-qr-viewer {:contact contact
:source source
:value value}]))
(defn share-contact-code [current-account public-key]
[react/touchable-highlight {:on-press (show-qr current-account :public-key public-key)}
[react/view styles/share-contact-code
[react/view styles/share-contact-code-text-container
[react/text {:style styles/share-contact-code-text
:uppercase? components.styles/uppercase?}
(i18n/label :t/share-contact-code)]]
[react/view styles/share-contact-icon-container
[vector-icons/icon :icons/qr {:color colors/blue}]]]])
(defn my-profile-settings [{:keys [network networks]}]
[react/view
[profile.components/settings-title (i18n/label :t/settings)]
[profile.components/settings-item :t/main-currency "USD" #() false]
[profile.components/settings-item-separator]
[profile.components/settings-item :t/notifications "" #() true]
[profile.components/settings-item-separator]
[profile.components/settings-item :t/network (get-in networks [network :name])
#(re-frame/dispatch [:navigate-to :network-settings]) true]
(when config/offline-inbox-enabled?
[profile.components/settings-item-separator])
(when config/offline-inbox-enabled?
[profile.components/settings-item :t/offline-messaging-settings ""
#(re-frame/dispatch [:navigate-to :offline-messaging-settings]) true])])
(defn navigate-to-accounts []
;; TODO(rasom): probably not the best place for this call
(protocol/stop-whisper!)
(re-frame/dispatch [:navigate-to :accounts]))
(defn handle-logout []
(utils/show-confirmation (i18n/label :t/logout-title)
(i18n/label :t/logout-are-you-sure)
(i18n/label :t/logout) navigate-to-accounts))
(defn logout []
[react/view {}
[react/touchable-highlight
{:on-press handle-logout}
[react/view profile.components.styles/settings-item
[react/text {:style styles/logout-text
:font (if platform/android? :medium :default)}
(i18n/label :t/logout)]]]])
(defview my-profile []
(letsubs [{:keys [public-key] :as current-account} [:get-current-account]
editing? [:get :my-profile/editing?]
changed-account [:get :my-profile/profile]]
(let [shown-account (merge current-account changed-account)]
[react/view profile.components.styles/profile
(if editing?
[my-profile-edit-toolbar]
[my-profile-toolbar])
[react/scroll-view
[react/view profile.components.styles/profile-form
[profile.components/profile-header shown-account editing? true profile-icon-options :my-profile/update-name]]
[react/view action-button.styles/actions-list
[share-contact-code current-account public-key]]
[react/view profile.components.styles/profile-info-container
[my-profile-settings current-account]]
[logout]]])))

View File

@ -1,315 +0,0 @@
(ns status-im.ui.screens.profile.views
(: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.ui.components.action-button.action-button :as action-button]
[status-im.ui.components.action-button.styles :as action-button.styles]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[status-im.ui.components.common.common :as common]
[status-im.ui.components.common.styles :as common.styles]
[status-im.ui.components.list-selection :as list-selection]
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
[status-im.ui.components.react :as react]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.components.styles :as component.styles]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.toolbar.actions :as actions]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.screens.profile.styles :as styles]
[status-im.ui.components.colors :as colors]
[status-im.utils.utils :as utils]
[status-im.utils.core :refer [hash-tag?]]
[status-im.utils.datetime :as time]
[status-im.utils.config :as config]
[status-im.utils.platform :as platform]
[status-im.protocol.core :as protocol]))
(defn my-profile-toolbar []
[toolbar/toolbar {}
nil
[toolbar/content-title ""]
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:my-profile/start-editing-profile])}
[react/view
[react/text {:style common.styles/label-action-text
:uppercase? component.styles/uppercase?} (i18n/label :t/edit)]]]])
(defn my-profile-edit-toolbar []
[toolbar/toolbar {}
nil
[toolbar/content-title ""]
[toolbar/default-done {:handler #(re-frame/dispatch [:my-profile/save-profile])
:icon :icons/ok
:icon-opts {:color colors/blue}}]])
(defn profile-toolbar [contact]
[toolbar/toolbar {}
toolbar/default-nav-back
[toolbar/content-title ""]
[toolbar/actions
(when (and (not (:pending? contact))
(not (:unremovable? contact)))
[(actions/opts [{:action #(re-frame/dispatch [:hide-contact contact])
:label (i18n/label :t/remove-from-contacts)}])])]])
(defn online-text [last-online]
(let [last-online-date (time/to-date last-online)
now-date (time/now)]
(if (and (pos? last-online)
(<= last-online-date now-date))
(time/time-ago last-online-date)
(i18n/label :t/active-unknown))))
(defn profile-badge [{:keys [name] :as contact}]
[react/view styles/profile-badge
[chat-icon.screen/my-profile-icon {:account contact
:edit? false}]
[react/view styles/profile-badge-name-container
[react/text {:style styles/profile-name-text
:number-of-lines 1}
name]]])
(defn profile-name-input [name]
[react/view
[react/text-input
{:style styles/profile-name-input-text
:placeholder ""
:default-value name
:auto-focus true
:on-focus #(re-frame/dispatch [:my-profile/edit-profile])
:on-change-text #(re-frame/dispatch [:my-profile/update-name %])}]])
(def profile-icon-options
[{:label (i18n/label :t/image-source-gallery)
:action #(re-frame/dispatch [:my-profile/update-picture])}
{:label (i18n/label :t/image-source-make-photo)
:action (fn []
(re-frame/dispatch [:request-permissions
[:camera :write-external-storage]
#(re-frame/dispatch [:navigate-to :profile-photo-capture])
#(utils/show-popup (i18n/label :t/error)
(i18n/label :t/camera-access-error))]))}])
(defn profile-badge-edit [{:keys [name] :as account}]
[react/view styles/profile-badge-edit
[react/touchable-highlight {:on-press #(list-selection/show {:title (i18n/label :t/image-source-title)
:options profile-icon-options})}
[react/view styles/modal-menu
[chat-icon.screen/my-profile-icon {:account account
:edit? true}]]]
[react/view styles/profile-badge-name-container
[profile-name-input name]]])
(defn profile-actions [{:keys [pending? whisper-identity dapp?]} chat-id]
[react/view action-button.styles/actions-list
(if pending?
[action-button/action-button {:label (i18n/label :t/add-to-contacts)
:icon :icons/add
:icon-opts {:color :blue}
:on-press #(re-frame/dispatch [:add-pending-contact chat-id])}]
[action-button/action-button-disabled {:label (i18n/label :t/in-contacts) :icon :icons/ok}])
[action-button/action-separator]
[action-button/action-button {:label (i18n/label :t/start-conversation)
:icon :icons/chats
:icon-opts {:color :blue}
:on-press #(re-frame/dispatch [:start-chat whisper-identity {:navigation-replace? true}])}]
(when-not dapp?
[react/view
[action-button/action-separator]
[action-button/action-button {:label (i18n/label :t/send-transaction)
:icon :icons/arrow-right
:icon-opts {:color :blue}
:on-press #(re-frame/dispatch [:profile/send-transaction chat-id whisper-identity])}]])])
(defn profile-info-item [{:keys [label value options text-mode empty-value? accessibility-label]}]
[react/view styles/profile-setting-item
[react/view (styles/profile-info-text-container options)
[react/text {:style styles/profile-info-title}
label]
[react/view styles/profile-setting-spacing]
[react/text {:style (if empty-value?
styles/profile-setting-text-empty
styles/profile-setting-text)
:number-of-lines 1
:ellipsizeMode text-mode
:accessibility-label accessibility-label}
value]]
(when options
[react/touchable-highlight {:on-press #(list-selection/show {:options options})}
[react/view styles/modal-menu
[vector-icons/icon :icons/options {:container-style styles/profile-info-item-button}]]])])
(defn- toolbar [label value]
[toolbar/toolbar {}
[toolbar/default-done {:icon-opts {:color colors/black}}]
[toolbar/content-title label]
[toolbar/actions [{:icon :icons/share
:icon-opts {:color :black}
:handler #(list-selection/open-share {:message value})}]]])
(defview qr-viewer []
(letsubs [{:keys [value contact]} [:get :qr-modal]]
[react/view {:flex-grow 1
:flex-direction :column}
[status-bar/status-bar {:type :modal}]
[toolbar (:name contact) value]
[qr-code-viewer/qr-code-viewer {}
value (i18n/label :t/qr-code-public-key-hint) (str value)]]))
(defn- show-qr [contact source value]
#(re-frame/dispatch [:navigate-to :profile-qr-viewer {:contact contact
:source source
:value value}]))
(defn profile-options [text]
(into []
(when text
(list-selection/share-options text))))
(defn profile-info-address-item [address]
[profile-info-item
{:label (i18n/label :t/address)
:action address
:options (profile-options address)
:text-mode :middle
:accessibility-label :profile-address
:value address}])
(defn profile-info-public-key-item [whisper-identity]
[profile-info-item
{:label (i18n/label :t/public-key)
:action whisper-identity
:options (profile-options whisper-identity)
:text-mode :middle
:accessibility-label :profile-public-key
:value whisper-identity}])
(defn settings-item-separator []
[common/separator styles/settings-item-separator])
(defn tag-view [tag]
[react/text {:style {:color colors/blue}
:font :medium}
(str tag " ")])
(defn colorize-status-hashtags [status]
(for [[i status] (map-indexed vector (string/split status #" "))]
(if (hash-tag? status)
^{:key (str "item-" i)}
[tag-view status]
^{:key (str "item-" i)}
(str status " "))))
(defn settings-title [title]
[react/text {:style styles/profile-settings-title}
title])
(defn settings-item [label-kw value action-fn active?]
[react/touchable-highlight
{:on-press action-fn
:disabled (not active?)}
[react/view styles/settings-item
[react/text {:style styles/settings-item-text}
(i18n/label label-kw)]
(when-not (string/blank? value)
[react/text {:style styles/settings-item-value
:number-of-lines 1
:uppercase? component.styles/uppercase?}
value])
(when active?
[vector-icons/icon :icons/forward {:color colors/gray}])]])
(defn profile-info [{:keys [whisper-identity address]}]
[react/view
[profile-info-address-item address]
[settings-item-separator]
[profile-info-public-key-item whisper-identity]])
(defn navigate-to-accounts []
;; TODO(rasom): probably not the best place for this call
(protocol/stop-whisper!)
(re-frame/dispatch [:navigate-to :accounts]))
(defn handle-logout []
(utils/show-confirmation (i18n/label :t/logout-title)
(i18n/label :t/logout-are-you-sure)
(i18n/label :t/logout) navigate-to-accounts))
(defn logout []
[react/view {}
[react/touchable-highlight
{:on-press handle-logout}
[react/view styles/settings-item
[react/text {:style styles/logout-text
:font (if platform/android? :medium :default)}
(i18n/label :t/logout)]]]])
(defn my-profile-settings [{:keys [network networks]}]
[react/view
[settings-title (i18n/label :t/settings)]
[settings-item :t/main-currency "USD" #() false]
[settings-item-separator]
[settings-item :t/notifications "" #() true]
[settings-item-separator]
[settings-item :t/network (get-in networks [network :name])
#(re-frame/dispatch [:navigate-to :network-settings]) true]
(when config/offline-inbox-enabled?
[settings-item-separator])
(when config/offline-inbox-enabled?
[settings-item :t/offline-messaging-settings ""
#(re-frame/dispatch [:navigate-to :offline-messaging-settings]) true])])
(defn network-info []
[react/view styles/network-info
[common/network-info]
[common/separator]])
(defn share-contact-code [current-account public-key]
[react/touchable-highlight {:on-press (show-qr current-account :public-key public-key)}
[react/view styles/share-contact-code
[react/view styles/share-contact-code-text-container
[react/text {:style styles/share-contact-code-text
:uppercase? component.styles/uppercase?}
(i18n/label :t/share-contact-code)]]
[react/view styles/share-contact-icon-container
[vector-icons/icon :icons/qr {:color colors/blue}]]]])
(defview my-profile []
(letsubs [{:keys [public-key] :as current-account} [:get-current-account]
editing? [:get :my-profile/editing?]
changed-account [:get :my-profile/profile]]
[react/view styles/profile
(if editing?
[my-profile-edit-toolbar]
[my-profile-toolbar])
[react/scroll-view
[react/view styles/profile-form
(if editing?
[profile-badge-edit (merge current-account changed-account)]
[profile-badge current-account])]
[react/view action-button.styles/actions-list
[share-contact-code current-account public-key]]
[react/view styles/profile-info-container
[my-profile-settings current-account]]
[logout]]]))
(defview profile []
(letsubs [contact [:contact]
chat-id [:get :current-chat-id]]
[react/view styles/profile
[status-bar/status-bar]
[profile-toolbar contact]
[network-info]
[react/scroll-view
[react/view styles/profile-form
[profile-badge contact]]
[common/form-spacer]
[profile-actions contact chat-id]
[common/form-spacer]
[react/view styles/profile-info-container
[profile-info contact]
[common/bottom-shadow]]]]))

View File

@ -8,7 +8,6 @@
status-im.ui.screens.discover.subs status-im.ui.screens.discover.subs
status-im.ui.screens.contacts.subs status-im.ui.screens.contacts.subs
status-im.ui.screens.group.subs status-im.ui.screens.group.subs
status-im.ui.screens.profile.subs
status-im.ui.screens.wallet.subs status-im.ui.screens.wallet.subs
status-im.ui.screens.wallet.request.subs status-im.ui.screens.wallet.request.subs
status-im.ui.screens.wallet.send.subs status-im.ui.screens.wallet.send.subs

View File

@ -19,15 +19,15 @@
[status-im.ui.screens.qr-scanner.views :refer [qr-scanner]] [status-im.ui.screens.qr-scanner.views :refer [qr-scanner]]
[status-im.ui.screens.group.views :refer [new-group edit-contact-group]] [status-im.ui.screens.group.views :refer [new-group]]
[status-im.ui.screens.group.chat-settings.views :refer [chat-group-settings]] [status-im.ui.screens.group.edit-contacts.views :refer [edit-contact-group-contact-list]]
[status-im.ui.screens.group.edit-contacts.views :refer [edit-contact-group-contact-list
edit-chat-group-contact-list]]
[status-im.ui.screens.group.add-contacts.views :refer [contact-toggle-list [status-im.ui.screens.group.add-contacts.views :refer [contact-toggle-list
add-contacts-toggle-list add-contacts-toggle-list
add-participants-toggle-list]] add-participants-toggle-list]]
[status-im.ui.screens.profile.views :as profile] [status-im.ui.screens.profile.user.views :as profile.user]
[status-im.ui.screens.profile.contact.views :as profile.contact]
[status-im.ui.screens.profile.group-chat.views :as profile.group-chat]
[status-im.ui.screens.profile.photo-capture.views :refer [profile-photo-capture]] [status-im.ui.screens.profile.photo-capture.views :refer [profile-photo-capture]]
[status-im.ui.screens.wallet.send.views :refer [send-transaction send-transaction-modal]] [status-im.ui.screens.wallet.send.views :refer [send-transaction send-transaction-modal]]
[status-im.ui.screens.wallet.choose-recipient.views :refer [choose-recipient]] [status-im.ui.screens.wallet.choose-recipient.views :refer [choose-recipient]]
@ -144,18 +144,16 @@
:wallet-request-assets wallet.components/request-assets :wallet-request-assets wallet.components/request-assets
:new add-new :new add-new
:new-group new-group :new-group new-group
:edit-contact-group edit-contact-group
:chat-group-settings chat-group-settings
:add-contacts-toggle-list add-contacts-toggle-list :add-contacts-toggle-list add-contacts-toggle-list
:add-participants-toggle-list add-participants-toggle-list :add-participants-toggle-list add-participants-toggle-list
:edit-group-contact-list edit-contact-group-contact-list :edit-group-contact-list edit-contact-group-contact-list
:edit-chat-group-contact-list edit-chat-group-contact-list
:new-public-chat new-public-chat :new-public-chat new-public-chat
:contact-toggle-list contact-toggle-list :contact-toggle-list contact-toggle-list
:new-chat new-chat :new-chat new-chat
:qr-scanner qr-scanner :qr-scanner qr-scanner
:chat chat :chat chat
:profile profile/profile :profile profile.contact/profile
:group-chat-profile profile.group-chat/group-chat-profile
:discover-all-recent discover-recent/discover-all-recent :discover-all-recent discover-recent/discover-all-recent
:discover-all-popular-hashtags discover-popular/discover-all-popular-hashtags :discover-all-popular-hashtags discover-popular/discover-all-popular-hashtags
:discover-search-results discover-search/discover-search-results :discover-search-results discover-search/discover-search-results
@ -173,7 +171,7 @@
:recent-recipients recent-recipients :recent-recipients recent-recipients
:recipient-qr-code recipient-qr-code :recipient-qr-code recipient-qr-code
:contact-code contact-code :contact-code contact-code
:profile-qr-viewer profile/qr-viewer :profile-qr-viewer profile.user/qr-viewer
(throw (str "Unknown view: " current-view))) (throw (str "Unknown view: " current-view)))
main-screen-view (create-main-screen-view current-view)] main-screen-view (create-main-screen-view current-view)]
[main-screen-view common-styles/flex [main-screen-view common-styles/flex

View File

@ -30,15 +30,6 @@
[react/text {:style styles/total-balance-currency} (i18n/label :t/usd-currency)]] [react/text {:style styles/total-balance-currency} (i18n/label :t/usd-currency)]]
[react/text {:style styles/total-value} (i18n/label :t/wallet-total-value)]]]) [react/text {:style styles/total-value} (i18n/label :t/wallet-total-value)]]])
(defn- render-action [{:keys [label icon action]}]
[react/touchable-highlight {:on-press action}
[react/view
[list/item
[list/item-icon {:icon icon :style styles/action :icon-opts {:color :white}}]
[list/item-primary-only {:style styles/action-label}
label]
list/item-icon-forward]]])
(def actions (def actions
[{:label (i18n/label :t/send-transaction) [{:label (i18n/label :t/send-transaction)
:icon :icons/arrow-right :icon :icons/arrow-right
@ -50,13 +41,6 @@
:icon :icons/transaction-history :icon :icons/transaction-history
:action #(re-frame/dispatch [:navigate-to :transactions-history])}]) :action #(re-frame/dispatch [:navigate-to :transactions-history])}])
(defn- action-section []
[react/view styles/action-section
[list/flat-list
{:separator (when platform/ios? [react/view styles/action-separator])
:data actions
:render-fn render-action}]])
(defn- render-asset [{:keys [symbol icon decimals amount]}] (defn- render-asset [{:keys [symbol icon decimals amount]}]
[react/view [react/view
[list/item [list/item
@ -97,5 +81,6 @@
[toolbar-view] [toolbar-view]
[react/view components.styles/flex [react/view components.styles/flex
[total-section portfolio-value] [total-section portfolio-value]
[action-section] [list/action-list actions
{:container-style styles/action-section}]
[asset-section network balance visible-tokens prices-loading? balance-loading?]]])) [asset-section network balance visible-tokens prices-loading? balance-loading?]]]))

View File

@ -24,46 +24,3 @@
(rf/reg-fx ::events/init-store #()) (rf/reg-fx ::events/init-store #())
(rf/reg-fx ::account-events/save-account #())) (rf/reg-fx ::account-events/save-account #()))
(deftest profile-edit-events
(run-test-sync
(test-fixtures)
(let [accounts (rf/subscribe [:get-accounts])
address (:address new-account)]
(rf/dispatch [:initialize-db])
(rf/dispatch [:add-account new-account])
(rf/dispatch [:initialize-account-db address])
(testing "Setting status from edit profile screen"
(let [new-status "New edit profile status"]
(is (= (:status new-account) (-> @accounts
(get address)
:status)))
(rf/dispatch [:my-profile/edit-profile :edit-status])
(rf/dispatch [:my-profile/update-status new-status])
(rf/dispatch [:my-profile/save-profile])
(is (= new-status (-> @accounts
(get address)
:status)))))
(testing "Setting status from drawer"
(let [new-status "New drawer status"]
(rf/dispatch [:my-profile.drawer/edit-status])
(rf/dispatch [:my-profile.drawer/update-status new-status])
(rf/dispatch [:my-profile.drawer/save-status])
(is (= new-status (-> @accounts
(get address)
:status))))))))
(deftest test-status-change
(let [fx {:db {}}]
(is (= (profile-events/status-change fx {:old-status "this is old status"
:status "this is new and CHANGED status"})
{:db {}
:dispatch-n [[:broadcast-status "this is new and CHANGED status"]]}))
(is (= (profile-events/status-change fx {:old-status "this is old status"
:status "this is new and #changed status"})
{:db {}
:dispatch-n [[:broadcast-status "this is new and #changed status"]]}))
(is (= (profile-events/status-change fx {:old-status "this is old status"
:status "this is old status"})
{:db {}}))))