mirror of
https://github.com/status-im/status-mobile.git
synced 2025-01-12 17:54:32 +00:00
[ISSUE #1840] Migrated to FlatList
This commit is contained in:
parent
558fc8fd62
commit
7c8aa75724
@ -13,7 +13,6 @@
|
||||
},
|
||||
"modules": [
|
||||
"react-native-contacts",
|
||||
"react-native-invertible-scroll-view",
|
||||
"awesome-phonenumber",
|
||||
"realm",
|
||||
"react-native-i18n",
|
||||
|
11
package-lock.json
generated
11
package-lock.json
generated
@ -7586,17 +7586,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-native-image-resizer/-/react-native-image-resizer-1.0.0.tgz",
|
||||
"integrity": "sha1-1H4UlDw3k44of71jnk23zrf9iRc="
|
||||
},
|
||||
"react-native-invertible-scroll-view": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-invertible-scroll-view/-/react-native-invertible-scroll-view-1.1.0.tgz",
|
||||
"integrity": "sha1-v9UKP11myhJjm3x6mETO3dHRaJA=",
|
||||
"requires": {
|
||||
"create-react-class": "15.6.2",
|
||||
"prop-types": "15.6.0",
|
||||
"react-clone-referenced-element": "1.0.1",
|
||||
"react-native-scrollable-mixin": "1.0.1"
|
||||
}
|
||||
},
|
||||
"react-native-level-fs": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-level-fs/-/react-native-level-fs-3.0.0.tgz",
|
||||
|
@ -19,7 +19,6 @@
|
||||
(def image-crop-picker (js/require "react-native-image-crop-picker"))
|
||||
(def image-resizer (js/require "react-native-image-resizer"))
|
||||
(def instabug (js/require "instabug-reactnative"))
|
||||
(def invertible-scroll-view (js/require "react-native-invertible-scroll-view"))
|
||||
(def linear-gradient (js/require "react-native-linear-gradient"))
|
||||
(def mapbox-gl (js/require "react-native-mapbox-gl"))
|
||||
(def nfc (js/require "nfc-react-native"))
|
||||
|
@ -6,5 +6,5 @@
|
||||
:margin-bottom 0})
|
||||
|
||||
(def contacts-list
|
||||
{:backgroundColor common/color-light-gray})
|
||||
{:background-color common/color-light-gray})
|
||||
|
||||
|
@ -2,75 +2,72 @@
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [re-frame.core :refer [dispatch]]
|
||||
[status-im.ui.components.common.common :as common]
|
||||
[status-im.ui.components.renderers.renderers :as renderers]
|
||||
[status-im.ui.components.action-button.action-button :refer [action-button
|
||||
action-separator]]
|
||||
[status-im.ui.components.action-button.styles :refer [actions-list]]
|
||||
[status-im.ui.components.react :refer [view text list-view list-item]]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.contact.contact :refer [contact-view]]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.status-bar.view :refer [status-bar]]
|
||||
[status-im.ui.components.toolbar.view :refer [toolbar-with-search]]
|
||||
[status-im.ui.components.drawer.view :refer [drawer-view]]
|
||||
[status-im.ui.components.drawer.view :as drawer]
|
||||
[status-im.chat.new-chat.styles :as styles]
|
||||
[status-im.utils.listview :as lw]
|
||||
[status-im.i18n :refer [label]]))
|
||||
[status-im.i18n :as i18n]))
|
||||
|
||||
(defn options-list []
|
||||
[view actions-list
|
||||
[action-button {:label (label :t/new-group-chat)
|
||||
[react/view actions-list
|
||||
[action-button {:label (i18n/label :t/new-group-chat)
|
||||
:icon :icons/group-big
|
||||
:icon-opts {:color :blue}
|
||||
:on-press #(dispatch [:open-contact-toggle-list :chat-group])}]
|
||||
[action-separator]
|
||||
[action-button {:label (label :t/new-public-group-chat)
|
||||
[action-button {:label (i18n/label :t/new-public-group-chat)
|
||||
:icon :icons/public
|
||||
:icon-opts {:color :blue}
|
||||
:on-press #(dispatch [:navigate-to :new-public-chat])}]
|
||||
[action-separator]
|
||||
[action-button {:label (label :t/add-new-contact)
|
||||
[action-button {:label (i18n/label :t/add-new-contact)
|
||||
:icon :icons/add
|
||||
:icon-opts {:color :blue}
|
||||
:on-press #(dispatch [:navigate-to :new-contact])}]])
|
||||
|
||||
(defn contact-list-row []
|
||||
(fn [row _ _]
|
||||
(list-item ^{:key row}
|
||||
[contact-view {:contact row
|
||||
:on-press #(dispatch [:open-chat-with-contact %])}])))
|
||||
(defn contact-list-row [contact]
|
||||
[contact-view {:contact contact
|
||||
:on-press #(dispatch [:open-chat-with-contact %])}])
|
||||
|
||||
(defview new-chat-toolbar []
|
||||
(letsubs [show-search [:get-in [:toolbar-search :show]]
|
||||
search-text [:get-in [:toolbar-search :text]]]
|
||||
[view
|
||||
[react/view
|
||||
[status-bar]
|
||||
(toolbar-with-search
|
||||
{:show-search? (= show-search :contact-list)
|
||||
:search-text search-text
|
||||
:search-key :contact-list
|
||||
:title (label :t/contacts-group-new-chat)
|
||||
:search-placeholder (label :t/search-for)})]))
|
||||
:title (i18n/label :t/contacts-group-new-chat)
|
||||
:search-placeholder (i18n/label :t/search-for)})]))
|
||||
|
||||
(defn- header [contacts]
|
||||
[react/view
|
||||
[options-list]
|
||||
[common/bottom-shadow]
|
||||
[common/form-title (i18n/label :t/choose-from-contacts)
|
||||
{:count-value (count contacts)}]
|
||||
[common/list-header]])
|
||||
|
||||
(defview new-chat []
|
||||
(letsubs [contacts [:all-added-group-contacts-filtered]
|
||||
params [:get :contacts/click-params]]
|
||||
[drawer-view
|
||||
[view styles/contacts-list-container
|
||||
[drawer/drawer-view
|
||||
[react/view styles/contacts-list-container
|
||||
[new-chat-toolbar]
|
||||
(when contacts
|
||||
[list-view {:dataSource (lw/to-datasource contacts)
|
||||
:enableEmptySections true
|
||||
:renderRow (contact-list-row)
|
||||
:bounces false
|
||||
:keyboardShouldPersistTaps :always
|
||||
:renderHeader #(list-item
|
||||
[view
|
||||
[options-list]
|
||||
[common/bottom-shadow]
|
||||
[common/form-title (label :t/choose-from-contacts)
|
||||
{:count-value (count contacts)}]
|
||||
[common/list-header]])
|
||||
:renderSeparator renderers/list-separator-renderer
|
||||
:renderFooter #(list-item [view
|
||||
[common/list-footer]
|
||||
[common/bottom-shadow]])
|
||||
:style styles/contacts-list}])]]))
|
||||
[list/flat-list {:style styles/contacts-list
|
||||
:data contacts
|
||||
:render-fn contact-list-row
|
||||
:bounces false
|
||||
:keyboardShouldPersistTaps :always
|
||||
:header (header contacts)
|
||||
:footer [react/view
|
||||
[common/list-footer]
|
||||
[common/bottom-shadow]]}])]]))
|
||||
|
@ -1,16 +1,10 @@
|
||||
(ns status-im.chat.screen
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[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.chat-icon.screen :as chat-icon-screen]
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.chat.styles.screen :as style]
|
||||
[status-im.utils.listview :as listview]
|
||||
[status-im.utils.datetime :as time]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.ui.components.invertible-scroll-view :as scroll-view]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[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]
|
||||
@ -18,9 +12,15 @@
|
||||
[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.ui.components.list.views :as list]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[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.animation :as anim]
|
||||
[status-im.ui.components.animation :as anim]
|
||||
[status-im.ui.components.sync-state.offline :as offline]
|
||||
[clojure.string :as string]))
|
||||
[status-im.ui.components.toolbar.view :as toolbar]))
|
||||
|
||||
(defview chat-icon []
|
||||
(letsubs [{:keys [chat-id group-chat name color]} [:get-current-chat]]
|
||||
@ -65,26 +65,25 @@
|
||||
|
||||
(defmethod message-row :datemark
|
||||
[{{:keys [value]} :row}]
|
||||
(react/list-item [message-datemark/chat-datemark value]))
|
||||
[message-datemark/chat-datemark value])
|
||||
|
||||
(defmethod message-row :default
|
||||
[{:keys [group-chat current-public-key row]}]
|
||||
(react/list-item [message/chat-message (assoc row
|
||||
:group-chat group-chat
|
||||
:current-public-key current-public-key)]))
|
||||
[message/chat-message (assoc row
|
||||
:group-chat group-chat
|
||||
:current-public-key current-public-key)])
|
||||
|
||||
(defview messages-view [chat-id group-chat]
|
||||
(letsubs [messages [:get-chat-messages chat-id]
|
||||
current-public-key [:get-current-public-key]]
|
||||
[react/list-view {:renderRow (fn [row _ index]
|
||||
(message-row {:group-chat group-chat
|
||||
:current-public-key current-public-key
|
||||
:row row}))
|
||||
:renderScrollComponent #(scroll-view/invertible-scroll-view (js->clj %))
|
||||
:onEndReached #(re-frame/dispatch [:load-more-messages])
|
||||
:enableEmptySections true
|
||||
:keyboardShouldPersistTaps (if platform/android? :always :handled)
|
||||
:dataSource (listview/to-datasource-inverted messages)}]))
|
||||
[list/flat-list {:data messages
|
||||
:render-fn #(message-row {:group-chat group-chat
|
||||
:current-public-key current-public-key
|
||||
:row %1})
|
||||
:inverted true
|
||||
:onEndReached #(re-frame/dispatch [:load-more-messages])
|
||||
:enableEmptySections true
|
||||
:keyboardShouldPersistTaps (if platform/android? :always :handled)}]))
|
||||
|
||||
(defview chat []
|
||||
(letsubs [{:keys [chat-id group-chat input-text]} [:get-current-chat]
|
||||
|
@ -1,40 +1,33 @@
|
||||
(ns status-im.chat.views.api.choose-contact
|
||||
(:require-macros [status-im.utils.views :refer [defview]])
|
||||
(:require [reagent.core :as r]
|
||||
[re-frame.core :refer [dispatch subscribe]]
|
||||
[status-im.ui.components.react :refer [view
|
||||
text
|
||||
list-view
|
||||
list-item]]
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.ui.components.contact.contact :refer [contact-view]]
|
||||
[status-im.ui.components.renderers.renderers :as renderers]
|
||||
[status-im.utils.listview :as lw]))
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]))
|
||||
|
||||
(defn render-row [arg-index bot-db-key]
|
||||
(fn [contact _ _]
|
||||
(list-item
|
||||
^{:key contact}
|
||||
[contact-view {:contact contact
|
||||
:on-press #(dispatch
|
||||
(defn- render-contact [arg-index bot-db-key]
|
||||
(fn [contact]
|
||||
[contact-view {:contact contact
|
||||
:on-press #(re-frame/dispatch
|
||||
[:set-contact-as-command-argument {:arg-index arg-index
|
||||
:bot-db-key bot-db-key
|
||||
:contact contact}])}])))
|
||||
:contact contact}])}]))
|
||||
|
||||
|
||||
(defview choose-contact-view [{title :title
|
||||
arg-index :index
|
||||
bot-db-key :bot-db-key}]
|
||||
[contacts [:contacts-filtered :people-in-current-chat]]
|
||||
[view {:flex 1}
|
||||
[text {:style {:font-size 14
|
||||
:color "rgb(147, 155, 161)"
|
||||
:padding-top 12
|
||||
:padding-left 16
|
||||
:padding-right 16
|
||||
:padding-bottom 12}}
|
||||
[react/view {:flex 1}
|
||||
[react/text {:style {:font-size 14
|
||||
:color "rgb(147, 155, 161)"
|
||||
:padding-top 12
|
||||
:padding-left 16
|
||||
:padding-right 16
|
||||
:padding-bottom 12}}
|
||||
title]
|
||||
[list-view {:dataSource (lw/to-datasource contacts)
|
||||
:enableEmptySections true
|
||||
:renderRow (render-row arg-index bot-db-key)
|
||||
:bounces false
|
||||
:keyboardShouldPersistTaps :always
|
||||
:renderSeparator renderers/list-separator-renderer}]])
|
||||
[list/flat-list {:data contacts
|
||||
:render-fn (render-contact arg-index bot-db-key)
|
||||
:enableEmptySections true
|
||||
:keyboardShouldPersistTaps :always
|
||||
:bounces false}]])
|
||||
|
@ -1,23 +1,15 @@
|
||||
(ns status-im.chat.views.bottom-info
|
||||
(:require-macros [status-im.utils.views :refer [defview]])
|
||||
(:require [re-frame.core :refer [subscribe dispatch]]
|
||||
[reagent.core :as r]
|
||||
[status-im.ui.components.react :refer [view
|
||||
animated-view
|
||||
image
|
||||
text
|
||||
icon
|
||||
touchable-highlight
|
||||
list-view
|
||||
list-item]]
|
||||
[status-im.ui.components.chat-icon.screen :refer [chat-icon-view-menu-item]]
|
||||
[status-im.chat.styles.screen :as st]
|
||||
[status-im.i18n :refer [label label-pluralize message-status-label]]
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[clojure.string :as string]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.chat.styles.screen :as styles]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.animation :as anim]
|
||||
[status-im.utils.utils :refer [truncate-str]]
|
||||
[status-im.utils.identicon :refer [identicon]]
|
||||
[status-im.utils.listview :as lw]
|
||||
[clojure.string :as str]))
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im.utils.identicon :as identicon]))
|
||||
|
||||
(defn- container-animation-logic [{:keys [to-value val]}]
|
||||
(fn [_]
|
||||
@ -26,50 +18,50 @@
|
||||
:friction 6
|
||||
:tension 40}))))
|
||||
|
||||
(defn overlay [{:keys [on-click-outside]} items]
|
||||
[view {:style st/bottom-info-overlay}
|
||||
[touchable-highlight {:on-press on-click-outside
|
||||
:style st/overlay-highlight}
|
||||
[view nil]]
|
||||
(defn- overlay [{:keys [on-click-outside]} items]
|
||||
[react/view styles/bottom-info-overlay
|
||||
[react/touchable-highlight {:on-press on-click-outside
|
||||
:style styles/overlay-highlight}
|
||||
[react/view nil]]
|
||||
items])
|
||||
|
||||
(defn container [height & _]
|
||||
(defn- container [height & _]
|
||||
(let [anim-value (anim/create-value 1)
|
||||
context {:to-value height
|
||||
:val anim-value}
|
||||
on-update (container-animation-logic context)]
|
||||
(r/create-class
|
||||
(reagent/create-class
|
||||
{:component-did-update
|
||||
on-update
|
||||
:display-name "container"
|
||||
:reagent-render
|
||||
(fn [height & children]
|
||||
[animated-view {:style (st/bottom-info-container height)}
|
||||
(into [view] children)])})))
|
||||
[react/animated-view {:style (styles/bottom-info-container height)}
|
||||
(into [react/view] children)])})))
|
||||
|
||||
(defn message-status-row [{:keys [photo-path name]} {:keys [whisper-identity status]}]
|
||||
[view st/bottom-info-row
|
||||
[image {:source {:uri (or photo-path (identicon whisper-identity))}
|
||||
:style st/bottom-info-row-photo}]
|
||||
[view st/bottom-info-row-text-container
|
||||
[text {:style st/bottom-info-row-text1
|
||||
:number-of-lines 1}
|
||||
(truncate-str (if-not (str/blank? name)
|
||||
name
|
||||
whisper-identity) 30)]
|
||||
[text {:style st/bottom-info-row-text2
|
||||
:number-of-lines 1}
|
||||
(message-status-label (or status :sending))]]])
|
||||
(defn- message-status-row [{:keys [photo-path name]} {:keys [whisper-identity status]}]
|
||||
[react/view styles/bottom-info-row
|
||||
[react/image {:source {:uri (or photo-path (identicon/identicon whisper-identity))}
|
||||
:style styles/bottom-info-row-photo}]
|
||||
[react/view styles/bottom-info-row-text-container
|
||||
[react/text {:style styles/bottom-info-row-text1
|
||||
:number-of-lines 1}
|
||||
(utils/truncate-str (if-not (string/blank? name)
|
||||
name
|
||||
whisper-identity) 30)]
|
||||
[react/text {:style styles/bottom-info-row-text2
|
||||
:number-of-lines 1}
|
||||
(i18n/message-status-label (or status :sending))]]])
|
||||
|
||||
(defn render-row [contacts]
|
||||
(defn- render-status [contacts]
|
||||
(fn [{:keys [whisper-identity] :as row} _ _]
|
||||
(let [contact (get contacts whisper-identity)]
|
||||
(list-item [message-status-row contact row]))))
|
||||
[message-status-row contact row])))
|
||||
|
||||
(defn bottom-info-view []
|
||||
(let [bottom-info (subscribe [:get-current-chat-ui-prop :bottom-info])
|
||||
contacts (subscribe [:get-contacts])]
|
||||
(r/create-class
|
||||
(let [bottom-info (re-frame/subscribe [:get-current-chat-ui-prop :bottom-info])
|
||||
contacts (re-frame/subscribe [:get-contacts])]
|
||||
(reagent/create-class
|
||||
{:display-name "bottom-info-view"
|
||||
:reagent-render
|
||||
(fn []
|
||||
@ -80,9 +72,9 @@
|
||||
:status message-status}]))
|
||||
(into {}))
|
||||
statuses (vals (merge participants user-statuses))]
|
||||
[overlay {:on-click-outside #(dispatch [:set-chat-ui-props {:show-bottom-info? false}])}
|
||||
[container (* st/item-height (count statuses))
|
||||
[list-view {:dataSource (lw/to-datasource statuses)
|
||||
:enableEmptySections true
|
||||
:renderRow (render-row @contacts)
|
||||
:contentContainerStyle st/bottom-info-list-container}]]]))})))
|
||||
[overlay {:on-click-outside #(re-frame/dispatch [:set-chat-ui-props {:show-bottom-info? false}])}
|
||||
[container (* styles/item-height (count statuses))
|
||||
[list/flat-list {:contentContainerStyle styles/bottom-info-list-container
|
||||
:data statuses
|
||||
:render-fn (render-status @contacts)
|
||||
:enableEmptySections true}]]]))})))
|
@ -1,20 +1,19 @@
|
||||
(ns status-im.chat.views.input.validation-messages
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.ui.components.react :as c]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.chat.styles.input.validation-message :as style]
|
||||
[status-im.utils.listview :as lw]
|
||||
[status-im.i18n :as i18n]))
|
||||
|
||||
(defn validation-message [{:keys [title description]}]
|
||||
[c/view style/message-container
|
||||
[c/text {:style style/message-title}
|
||||
[react/view style/message-container
|
||||
[react/text {:style style/message-title}
|
||||
title]
|
||||
[c/text {:style style/message-description}
|
||||
[react/text {:style style/message-description}
|
||||
description]])
|
||||
|
||||
(defn messages-list [markup]
|
||||
[c/view {:flex 1}
|
||||
(defn- messages-list [markup]
|
||||
[react/view {:flex 1}
|
||||
markup])
|
||||
|
||||
(defview validation-messages-view []
|
||||
@ -22,7 +21,7 @@
|
||||
input-height [:get-current-chat-ui-prop :input-height]
|
||||
messages [:validation-messages]]
|
||||
(when messages
|
||||
[c/view (style/root (+ input-height chat-input-margin))
|
||||
[react/view (style/root (+ input-height chat-input-margin))
|
||||
(if (string? messages)
|
||||
[messages-list [validation-message {:title (i18n/label :t/error)
|
||||
:description messages}]]
|
||||
|
@ -1,30 +1,19 @@
|
||||
(ns status-im.ui.components.drawer.view
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [cljs.spec.alpha :as s]
|
||||
[clojure.string :as str]
|
||||
[reagent.core :as r]
|
||||
[re-frame.core :as rf]
|
||||
(:require [clojure.string :as string]
|
||||
[reagent.core :as reagent]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ui.components.chat-icon.screen :as ci]
|
||||
[status-im.ui.components.common.common :as common]
|
||||
[status-im.ui.components.context-menu :as context-menu]
|
||||
[status-im.ui.components.drawer.styles :as st]
|
||||
[status-im.ui.components.react :refer [view
|
||||
text
|
||||
text-input
|
||||
list-item
|
||||
list-view
|
||||
drawer-layout
|
||||
touchable-without-feedback
|
||||
touchable-highlight
|
||||
touchable-opacity
|
||||
dismiss-keyboard!]]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.icons.vector-icons :as vi]
|
||||
[status-im.ui.components.status-view.view :as status-view]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.profile.db :as profile.db]
|
||||
[status-im.utils.datetime :as time]
|
||||
[status-im.utils.gfycat.core :as gfycat]
|
||||
[status-im.utils.listview :as lw]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im.utils.money :as money]
|
||||
@ -39,26 +28,26 @@
|
||||
;; editing the name or status field
|
||||
|
||||
(defn save-profile! []
|
||||
(when-let [save-event @(rf/subscribe [:my-profile.drawer/save-event])]
|
||||
(rf/dispatch [save-event])))
|
||||
(when-let [save-event @(re-frame/subscribe [:my-profile.drawer/save-event])]
|
||||
(re-frame/dispatch [save-event])))
|
||||
|
||||
(defn navigate-to-profile []
|
||||
(close-drawer!)
|
||||
(save-profile!)
|
||||
(rf/dispatch [:navigate-to :my-profile]))
|
||||
(re-frame/dispatch [:navigate-to :my-profile]))
|
||||
|
||||
(defn navigate-to-accounts []
|
||||
(close-drawer!)
|
||||
(save-profile!)
|
||||
;; TODO(rasom): probably not the best place for this call
|
||||
(protocol/stop-whisper!)
|
||||
(rf/dispatch [:navigate-to :accounts]))
|
||||
(re-frame/dispatch [:navigate-to :accounts]))
|
||||
|
||||
(defview profile-picture []
|
||||
(letsubs [account [:get-current-account]]
|
||||
[touchable-opacity {:on-press navigate-to-profile
|
||||
:style st/user-photo-container}
|
||||
[view
|
||||
[react/touchable-opacity {:on-press navigate-to-profile
|
||||
:style st/user-photo-container}
|
||||
[react/view
|
||||
[ci/chat-icon (:photo-path account) {:size 52
|
||||
:accessibility-label :drawer-profile-icon}]]]))
|
||||
|
||||
@ -66,88 +55,79 @@
|
||||
(letsubs [profile-name [:my-profile.drawer/get :name]
|
||||
valid-name? [:my-profile.drawer/valid-name?]
|
||||
placeholder [:get :my-profile/default-name]]
|
||||
[view st/name-input-wrapper
|
||||
[text-input
|
||||
[react/view st/name-input-wrapper
|
||||
[react/text-input
|
||||
{:placeholder placeholder
|
||||
:style (st/name-input-text valid-name?)
|
||||
:font :medium
|
||||
:default-value profile-name
|
||||
:on-focus #(rf/dispatch [:my-profile.drawer/edit-name])
|
||||
:on-change-text #(rf/dispatch [:my-profile.drawer/update-name %])
|
||||
:on-end-editing #(rf/dispatch [:my-profile.drawer/save-name])}]]))
|
||||
:default-value profile-name
|
||||
:on-focus #(re-frame/dispatch [:my-profile.drawer/edit-name])
|
||||
:on-change-text #(re-frame/dispatch [:my-profile.drawer/update-name %])
|
||||
:on-end-editing #(re-frame/dispatch [:my-profile.drawer/save-name])}]]))
|
||||
|
||||
(defview status-input []
|
||||
(letsubs [edit-status? [:my-profile.drawer/get :edit-status?]
|
||||
status [:my-profile.drawer/get :status]]
|
||||
(let [placeholder (i18n/label :t/update-status)]
|
||||
[view st/status-container
|
||||
[react/view st/status-container
|
||||
(if edit-status?
|
||||
[text-input {:style st/status-input-view
|
||||
:multiline true
|
||||
:auto-focus true
|
||||
:focus edit-status?
|
||||
:max-length 140
|
||||
:accessibility-label :drawer-status-input
|
||||
:placeholder placeholder
|
||||
:default-value status
|
||||
:on-change-text #(rf/dispatch [:my-profile.drawer/update-status %])
|
||||
:on-end-editing #(when edit-status?
|
||||
(rf/dispatch [:my-profile.drawer/save-status]))}]
|
||||
|
||||
[status-view/status-view {:style (st/status-view (str/blank? status))
|
||||
[react/text-input {:style st/status-input-view
|
||||
:multiline true
|
||||
:auto-focus true
|
||||
:focus edit-status?
|
||||
:max-length 140
|
||||
:accessibility-label :drawer-status-input
|
||||
:placeholder placeholder
|
||||
:default-value status
|
||||
:on-change-text #(re-frame/dispatch [:my-profile.drawer/update-status %])
|
||||
:on-end-editing #(when edit-status?
|
||||
(re-frame/dispatch [:my-profile.drawer/save-status]))}]
|
||||
[status-view/status-view {:style (st/status-view (string/blank? status))
|
||||
:number-of-lines 3
|
||||
:status (if (str/blank? status)
|
||||
:status (if (string/blank? status)
|
||||
placeholder
|
||||
status)
|
||||
:on-press #(rf/dispatch [:my-profile.drawer/edit-status])}])])))
|
||||
|
||||
(defn render-separator-fn [transactions-count]
|
||||
(fn [_ row-id _]
|
||||
(when (< row-id (dec transactions-count))
|
||||
(list-item
|
||||
^{:key row-id}
|
||||
[common/separator {} st/transactions-list-separator]))))
|
||||
:on-press #(re-frame/dispatch [:my-profile.drawer/edit-status])}])])))
|
||||
|
||||
(defview current-network []
|
||||
(letsubs [network [:get-current-account-network]]
|
||||
[view {:style st/network-label-container}
|
||||
[text {:style st/network-label} (i18n/label :t/current-network)]
|
||||
[text {:style st/network-title} (:name network)]]))
|
||||
[react/view {:style st/network-label-container}
|
||||
[react/text {:style st/network-label} (i18n/label :t/current-network)]
|
||||
[react/text {:style st/network-title} (:name network)]]))
|
||||
|
||||
(defn options-btn []
|
||||
[view {:style st/options-button}
|
||||
[touchable-highlight
|
||||
{:on-press navigate-to-profile}
|
||||
[view [vi/icon :icons/options]]]])
|
||||
[react/view {:style st/options-button}
|
||||
[react/touchable-highlight {:on-press navigate-to-profile}
|
||||
[react/view [vi/icon :icons/options]]]])
|
||||
|
||||
(defn switch-account []
|
||||
[view st/switch-account-container
|
||||
[touchable-highlight
|
||||
[react/view st/switch-account-container
|
||||
[react/touchable-highlight
|
||||
{:on-press navigate-to-accounts}
|
||||
[view
|
||||
[text {:style st/switch-account-text
|
||||
:font (if platform/android? :medium :default)
|
||||
:uppercase? platform/android?}
|
||||
[react/view
|
||||
[react/text {:style st/switch-account-text
|
||||
:font (if platform/android? :medium :default)
|
||||
:uppercase? platform/android?}
|
||||
(i18n/label :t/switch-users)]]]])
|
||||
|
||||
(defn drawer []
|
||||
(fn []
|
||||
[touchable-without-feedback {:on-press #(dismiss-keyboard!)}
|
||||
[view st/drawer
|
||||
[view st/upper-container
|
||||
[view st/profile-container
|
||||
[react/touchable-without-feedback {:on-press #(react/dismiss-keyboard!)}
|
||||
[react/view st/drawer
|
||||
[react/view st/upper-container
|
||||
[react/view st/profile-container
|
||||
[profile-picture]
|
||||
[name-input]
|
||||
[status-input]
|
||||
[options-btn]]
|
||||
[current-network]]
|
||||
[view
|
||||
[react/view
|
||||
[switch-account]]]]))
|
||||
|
||||
(defn drawer-view [items]
|
||||
[drawer-layout {:drawerWidth 300
|
||||
:renderNavigationView #(r/as-element [drawer])
|
||||
:onDrawerSlide dismiss-keyboard!
|
||||
:ref (fn [drawer]
|
||||
(reset! drawer-atom drawer))}
|
||||
[react/drawer-layout {:drawerWidth 300
|
||||
:renderNavigationView #(reagent/as-element [drawer])
|
||||
:onDrawerSlide react/dismiss-keyboard!
|
||||
:ref (fn [drawer]
|
||||
(reset! drawer-atom drawer))}
|
||||
items])
|
||||
|
@ -1,8 +0,0 @@
|
||||
(ns status-im.ui.components.invertible-scroll-view
|
||||
(:require [reagent.core :as r]
|
||||
[status-im.react-native.js-dependencies :as rn-dependencies]))
|
||||
|
||||
(defn invertible-scroll-view [props]
|
||||
(r/create-element rn-dependencies/invertible-scroll-view
|
||||
(clj->js (merge {:inverted true} props))))
|
||||
|
@ -62,6 +62,10 @@
|
||||
base-separator
|
||||
{:margin-left 70}))
|
||||
|
||||
(defstyle list-header-footer-spacing
|
||||
{:android {:background-color styles/color-white
|
||||
:height 8}})
|
||||
|
||||
(defstyle section-separator
|
||||
(merge base-separator
|
||||
{:android {:margin-top 12}
|
||||
|
@ -18,129 +18,147 @@
|
||||
|
||||
[section-list {:sections [{:title \"\" :key :unik :render-fn render :data {:title \"\" :subtitle \"\"}}]}]
|
||||
"
|
||||
(:require [reagent.core :as r]
|
||||
[status-im.ui.components.list.styles :as lst]
|
||||
(:require [reagent.core :as reagent]
|
||||
[reagent.impl.template :as temp]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.checkbox.view :as checkbox]
|
||||
[status-im.ui.components.react :as rn]
|
||||
[status-im.ui.components.icons.vector-icons :as vi]
|
||||
[status-im.utils.platform :as p]))
|
||||
[status-im.ui.components.list.styles :as styles]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.utils.platform :as platform]))
|
||||
|
||||
(def flat-list-class (rn/get-class "FlatList"))
|
||||
(def section-list-class (rn/get-class "SectionList"))
|
||||
(def flat-list-class (react/get-class "FlatList"))
|
||||
(def section-list-class (react/get-class "SectionList"))
|
||||
|
||||
(defn item
|
||||
([content] (item nil content))
|
||||
([left-action content] (item left-action content nil))
|
||||
([left-action content right-action]
|
||||
[rn/view {:style lst/item}
|
||||
[rn/view {:style lst/left-item-wrapper}
|
||||
[react/view {:style styles/item}
|
||||
[react/view {:style styles/left-item-wrapper}
|
||||
left-action]
|
||||
[rn/view {:style lst/content-item-wrapper}
|
||||
[react/view {:style styles/content-item-wrapper}
|
||||
content]
|
||||
(when right-action
|
||||
[rn/view {:style lst/right-item-wrapper}
|
||||
[react/view {:style styles/right-item-wrapper}
|
||||
right-action])]))
|
||||
|
||||
(defn touchable-item [handler item]
|
||||
[rn/touchable-highlight {:on-press handler}
|
||||
[react/touchable-highlight {:on-press handler}
|
||||
item])
|
||||
|
||||
(defn item-icon
|
||||
[{:keys [icon style icon-opts]}]
|
||||
[rn/view {:style style}
|
||||
[vi/icon icon (merge icon-opts {:style lst/item-icon})]])
|
||||
[react/view {:style style}
|
||||
[vector-icons/icon icon (merge icon-opts {:style styles/item-icon})]])
|
||||
|
||||
(defn item-image
|
||||
[{:keys [source style]}]
|
||||
[rn/view {:style style}
|
||||
[rn/image {:source source
|
||||
:style lst/item-image}]])
|
||||
[{:keys[source style]}]
|
||||
[react/view {:style style}
|
||||
[react/image {:source source
|
||||
:style styles/item-image}]])
|
||||
|
||||
(defn item-primary
|
||||
[primary]
|
||||
[rn/text {:style lst/primary-text} primary])
|
||||
[react/text {:style styles/primary-text} primary])
|
||||
|
||||
(defn item-primary-only
|
||||
[primary]
|
||||
[rn/text {:style lst/primary-text-only} primary])
|
||||
[react/text {:style styles/primary-text-only} primary])
|
||||
|
||||
(defn item-secondary
|
||||
[secondary]
|
||||
[rn/text {:style lst/secondary-text :ellipsize-mode "middle" :number-of-lines 1} secondary])
|
||||
[react/text {:style styles/secondary-text :ellipsize-mode :middle :number-of-lines 1} secondary])
|
||||
|
||||
(defn item-content
|
||||
[& children]
|
||||
(into [rn/view {:style lst/item-text-view}] (keep identity children)))
|
||||
(into [react/view {:style styles/item-text-view}] (keep identity children)))
|
||||
|
||||
(defn item-checkbox
|
||||
[{:keys [style] :as props}]
|
||||
[rn/view {:style (merge style lst/item-checkbox)}
|
||||
[react/view {:style (merge style styles/item-checkbox)}
|
||||
[checkbox/checkbox props]])
|
||||
|
||||
(defn- wrap-render-fn [f]
|
||||
(fn [data]
|
||||
;; For details on passed data
|
||||
;; https://facebook.github.io/react-native/docs/sectionlist.html#renderitem
|
||||
(let [{:keys [item index separators]} (js->clj data :keywordize-keys true)]
|
||||
(r/as-element (f (js->clj item) index separators)))))
|
||||
(reagent/as-element (f (.-item data) (.-index data) (.-separators data)))))
|
||||
|
||||
(defn- separator []
|
||||
[rn/view lst/separator])
|
||||
(def default-separator [react/view styles/separator])
|
||||
|
||||
(defn- section-separator []
|
||||
[rn/view lst/section-separator])
|
||||
(def default-header [react/view styles/list-header-footer-spacing])
|
||||
|
||||
(defn- base-list-props [render-fn empty-component separator?]
|
||||
(merge {:keyExtractor (fn [_ i] i)}
|
||||
(when render-fn {:renderItem (wrap-render-fn render-fn)})
|
||||
(when (and p/ios? separator?) {:ItemSeparatorComponent (fn [] (r/as-element [separator]))})
|
||||
;; TODO(jeluard) Does not work with our current ReactNative version
|
||||
(when empty-component {:ListEmptyComponent (r/as-element [empty-component])})))
|
||||
(def default-footer [react/view styles/list-header-footer-spacing])
|
||||
|
||||
(def section-separator [react/view styles/section-separator])
|
||||
|
||||
(defn- base-list-props
|
||||
[{:keys [render-fn empty-component header separator default-separator?]}]
|
||||
(let [separator (or separator (when (and platform/ios? default-separator?) default-separator))]
|
||||
(merge {:keyExtractor (fn [_ i] i)}
|
||||
(when render-fn {:renderItem (wrap-render-fn render-fn)})
|
||||
(when separator {:ItemSeparatorComponent (fn [] (reagent/as-element [separator]))})
|
||||
(when empty-component {:ListEmptyComponent (fn [] (reagent/as-element empty-component))})
|
||||
(when header {:ListHeaderComponent (fn [] (reagent/as-element header))}))))
|
||||
|
||||
;; Workaround an issue in reagent that does not consider JS array as JS value
|
||||
;; This forces clj <-> js serialization and breaks clj semantic
|
||||
;; See https://github.com/reagent-project/reagent/issues/335
|
||||
|
||||
(deftype Item [value]
|
||||
IEncodeJS
|
||||
(-clj->js [x] (.-value x))
|
||||
(-key->js [x] (.-value x))
|
||||
IEncodeClojure
|
||||
(-js->clj [x options] (.-value x)))
|
||||
|
||||
(defn- to-js-array
|
||||
"Converts a collection to a JS array (but leave content as is)"
|
||||
[coll]
|
||||
(let [arr (array)]
|
||||
(doseq [x coll]
|
||||
(.push arr x))
|
||||
arr))
|
||||
|
||||
(defn- wrap-data [o]
|
||||
(Item. (to-js-array o)))
|
||||
|
||||
(defn flat-list
|
||||
"A wrapper for FlatList.
|
||||
See https://facebook.github.io/react-native/docs/flatlist.html"
|
||||
[{:keys [data render-fn empty-component separator?] :as props
|
||||
:or {separator? true}}]
|
||||
[{:keys [data empty-component] :as props}]
|
||||
{:pre [(or (nil? data)
|
||||
(sequential? data))]}
|
||||
(if (and (empty? data) empty-component)
|
||||
;; TODO(jeluard) remove when native :ListEmptyComponent is supported
|
||||
empty-component
|
||||
[flat-list-class
|
||||
(merge (base-list-props render-fn empty-component separator?)
|
||||
{:data (clj->js data)}
|
||||
props)]))
|
||||
[flat-list-class
|
||||
(merge (base-list-props props)
|
||||
props
|
||||
{:data (wrap-data data)})])
|
||||
|
||||
(defn- wrap-render-section-header-fn [f]
|
||||
(fn [data]
|
||||
;; For details on passed data
|
||||
;; https://facebook.github.io/react-native/docs/sectionlist.html#rendersectionheader
|
||||
(let [{:keys [section]} (js->clj data :keywordize-keys true)]
|
||||
(r/as-element (f section)))))
|
||||
(reagent/as-element (f (.-section data)))))
|
||||
|
||||
(defn- default-render-section-header [{:keys [title data]}]
|
||||
(when (seq data)
|
||||
[rn/text {:style lst/section-header}
|
||||
[react/text {:style styles/section-header}
|
||||
title]))
|
||||
|
||||
(defn- wrap-per-section-render-fn [props]
|
||||
;; TODO(jeluard) Somehow wrapping `:render-fn` does not work
|
||||
(if-let [f (:render-fn props)]
|
||||
(assoc (dissoc props :render-fn) :renderItem (wrap-render-fn f))
|
||||
props))
|
||||
(update
|
||||
(if-let [f (:render-fn props)]
|
||||
(assoc (dissoc props :render-fn) :renderItem (wrap-render-fn f))
|
||||
props)
|
||||
:data wrap-data))
|
||||
|
||||
(defn section-list
|
||||
"A wrapper for SectionList.
|
||||
See https://facebook.github.io/react-native/docs/sectionlist.html"
|
||||
[{:keys [sections render-fn empty-component render-section-header-fn separator?] :as props
|
||||
:or {render-section-header-fn default-render-section-header
|
||||
separator? true}}]
|
||||
[{:keys [sections empty-component render-section-header-fn] :as props
|
||||
:or {render-section-header-fn default-render-section-header}}]
|
||||
(if (and (every? #(empty? (:data %)) sections) empty-component)
|
||||
empty-component
|
||||
[section-list-class
|
||||
(merge (base-list-props render-fn empty-component separator?)
|
||||
(merge (base-list-props props)
|
||||
props
|
||||
{:sections (clj->js (map wrap-per-section-render-fn sections))
|
||||
:renderSectionHeader (wrap-render-section-header-fn render-section-header-fn)}
|
||||
(when p/ios? {:SectionSeparatorComponent (fn [] (r/as-element [section-separator]))})
|
||||
props)]))
|
||||
(when platform/ios? {:SectionSeparatorComponent (fn [] (reagent/as-element [section-separator]))}))]))
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
(ns status-im.ui.components.react
|
||||
(:require-macros [status-im.utils.views :as views])
|
||||
(:require [reagent.core :as r]
|
||||
(:require [clojure.string :as string]
|
||||
[reagent.core :as r]
|
||||
[status-im.ui.components.styles :as st]
|
||||
[status-im.utils.utils :as u]
|
||||
[status-im.utils.platform :refer [platform-specific ios?]]
|
||||
@ -40,7 +41,6 @@
|
||||
(def status-bar (get-class "StatusBar"))
|
||||
(def drawer-layout (adapt-class (.-default drawer)))
|
||||
|
||||
(def list-view-class (get-class "ListView"))
|
||||
(def scroll-view (get-class "ScrollView"))
|
||||
(def web-view (get-class "WebView"))
|
||||
(def keyboard-avoiding-view-class (get-class "KeyboardAvoidingView"))
|
||||
@ -82,7 +82,7 @@
|
||||
([{:keys [uppercase?] :as opts} t & ts]
|
||||
(r/as-element
|
||||
(let [ts (cond->> (conj ts t)
|
||||
uppercase? (map clojure.string/upper-case))]
|
||||
uppercase? (map #(when % (string/upper-case %))))]
|
||||
(vec (concat
|
||||
[text-class (add-font-style :style opts)]
|
||||
ts))))))
|
||||
@ -106,11 +106,6 @@
|
||||
:resizeMode "contain"
|
||||
:style style}]))
|
||||
|
||||
;; TODO Migrate to new FlatList and SectionList when appropriate (see components.list). ListView will eventually get deprecated
|
||||
;; see https://facebook.github.io/react-native/docs/using-a-listview.html
|
||||
(defn list-view [props]
|
||||
[list-view-class (merge {:enableEmptySections true} props)])
|
||||
|
||||
(defn touchable-highlight [props content]
|
||||
[touchable-highlight-class
|
||||
(merge {:underlay-color :transparent} props)
|
||||
|
@ -1,14 +0,0 @@
|
||||
(ns status-im.ui.components.renderers.renderers
|
||||
(:require [status-im.ui.components.react :refer [list-item]]
|
||||
[status-im.ui.components.common.common :as common]))
|
||||
|
||||
(defn list-separator-renderer [_ row-id _]
|
||||
(list-item
|
||||
^{:key row-id}
|
||||
[common/list-separator]))
|
||||
|
||||
(defn list-header-renderer [& _]
|
||||
(list-item [common/list-header]))
|
||||
|
||||
(defn list-footer-renderer [& _]
|
||||
(list-item [common/list-footer]))
|
@ -1,60 +1,56 @@
|
||||
(ns status-im.ui.screens.accounts.views
|
||||
(:require-macros [status-im.utils.views :refer [defview]])
|
||||
(:require [re-frame.core :refer [dispatch dispatch-sync]]
|
||||
[status-im.ui.screens.accounts.styles :as st]
|
||||
[status-im.ui.components.status-bar.view :refer [status-bar]]
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ui.screens.accounts.styles :as styles]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]
|
||||
[status-im.ui.components.toolbar.actions :as act]
|
||||
[status-im.ui.components.common.common :as common]
|
||||
[status-im.ui.components.action-button.action-button :refer [action-button]]
|
||||
[status-im.utils.listview :as lw]
|
||||
[status-im.constants :refer [console-chat-id]]
|
||||
[status-im.ui.components.react :refer [view
|
||||
text
|
||||
list-view
|
||||
list-item
|
||||
image
|
||||
touchable-highlight]]
|
||||
[status-im.i18n :as i18n]
|
||||
[clojure.string :as str]))
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.i18n :as i18n]))
|
||||
|
||||
|
||||
(defn account-badge [address photo-path name]
|
||||
[view st/account-badge
|
||||
[image {:source {:uri (if (str/blank? photo-path) :avatar photo-path)}
|
||||
:style st/photo-image}]
|
||||
[view st/account-badge-text-view
|
||||
[text {:style st/account-badge-text
|
||||
:numberOfLines 1}
|
||||
[react/view styles/account-badge
|
||||
[react/image {:source {:uri (if (string/blank? photo-path) :avatar photo-path)}
|
||||
:style styles/photo-image}]
|
||||
[react/view styles/account-badge-text-view
|
||||
[react/text {:style styles/account-badge-text
|
||||
:numberOfLines 1}
|
||||
(or name address)]]])
|
||||
|
||||
(defn account-view [{:keys [address photo-path name] :as account}]
|
||||
[view
|
||||
[touchable-highlight {:on-press #(dispatch [:open-login address photo-path name])}
|
||||
[view st/account-view
|
||||
[react/view
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:open-login address photo-path name])}
|
||||
[react/view styles/account-view
|
||||
[account-badge address photo-path name]]]])
|
||||
|
||||
(defview accounts []
|
||||
[accounts [:get-accounts]]
|
||||
[view st/accounts-container
|
||||
[status-bar {:type :transparent}]
|
||||
[view st/account-title-conatiner
|
||||
[text {:style st/account-title-text
|
||||
:font :toolbar-title}
|
||||
[react/view styles/accounts-container
|
||||
[status-bar/status-bar {:type :transparent}]
|
||||
[react/view styles/account-title-conatiner
|
||||
[react/text {:style styles/account-title-text
|
||||
:font :toolbar-title}
|
||||
(i18n/label :t/sign-in-to-status)]]
|
||||
[view st/accounts-list-container
|
||||
[list-view {:dataSource (lw/to-datasource (vals accounts))
|
||||
:renderSeparator #(list-item ^{:key %2} [view {:height 10}])
|
||||
:renderRow #(list-item [account-view %])}]]
|
||||
[view st/bottom-actions-container
|
||||
[react/view styles/accounts-list-container
|
||||
[list/flat-list {:data (vals accounts)
|
||||
:render-fn (fn [account] [account-view account])
|
||||
:separator [react/view {:height 10}]}]]
|
||||
[react/view styles/bottom-actions-container
|
||||
[action-button (merge
|
||||
{:label (i18n/label :t/create-new-account)
|
||||
:icon :icons/add
|
||||
:icon-opts {:color :white}
|
||||
:on-press #(dispatch [:create-new-account-handler])}
|
||||
st/accounts-action-button)]
|
||||
[common/separator st/accounts-separator st/accounts-separator-wrapper]
|
||||
:on-press #(re-frame/dispatch [:create-new-account-handler])}
|
||||
styles/accounts-action-button)]
|
||||
[common/separator styles/accounts-separator styles/accounts-separator-wrapper]
|
||||
[action-button (merge
|
||||
{:label (i18n/label :t/recover-access)
|
||||
:icon :icons/dots-horizontal
|
||||
:icon-opts {:color :white}
|
||||
:on-press #(dispatch [:navigate-to :recover])}
|
||||
st/accounts-action-button)]]])
|
||||
:on-press #(re-frame/dispatch [:navigate-to :recover])}
|
||||
styles/accounts-action-button)]]])
|
||||
|
@ -2,7 +2,7 @@
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.ui.components.common.common :as common]
|
||||
[status-im.ui.components.renderers.renderers :as renderers]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.native-action-button :refer [native-action-button]]
|
||||
[status-im.ui.components.drawer.view :as drawer]
|
||||
@ -15,7 +15,6 @@
|
||||
[status-im.ui.components.sync-state.offline :refer [offline-view]]
|
||||
[status-im.ui.components.context-menu :refer [context-menu]]
|
||||
[status-im.ui.components.tabs.styles :refer [tabs-height]]
|
||||
[status-im.utils.listview :refer [to-datasource]]
|
||||
[status-im.ui.screens.chats-list.views.inner-item :as inner-item]
|
||||
[status-im.ui.screens.chats-list.styles :as st]
|
||||
[status-im.i18n :as i18n]
|
||||
@ -84,18 +83,17 @@
|
||||
edit? [toolbar-edit]
|
||||
(= show-search :chat-list) [toolbar-search]
|
||||
:else [toolbar-view])
|
||||
[react/list-view {:dataSource (to-datasource chats)
|
||||
:renderRow (fn [[id :as row] _ _]
|
||||
(react/list-item ^{:key id} [chat-list-item row edit?]))
|
||||
:renderHeader (when-not (empty? chats) renderers/list-header-renderer)
|
||||
:renderFooter (when-not (empty? chats)
|
||||
#(react/list-item [react/view
|
||||
[common/list-footer]
|
||||
[common/bottom-shadow]]))
|
||||
:renderSeparator renderers/list-separator-renderer
|
||||
:style st/list-container}]
|
||||
[list/flat-list {:style st/list-container
|
||||
:data chats
|
||||
:render-fn (fn [chat] [chat-list-item chat edit?])
|
||||
:header (when-not (empty? chats) list/default-header)
|
||||
:footer (when-not (empty? chats)
|
||||
[react/view
|
||||
[common/list-footer]
|
||||
[common/bottom-shadow]])}]
|
||||
|
||||
(when (and (not edit?)
|
||||
(not= show-search :chat-list)
|
||||
(not= show-search :chat-list)
|
||||
(get-in platform-specific [:chats :action-button?]))
|
||||
[chats-action-button])
|
||||
[offline-view]]))
|
||||
|
@ -1,34 +1,32 @@
|
||||
(ns status-im.ui.screens.contacts.contact-list.views
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [re-frame.core :refer [dispatch]]
|
||||
[status-im.ui.components.renderers.renderers :as renderers]
|
||||
[status-im.ui.components.contact.contact :refer [contact-view]]
|
||||
[status-im.ui.screens.contacts.views :refer [contact-options]]
|
||||
[status-im.ui.components.react :refer [view list-view list-item]]
|
||||
[status-im.ui.components.status-bar.view :refer [status-bar]]
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.ui.components.contact.contact :as contact-view]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.components.toolbar.actions :as act]
|
||||
[status-im.ui.components.drawer.view :refer [drawer-view]]
|
||||
[status-im.ui.screens.contacts.styles :as st]
|
||||
[status-im.utils.listview :as lw]
|
||||
[status-im.i18n :refer [label]]))
|
||||
[status-im.ui.components.drawer.view :as drawer-view]
|
||||
[status-im.ui.screens.contacts.styles :as styles]
|
||||
[status-im.ui.screens.contacts.views :as contact-options]
|
||||
[status-im.i18n :as i18n]))
|
||||
|
||||
|
||||
(defn render-row [group edit?]
|
||||
(fn [row _ _]
|
||||
(list-item
|
||||
^{:key row}
|
||||
[contact-view {:contact row
|
||||
:on-press #(dispatch [:open-chat-with-contact %])
|
||||
:extended? edit?
|
||||
:extend-options (contact-options row group)}])))
|
||||
[contact-view/contact-view {:contact row
|
||||
:on-press #(re-frame/dispatch [:open-chat-with-contact %])
|
||||
:extended? edit?
|
||||
:extend-options (contact-options/contact-options row group)}]))
|
||||
|
||||
(defview contact-list-toolbar-edit [group]
|
||||
[toolbar/toolbar {}
|
||||
[toolbar/nav-button (act/back #(dispatch [:set-in [:contacts/list-ui-props :edit?] false]))]
|
||||
[toolbar/nav-button (act/back #(re-frame/dispatch [:set-in [:contacts/list-ui-props :edit?] false]))]
|
||||
[toolbar/content-title
|
||||
(if-not group
|
||||
(label :t/contacts)
|
||||
(or (:name group) (label :t/contacts-group-new-chat)))]])
|
||||
(i18n/label :t/contacts)
|
||||
(or (:name group) (i18n/label :t/contacts-group-new-chat)))]])
|
||||
|
||||
(defview contact-list-toolbar [group]
|
||||
(letsubs [show-search [:get-in [:toolbar-search :show]]
|
||||
@ -38,30 +36,29 @@
|
||||
:search-text search-text
|
||||
:search-key :contact-list
|
||||
:title (if-not group
|
||||
(label :t/contacts)
|
||||
(or (:name group) (label :t/contacts-group-new-chat)))
|
||||
:search-placeholder (label :t/search-contacts)
|
||||
:actions [(act/opts [{:text (label :t/edit)
|
||||
:value #(dispatch [:set-in [:contacts/list-ui-props :edit?] true])}])]})))
|
||||
(i18n/label :t/contacts)
|
||||
(or (:name group) (i18n/label :t/contacts-group-new-chat)))
|
||||
:search-placeholder (i18n/label :t/search-contacts)
|
||||
:actions [(act/opts [{:text (i18n/label :t/edit)
|
||||
:value #(re-frame/dispatch [:set-in [:contacts/list-ui-props :edit?] true])}])]})))
|
||||
|
||||
(defview contacts-list-view [group edit?]
|
||||
(letsubs [contacts [:all-added-group-contacts-filtered (:group-id group)]]
|
||||
[list-view {:dataSource (lw/to-datasource contacts)
|
||||
:enableEmptySections true
|
||||
:renderRow (render-row group edit?)
|
||||
:keyboardShouldPersistTaps :always
|
||||
:renderHeader renderers/list-header-renderer
|
||||
:renderFooter renderers/list-footer-renderer
|
||||
:renderSeparator renderers/list-separator-renderer
|
||||
:style st/contacts-list}]))
|
||||
[list/flat-list {:style styles/contacts-list
|
||||
:data contacts
|
||||
:render-fn (render-row group edit?)
|
||||
:enableEmptySections true
|
||||
:keyboardShouldPersistTaps :always
|
||||
:header list/default-header
|
||||
:footer list/default-footer}]))
|
||||
|
||||
(defview contact-list []
|
||||
(letsubs [edit? [:get-in [:contacts/list-ui-props :edit?]]
|
||||
group [:get-contact-group]]
|
||||
[drawer-view
|
||||
[view {:flex 1}
|
||||
[view
|
||||
[status-bar]
|
||||
[drawer-view/drawer-view
|
||||
[react/view {:flex 1}
|
||||
[react/view
|
||||
[status-bar/status-bar]
|
||||
(if edit?
|
||||
[contact-list-toolbar-edit group]
|
||||
[contact-list-toolbar group])]
|
||||
|
@ -2,18 +2,17 @@
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [re-frame.core :refer [dispatch]]
|
||||
[status-im.ui.components.common.common :as common]
|
||||
[status-im.ui.components.renderers.renderers :as renderers]
|
||||
[status-im.ui.components.react :refer [view list-view list-item]]
|
||||
[status-im.ui.components.contact.contact :refer [contact-view]]
|
||||
[status-im.ui.components.action-button.action-button :refer [action-button
|
||||
action-separator]]
|
||||
[status-im.ui.components.action-button.styles :refer [actions-list]]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.status-bar.view :refer [status-bar]]
|
||||
[status-im.ui.components.toolbar.view :refer [toolbar-with-search]]
|
||||
[status-im.ui.components.drawer.view :refer [drawer-view]]
|
||||
[status-im.ui.screens.contacts.styles :as st]
|
||||
[status-im.utils.listview :as lw]
|
||||
[status-im.i18n :refer [label]]))
|
||||
[status-im.i18n :as i18n]))
|
||||
|
||||
(defview contact-list-modal-toolbar []
|
||||
(letsubs [show-search [:get-in [:toolbar-search :show]]
|
||||
@ -23,13 +22,13 @@
|
||||
:show-search? (= show-search :contact-list)
|
||||
:search-text search-text
|
||||
:search-key :contact-list
|
||||
:title (label :t/contacts)
|
||||
:search-placeholder (label :t/search-contacts)})))
|
||||
:title (i18n/label :t/contacts)
|
||||
:search-placeholder (i18n/label :t/search-contacts)})))
|
||||
|
||||
(defn actions-view [action click-handler]
|
||||
[view actions-list
|
||||
[react/view actions-list
|
||||
[action-button
|
||||
{:label (label :t/enter-address)
|
||||
{:label (i18n/label :t/enter-address)
|
||||
:icon :icons/address
|
||||
:icon-opts {:color :blue}
|
||||
:on-press #(do
|
||||
@ -38,22 +37,21 @@
|
||||
(dispatch [:navigate-back]))}]
|
||||
[action-separator]
|
||||
(if (= :request action)
|
||||
[action-button {:label (label :t/show-qr)
|
||||
[action-button {:label (i18n/label :t/show-qr)
|
||||
:icon :icons/qr
|
||||
:icon-opts {:color :blue}
|
||||
:on-press #(click-handler :qr-scan action)}]
|
||||
[action-button {:label (label :t/scan-qr)
|
||||
[action-button {:label (i18n/label :t/scan-qr)
|
||||
:icon :icons/fullscreen
|
||||
:icon-opts {:color :blue}
|
||||
:on-press #(click-handler :qr-scan action)}])])
|
||||
|
||||
(defn render-row [click-handler action params]
|
||||
(fn [row _ _]
|
||||
(list-item
|
||||
^{:key row}
|
||||
[contact-view {:contact row
|
||||
:on-press #(when click-handler
|
||||
(click-handler row action params))}])))
|
||||
[contact-view {:contact row
|
||||
:on-press #(when click-handler
|
||||
(click-handler row action params))}]))
|
||||
|
||||
|
||||
(defview contact-list-modal []
|
||||
(letsubs [contacts [:contacts-filtered :all-added-people-contacts]
|
||||
@ -61,24 +59,22 @@
|
||||
action [:get :contacts/click-action]
|
||||
params [:get :contacts/click-params]]
|
||||
[drawer-view
|
||||
[view {:flex 1}
|
||||
[react/view {:flex 1}
|
||||
[status-bar {:type :modal-white}]
|
||||
[contact-list-modal-toolbar]
|
||||
[list-view {:dataSource (lw/to-datasource contacts)
|
||||
:enableEmptySections true
|
||||
:renderRow (render-row click-handler action params)
|
||||
:bounces false
|
||||
:keyboardShouldPersistTaps :always
|
||||
:renderHeader (when-not (:hide-actions? params)
|
||||
#(list-item
|
||||
[view
|
||||
[actions-view action click-handler]
|
||||
[common/bottom-shadow]
|
||||
[common/form-title (label :t/choose-from-contacts)
|
||||
{:count-value (count contacts)}]
|
||||
[common/list-header]]))
|
||||
:renderFooter #(list-item [view
|
||||
[common/list-footer]
|
||||
[common/bottom-shadow]])
|
||||
:renderSeparator renderers/list-separator-renderer
|
||||
:style st/contacts-list-modal}]]]))
|
||||
[list/flat-list {:style st/contacts-list-modal
|
||||
:data contacts
|
||||
:render-fn (render-row click-handler action params)
|
||||
:header (when-not (:hide-actions? params)
|
||||
[react/view
|
||||
[actions-view action click-handler]
|
||||
[common/bottom-shadow]
|
||||
[common/form-title (i18n/label :t/choose-from-contacts)
|
||||
{:count-value (count contacts)}]
|
||||
[common/list-header]])
|
||||
:footer [react/view
|
||||
[common/list-footer]
|
||||
[common/bottom-shadow]]
|
||||
:enableEmptySections true
|
||||
:bounces false
|
||||
:keyboardShouldPersistTaps :always}]]]))
|
||||
|
@ -40,7 +40,7 @@
|
||||
[list/flat-list {:data (vals dapps)
|
||||
:render-fn render-dapp
|
||||
:horizontal true
|
||||
:separator? false
|
||||
:default-separator? false
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:content-container-style styles/dapp-preview-flat-list}]
|
||||
[react/text (i18n/label :t/none)])])
|
||||
|
@ -22,7 +22,7 @@
|
||||
:render-fn render-tag
|
||||
:horizontal true
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:separator? false}]])
|
||||
:default-separator? false}]])
|
||||
|
||||
(defview discover-all-hashtags []
|
||||
(letsubs [current-account [:get-current-account]
|
||||
|
@ -2,11 +2,11 @@
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.icons.vector-icons :as vi]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.screens.discover.components.views :as components]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.discover.styles :as styles]
|
||||
[status-im.ui.screens.contacts.styles :as contacts-styles]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]))
|
||||
[status-im.ui.screens.contacts.styles :as contacts-styles]))
|
||||
|
||||
;; TOOD(oskarth): Refactor this, very similar to discover-all-hashtags view
|
||||
(defview discover-search-results []
|
||||
|
@ -1,24 +1,26 @@
|
||||
(ns status-im.ui.screens.group.add-contacts.views
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [re-frame.core :refer [dispatch]]
|
||||
[status-im.ui.components.renderers.renderers :as renderers]
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.ui.components.contact.contact :refer [toogle-contact-view]]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.sticky-button :refer [sticky-button]]
|
||||
[status-im.ui.components.status-bar.view :refer [status-bar]]
|
||||
[status-im.ui.components.toolbar.view :refer [toolbar-with-search]]
|
||||
[status-im.utils.listview :refer [to-datasource]]
|
||||
[status-im.ui.screens.group.styles :as styles]
|
||||
[status-im.ui.screens.contacts.styles :as contacts.styles]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.contacts.styles :as cstyles]
|
||||
[status-im.i18n :refer [label]]
|
||||
[status-im.ui.components.contact.contact :refer [toogle-contact-view]]))
|
||||
|
||||
(defn on-toggle [checked? whisper-identity]
|
||||
(let [action (if checked? :deselect-contact :select-contact)]
|
||||
(dispatch [action whisper-identity])))
|
||||
(re-frame/dispatch [action whisper-identity])))
|
||||
|
||||
(defn on-toggle-participant [checked? whisper-identity]
|
||||
(let [action (if checked? :deselect-participant :select-participant)]
|
||||
(dispatch [action whisper-identity])))
|
||||
(re-frame/dispatch [action whisper-identity])))
|
||||
|
||||
(defn group-toggle-contact [{:keys [whisper-identity] :as contact}]
|
||||
[toogle-contact-view contact :is-contact-selected? on-toggle])
|
||||
@ -45,19 +47,16 @@
|
||||
:search-text search-text
|
||||
:search-key :contact-group-list
|
||||
:custom-title (title-with-count title contacts-count)
|
||||
:search-placeholder (label :t/search-contacts)})))
|
||||
:search-placeholder (i18n/label :t/search-contacts)})))
|
||||
|
||||
(defn toggle-list [contacts render-function]
|
||||
[react/view {:flex 1}
|
||||
[react/list-view
|
||||
{:dataSource (to-datasource contacts)
|
||||
:renderRow (fn [row _ _]
|
||||
(react/list-item ^{:key row} [render-function row]))
|
||||
:renderSeparator renderers/list-separator-renderer
|
||||
:renderFooter renderers/list-footer-renderer
|
||||
:renderHeader renderers/list-header-renderer
|
||||
:style cstyles/contacts-list
|
||||
:keyboardShouldPersistTaps :always}]])
|
||||
[list/flat-list {:style contacts.styles/contacts-list
|
||||
:data contacts
|
||||
:render-fn (fn [contact] [render-function contact])
|
||||
:footer list/default-footer
|
||||
:header list/default-header
|
||||
:keyboardShouldPersistTaps :always}]])
|
||||
|
||||
(defview contact-toggle-list []
|
||||
(letsubs [contacts [:all-added-group-contacts-filtered]
|
||||
@ -66,13 +65,13 @@
|
||||
[react/keyboard-avoiding-view {:style styles/group-container}
|
||||
[status-bar]
|
||||
[toggle-list-toolbar
|
||||
(label (if (= group-type :contact-group)
|
||||
:t/new-group
|
||||
:t/new-group-chat))
|
||||
(i18n/label (if (= group-type :contact-group)
|
||||
:t/new-group
|
||||
:t/new-group-chat))
|
||||
selected-contacts-count]
|
||||
[toggle-list contacts group-toggle-contact]
|
||||
(when (pos? selected-contacts-count)
|
||||
[sticky-button (label :t/next) #(dispatch [:navigate-to :new-group])])]))
|
||||
[sticky-button (i18n/label :t/next) #(re-frame/dispatch [:navigate-to :new-group])])]))
|
||||
|
||||
(defview add-contacts-toggle-list []
|
||||
(letsubs [contacts [:all-group-not-added-contacts-filtered]
|
||||
@ -83,9 +82,9 @@
|
||||
[toggle-list-toolbar (:name group) selected-contacts-count]
|
||||
[toggle-list contacts group-toggle-contact]
|
||||
(when (pos? selected-contacts-count)
|
||||
[sticky-button (label :t/save) #(do
|
||||
(dispatch [:add-selected-contacts-to-group])
|
||||
(dispatch [:navigate-back]))])]))
|
||||
[sticky-button (i18n/label :t/save) #(do
|
||||
(re-frame/dispatch [:add-selected-contacts-to-group])
|
||||
(re-frame/dispatch [:navigate-back]))])]))
|
||||
|
||||
(defview add-participants-toggle-list []
|
||||
(letsubs [contacts [:contacts-filtered :all-new-contacts]
|
||||
@ -96,6 +95,6 @@
|
||||
[toggle-list-toolbar chat-name selected-contacts-count]
|
||||
[toggle-list contacts group-toggle-participant]
|
||||
(when (pos? selected-contacts-count)
|
||||
[sticky-button (label :t/save) #(do
|
||||
(dispatch [:add-new-group-chat-participants])
|
||||
(dispatch [:navigate-back]))])]))
|
||||
[sticky-button (i18n/label :t/save) #(do
|
||||
(re-frame/dispatch [:add-new-group-chat-participants])
|
||||
(re-frame/dispatch [:navigate-back]))])]))
|
||||
|
@ -1,14 +1,13 @@
|
||||
(ns status-im.ui.screens.group.edit-contacts.views
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [re-frame.core :refer [dispatch]]
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.ui.components.contact.contact :refer [contact-view]]
|
||||
[status-im.ui.components.renderers.renderers :as renderers]
|
||||
[status-im.ui.components.react :refer [view list-view list-item]]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.status-bar.view :refer [status-bar]]
|
||||
[status-im.ui.components.toolbar.view :refer [toolbar-with-search]]
|
||||
[status-im.utils.listview :refer [to-datasource]]
|
||||
[status-im.ui.screens.group.styles :as styles]
|
||||
[status-im.i18n :refer [label]]))
|
||||
[status-im.i18n :as i18n]))
|
||||
|
||||
(defview contact-list-toolbar [title]
|
||||
(letsubs [show-search [:get-in [:toolbar-search :show]]
|
||||
@ -18,35 +17,33 @@
|
||||
:search-text search-text
|
||||
:search-key :contact-list
|
||||
:title title
|
||||
:search-placeholder (label :t/search-contacts)})))
|
||||
:search-placeholder (i18n/label :t/search-contacts)})))
|
||||
|
||||
(defn contacts-list [contacts extended? extend-options]
|
||||
[view {:flex 1}
|
||||
[list-view {:dataSource (to-datasource contacts)
|
||||
:enableEmptySections true
|
||||
:renderRow (fn [row _ _]
|
||||
(list-item
|
||||
^{:key row}
|
||||
[contact-view {:contact row
|
||||
:extended? extended?
|
||||
:extend-options (extend-options row)}]))
|
||||
:bounces false
|
||||
:keyboardShouldPersistTaps :always
|
||||
:renderSeparator renderers/list-separator-renderer
|
||||
:renderFooter renderers/list-footer-renderer
|
||||
:renderHeader renderers/list-header-renderer}]])
|
||||
[react/view {:flex 1}
|
||||
[list/flat-list {:data contacts
|
||||
:enableEmptySections true
|
||||
:renderRow (fn [contact]
|
||||
[contact-view {:contact contact
|
||||
:extended? extended?
|
||||
:extend-options (extend-options contact)}])
|
||||
|
||||
:bounces false
|
||||
:keyboardShouldPersistTaps :always
|
||||
:footer list/default-footer
|
||||
:header list/default-header}]])
|
||||
|
||||
(defn chat-extended-options [item]
|
||||
[{:value #(dispatch [:remove-group-chat-participants #{(:whisper-identity item)}])
|
||||
:text (label :t/remove)}])
|
||||
[{:value #(re-frame/dispatch [:remove-group-chat-participants #{(:whisper-identity item)}])
|
||||
:text (i18n/label :t/remove)}])
|
||||
|
||||
(defn contact-extended-options [group-id]
|
||||
(fn [item]
|
||||
[{:value #(dispatch [:remove-contact-from-group
|
||||
(:whisper-identity item)
|
||||
group-id])
|
||||
[{:value #(re-frame/dispatch [:remove-contact-from-group
|
||||
(:whisper-identity item)
|
||||
group-id])
|
||||
:accessibility-label :remove-button
|
||||
:text (label :t/remove-from-group)}]))
|
||||
:text (i18n/label :t/remove-from-group)}]))
|
||||
|
||||
(defview edit-chat-group-contact-list []
|
||||
(letsubs [chat-name [:chat :name]
|
||||
@ -54,7 +51,7 @@
|
||||
current-pk [:get :current-public-key]
|
||||
group-admin [:chat :group-admin]]
|
||||
(let [admin? (= current-pk group-admin)]
|
||||
[view styles/group-container
|
||||
[react/view styles/group-container
|
||||
[status-bar]
|
||||
[contact-list-toolbar chat-name]
|
||||
[contacts-list
|
||||
@ -71,7 +68,7 @@
|
||||
|
||||
(defview edit-contact-group-contact-list []
|
||||
(letsubs [group [:get-contact-group]]
|
||||
[view styles/group-container
|
||||
[react/view styles/group-container
|
||||
[status-bar]
|
||||
[contact-list-toolbar (:name group)]
|
||||
[contacts-list-view (:group-id group)]]))
|
||||
|
@ -5,15 +5,14 @@
|
||||
[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 :refer [view text touchable-highlight
|
||||
keyboard-avoiding-view list-view list-item]]
|
||||
keyboard-avoiding-view]]
|
||||
[status-im.ui.components.icons.vector-icons :as vi]
|
||||
[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 :refer [status-bar]]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.utils.platform :refer [platform-specific ios?]]
|
||||
[status-im.ui.components.sticky-button :refer [sticky-button]]
|
||||
[status-im.utils.listview :refer [to-datasource]]
|
||||
[status-im.ui.components.renderers.renderers :as renderers]
|
||||
[status-im.ui.components.contact.contact :refer [contact-view]]
|
||||
[status-im.ui.screens.group.styles :as styles]
|
||||
[status-im.i18n :refer [label]]
|
||||
@ -139,10 +138,9 @@
|
||||
(when save-btn-enabled?
|
||||
[sticky-button (label :t/save) #(dispatch [:set-contact-group-name])])])))
|
||||
|
||||
(defn render-row [row _ _]
|
||||
(list-item
|
||||
^{:key row}
|
||||
[contact-view {:contact row}]))
|
||||
(defn- render-contact [contact]
|
||||
[contact-view {:contact contact}])
|
||||
|
||||
|
||||
(defview new-group []
|
||||
(letsubs [contacts [:selected-group-contacts]
|
||||
@ -154,12 +152,11 @@
|
||||
[group-toolbar group-type false]
|
||||
[group-name-view]
|
||||
[view styles/list-view-container
|
||||
[list-view {:dataSource (to-datasource contacts)
|
||||
:enableEmptySections true
|
||||
:renderRow render-row
|
||||
:bounces false
|
||||
:keyboardShouldPersistTaps :always
|
||||
:renderSeparator renderers/list-separator-renderer}]]
|
||||
[list/flat-list {:data contacts
|
||||
:render-fn render-contact
|
||||
:bounces false
|
||||
:keyboardShouldPersistTaps :always
|
||||
:enableEmptySections true}]]
|
||||
(when save-btn-enabled?
|
||||
[sticky-button (label :t/save)
|
||||
(if (= group-type :contact-group)
|
||||
|
@ -1,31 +1,29 @@
|
||||
(ns status-im.ui.screens.network-settings.views
|
||||
(:require-macros [status-im.utils.views :as views])
|
||||
(:require
|
||||
[status-im.utils.listview :as lw]
|
||||
[re-frame.core :as rf]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[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.react :as react]
|
||||
[status-im.ui.components.icons.vector-icons :as vi]
|
||||
[status-im.ui.components.common.common :as common]
|
||||
[status-im.ui.components.renderers.renderers :as renderers]
|
||||
[status-im.ui.screens.network-settings.styles :as st]
|
||||
[status-im.i18n :as i18n]))
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[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.react :as react]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.common.common :as common]
|
||||
[status-im.ui.screens.network-settings.styles :as styles]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.i18n :as i18n]))
|
||||
|
||||
(defn network-icon [connected? size]
|
||||
[react/view (st/network-icon connected? size)
|
||||
[vi/icon :icons/network {:color (if connected? :white :gray)}]])
|
||||
[react/view (styles/network-icon connected? size)
|
||||
[vector-icons/icon :icons/network {:color (if connected? :white :gray)}]])
|
||||
|
||||
(defn network-badge [& [{:keys [name connected? options]}]]
|
||||
[react/view st/network-badge
|
||||
[react/view styles/network-badge
|
||||
[network-icon connected? 56]
|
||||
[react/view {:padding-left 16}
|
||||
[react/text {:style st/badge-name-text}
|
||||
[react/text {:style styles/badge-name-text}
|
||||
(or name (i18n/label :t/new-network))]
|
||||
(when connected?
|
||||
[react/text {:style st/badge-connected-text}
|
||||
[react/text {:style styles/badge-connected-text}
|
||||
(i18n/label :t/connected)])]])
|
||||
|
||||
(defn actions-view []
|
||||
@ -43,21 +41,19 @@
|
||||
{:text (i18n/label :t/paste-json-as-text) :value #(dispatch [:navigate-to :paste-json-text])}
|
||||
{:text (i18n/label :t/specify-rpc-url) :value #(dispatch [:navigate-to :add-rpc-url])}]]])
|
||||
|
||||
(defn render-row [current-network]
|
||||
(fn [{:keys [id name config] :as row} _ _]
|
||||
(defn render-network [current-network]
|
||||
(fn [{:keys [id name config] :as network}]
|
||||
(let [connected? (= id current-network)]
|
||||
(react/list-item
|
||||
^{:key row}
|
||||
[react/touchable-highlight
|
||||
{:on-press #(rf/dispatch [:navigate-to :network-details row])}
|
||||
[react/view st/network-item
|
||||
[network-icon connected? 40]
|
||||
[react/view {:padding-horizontal 16}
|
||||
[react/text {:style st/network-item-name-text}
|
||||
name]
|
||||
(when connected?
|
||||
[react/text {:style st/network-item-connected-text}
|
||||
(i18n/label :t/connected)])]]]))))
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:navigate-to :network-details network])}
|
||||
[react/view styles/network-item
|
||||
[network-icon connected? 40]
|
||||
[react/view {:padding-horizontal 16}
|
||||
[react/text {:style styles/network-item-name-text}
|
||||
name]
|
||||
(when connected?
|
||||
[react/text {:style styles/network-item-connected-text}
|
||||
(i18n/label :t/connected)])]]])))
|
||||
|
||||
(views/defview network-settings []
|
||||
(views/letsubs [{:keys [network networks]} [:get-current-account]]
|
||||
@ -66,17 +62,15 @@
|
||||
[toolbar/simple-toolbar
|
||||
(i18n/label :t/network-settings)]
|
||||
[react/view {:flex 1}
|
||||
[react/list-view {:dataSource (lw/to-datasource (vals networks))
|
||||
:renderRow (render-row network)
|
||||
:renderHeader #(react/list-item
|
||||
[react/view
|
||||
[actions-view]
|
||||
[common/bottom-shadow]
|
||||
[common/form-title (i18n/label :t/existing-networks)
|
||||
{:count-value (count networks)}]
|
||||
[common/list-header]])
|
||||
:renderFooter #(react/list-item [react/view
|
||||
[common/list-footer]
|
||||
[common/bottom-shadow]])
|
||||
:renderSeparator renderers/list-separator-renderer
|
||||
:style st/networks-list}]]]))
|
||||
[list/flat-list {:style styles/networks-list
|
||||
:data (vals networks)
|
||||
:render-fn (render-network network)
|
||||
:header [react/view
|
||||
[actions-view
|
||||
[common/bottom-shadow]
|
||||
[common/form-title (i18n/label :t/existing-networks)
|
||||
{:count-value (count networks)}]
|
||||
[common/list-header]]]
|
||||
:footer [react/view
|
||||
[common/list-footer]
|
||||
[common/bottom-shadow]]}]]]))
|
||||
|
@ -101,7 +101,7 @@
|
||||
[react/text {:style styles/asset-item-currency
|
||||
:uppercase? true
|
||||
:number-of-lines 1}
|
||||
symbol]]
|
||||
(clojure.core/name symbol)]]
|
||||
[list/item-icon {:icon :icons/forward}]]]]
|
||||
[add-asset]))
|
||||
|
||||
|
@ -146,17 +146,16 @@
|
||||
[list/item-primary label]
|
||||
[list/item-secondary symbol]]])
|
||||
|
||||
(defn- item-filter-type [{:keys [id label checked?]}]
|
||||
(let [kid (keyword id)]
|
||||
[item-filter {:icon (transaction-type->icon kid) :checked? checked? :path {:type kid}}
|
||||
[list/item-content
|
||||
[list/item-primary-only label]]]))
|
||||
(defn- render-item-filter [{:keys [id label checked?]}]
|
||||
[item-filter {:icon (transaction-type->icon id) :checked? checked? :path {:type id}}
|
||||
[list/item-content
|
||||
[list/item-primary-only label]]])
|
||||
|
||||
(defn- wrap-filter-data [m]
|
||||
;; TODO(jeluard) Restore tokens filtering once token support is added
|
||||
[{:title (i18n/label :t/transactions-filter-type)
|
||||
:key :type
|
||||
:renderItem (list/wrap-render-fn item-filter-type)
|
||||
:render-fn render-item-filter ;(list/wrap-render-fn item-filter-type)
|
||||
:data (:type m)}])
|
||||
|
||||
(defview filter-history []
|
||||
|
@ -1,20 +0,0 @@
|
||||
(ns status-im.utils.listview)
|
||||
|
||||
(defn clone-with-rows [ds rows]
|
||||
(.cloneWithRows ds (reduce (fn [ac el] (.push ac el) ac)
|
||||
(clj->js []) rows)))
|
||||
|
||||
(defn- data-source [config]
|
||||
(js/ReactNative.ListView.DataSource. (clj->js config)))
|
||||
|
||||
(defn to-datasource [items]
|
||||
(clone-with-rows (data-source {:rowHasChanged not=}) items))
|
||||
|
||||
(defn- clone-with-rows-inverted [ds rows]
|
||||
(let [rows (reduce (fn [ac el] (.push ac el) ac)
|
||||
(clj->js []) (reverse rows))
|
||||
row-ids (.reverse (.map rows (fn [_ index] index)))]
|
||||
(.cloneWithRows ds rows row-ids)))
|
||||
|
||||
(defn to-datasource-inverted [items]
|
||||
(clone-with-rows-inverted (data-source {:rowHasChanged not=}) items))
|
@ -16,7 +16,6 @@
|
||||
(def image-crop-picker #js {})
|
||||
(def image-resizer #js {})
|
||||
(def instabug #js {})
|
||||
(def invertible-scroll-view #js {})
|
||||
(def linear-gradient #js {})
|
||||
(def mapbox-gl #js {:setAccessToken (fn [])})
|
||||
(def nfc #js {})
|
||||
|
Loading…
x
Reference in New Issue
Block a user