implemented custom title for toolbar with search

added dapp icon to contact, fixed styles, fixed context menu warning,

implemented search input clearing, fixed styles, reworked styles

fixes for https://github.com/status-im/status-react/pull/826 code review

revert toolbar

contacts styles. global toolbar styles

toolbar style and small fixes for contacts

group contacts edit mode

groups reorder screen
This commit is contained in:
Andrey Shovkoplyas 2017-03-01 17:02:48 +03:00 committed by Roman Volosovskyi
parent d17646a6e9
commit 210a4823c9
70 changed files with 1070 additions and 396 deletions

View File

@ -26,6 +26,7 @@
"react-native-fs",
"react-native-dialogs",
"react-native-popup-menu",
"react-native-sortable-listview",
"react-native-image-resizer",
"react-native-image-crop-picker",
"react-native-webview-bridge",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 B

After

Width:  |  Height:  |  Size: 284 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 B

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 B

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 467 B

After

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

BIN
ios/SF-UI-Text-Semibold.otf Normal file

Binary file not shown.

View File

@ -68,6 +68,7 @@
E0AD9E8F495A4907B65104BF /* libRCTImageResizer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BEE3436791D42248F853999 /* libRCTImageResizer.a */; };
EC8998BFE2C04023A860C065 /* libRNNetworkInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 74B7BDFF464F43D3BA8EA040 /* libRNNetworkInfo.a */; };
EF2B5857B4A34E0C9707FB3F /* Octicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B3B19223008342D096AA356E /* Octicons.ttf */; };
F9238D6C1E5F055900C047B9 /* SF-UI-Text-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = F9238D6B1E5F055900C047B9 /* SF-UI-Text-Semibold.otf */; };
FD4F213C3873473CB703B1D2 /* libRNFS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674B3D9595A047AB8D518F4E /* libRNFS.a */; };
/* End PBXBuildFile section */
@ -468,6 +469,7 @@
F090E261B9854867A728CE4F /* RealmReact.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RealmReact.xcodeproj; path = "../node_modules/realm/react-native/ios/RealmReact.xcodeproj"; sourceTree = "<group>"; };
F3548417D8DA4362B6796A54 /* RNInstabug.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNInstabug.xcodeproj; path = "../node_modules/instabug-reactnative/ios/RNInstabug.xcodeproj"; sourceTree = "<group>"; };
F93B6663A59F4B26BD4DA525 /* RNNetworkInfo.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNNetworkInfo.xcodeproj; path = "../node_modules/react-native-network-info/ios/RNNetworkInfo.xcodeproj"; sourceTree = "<group>"; };
F9238D6B1E5F055900C047B9 /* SF-UI-Text-Semibold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-UI-Text-Semibold.otf"; sourceTree = "<group>"; };
FC1CBCFE6C906043D6CCEEE1 /* libPods-StatusImTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-StatusImTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
@ -671,6 +673,7 @@
2028E0111D4275BD00227DCD /* SF */ = {
isa = PBXGroup;
children = (
F9238D6B1E5F055900C047B9 /* SF-UI-Text-Semibold.otf */,
9ED2F4601D9D577B00B36508 /* SF-UI-Text-Bold.otf */,
9E0B01A01DDC5DA7002B0359 /* SF-UI-Text-Light.otf */,
9ED2F45D1D9D52DD00B36508 /* SF-UI-Text-Regular.otf */,
@ -1471,6 +1474,7 @@
9ED2F45F1D9D535A00B36508 /* SF-UI-Text-Medium.otf in Resources */,
2028DFFA1D4275B600227DCD /* SF-UI-Display-Regular.otf in Resources */,
2028DFF91D4275B600227DCD /* SF-UI-Display-Medium.otf in Resources */,
F9238D6C1E5F055900C047B9 /* SF-UI-Text-Semibold.otf in Resources */,
2028DFFC1D4275B600227DCD /* SF-UI-Display-Thin.otf in Resources */,
2028DFFB1D4275B600227DCD /* SF-UI-Display-Semibold.otf in Resources */,
D28AEFB4C39548EB80416889 /* Entypo.ttf in Resources */,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 344 B

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "icon_close_dark.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 B

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "icon_grab_gray.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

View File

@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "universal",
"filename" : "icon_dots_horizontal_dark.png",
"filename" : "icon_options_dark.png",
"scale" : "1x"
},
{

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

View File

@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "universal",
"filename" : "icon_dots_horizontal_gray.png",
"filename" : "icon_options_gray.png",
"scale" : "1x"
},
{

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

View File

@ -46,8 +46,8 @@
</dict>
</dict>
</dict>
<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for Instabug and Audio Messages</string>
<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for Instabug and Audio Messages</string>
<key>NSCameraUsageDescription</key>
<string>We need to access your camera</string>
<key>NSContactsUsageDescription</key>
@ -58,6 +58,7 @@
<string>We need to access your photo storage to give you an ability to select photos</string>
<key>UIAppFonts</key>
<array>
<string>SF-UI-Text-Semibold.otf</string>
<string>SF-UI-Text-Bold.otf</string>
<string>SF-UI-Text-Regular.otf</string>
<string>SF-UI-Text-Medium.otf</string>

View File

@ -69,6 +69,7 @@
"react-native-qrcode": "^0.2.2",
"react-native-randombytes": "^2.1.0",
"react-native-share": "1.0.17",
"react-native-sortable-listview": "^0.1.1",
"react-native-splash-screen": "1.0.9",
"react-native-swiper": "1.5.3",
"react-native-tcp": "^2.0.4",

View File

@ -25,8 +25,9 @@
[status-im.transactions.screen :refer [confirm]]
[status-im.chats-list.screen :refer [chats-list]]
[status-im.new-group.screen-public :refer [new-public-group]]
[status-im.new-group.screen-private :refer [new-group contact-group]];; TODO: confusion with names
[status-im.new-group.screen-private :refer [new-group contact-group]]
[status-im.new-group.views.contact-list :refer [contact-group-list]]
[status-im.new-group.views.reorder-groups :refer [reorder-groups]]
[status-im.participants.views.add :refer [new-participants]]
[status-im.participants.views.remove :refer [remove-participants]]
[status-im.group-settings.screen :refer [group-settings]]
@ -114,6 +115,7 @@
:contact-list main-tabs
:contact-list-search-results contacts-search-results
:group-contacts contact-list
:reorder-groups reorder-groups
:new-contact new-contact
:qr-scanner qr-scanner
:chat chat

View File

@ -8,6 +8,9 @@
:main {:height 0
:bar-style "dark-content"
:color styles/color-white}
:gray {:height 0
:bar-style "dark-content"
:color styles/color-light-gray}
:transparent {:height 20
:bar-style "light-content"
:translucent? true
@ -15,6 +18,13 @@
:modal {:height 0
:bar-style "light-content"
:color styles/color-black}}
:toolbar-new {:height 55
:padding-top 18
:padding-left 16
:padding-right 16}
:toolbar-title-container {:padding-left 30}
:toolbar-title-center? false
:toolbar-with-search-content {:padding-left 30}
:sized-text {:margin-top 0
:additional-height 0}
:chat {:new-message {:border-top-color styles/color-transparent
@ -35,6 +45,12 @@
:font-size 14}}}
:contacts {:subtitle {:color styles/color-gray4
:font-size 14}
:subtitle-count {:color styles/color-gray4
:font-size 14}
:info-container {:margin-left 16}
:contact-inner-container {:height 56}
:contacts-list-container {:padding-top 8
:padding-bottom 8}
:separator {:height 0}
:icon-check {:border-radius 2
:width 17
@ -43,7 +59,43 @@
:alignItems :center
:height 56
:padding-top 10
:backgroundColor styles/color-light-gray}}
:padding-left 16
:padding-right 14
:backgroundColor styles/color-light-gray}
:show-all {:padding-left 72
:height 56}
:show-all-text {:fontSize 14
:color styles/color-blue
:letter-spacing 0.5}
:show-all-text-font :medium
:contact-container {:padding-right 16}
:name-text {:fontSize 16
:line-height 24
:color styles/text1-color}}
:new-group {:group-name-text {:font-size 12}
:members-text {:font-size 14}
:members-text-count {:font-size 14}
:add-text {:margin-left 16
:letter-spacing 0.5
:font-size 14}
:delete-group-text {:letter-spacing 0.5
:font-size 14}
:delete-group-prompt-text {:font-size 14}
:contact-container {:height 56}
:delete-group-container {:padding-left 72}}
:reorder-groups {:order-item-container {:height 56
:background-color styles/color-white}
:order-item-icon {:padding-right 16}
:order-item-label {:padding-left 16
:font-size 16
:color styles/color-black
:line-height 24}
:reorder-list-container {:padding-top 16}
:order-item-contacts {:font-size 16
:line-height 24}}
:confirm-button-label {:color styles/color-white
:font-size 14
:letter-spacing 0.5}
:bottom-gradient {:height 3}
:input-label {:left 4}
:input-error-text {:margin-left 4}
@ -55,8 +107,7 @@
:toolbar-last-activity {:color styles/text2-color
:background-color :transparent
:top 0
:font-size 12}
:toolbar-title-container {:padding-left 16}})
:font-size 12}})
(def fonts
{:light {:font-family "sans-serif-light"}
@ -86,11 +137,13 @@
:tabs {:tab-shadows? true}
:chats {:action-button? true
:new-chat-in-toolbar? false}
:uppercase? true
:contacts {:action-button? true
:new-contact-in-toolbar? false
:uppercase-subtitles? false
:group-block-shadows? true}
:discover {:uppercase-subtitles? false}
:public-group-icon-container {:margin-top 4}
:private-group-icon-container {:margin-top 6}
:group-chat-focus-line-color styles/color-light-blue
:group-chat-focus-line-height 2
:public-group-chat-hash-style {:top 10 :left 4}})

View File

@ -117,8 +117,8 @@
[status-bar]
[toolbar {:hide-nav? (or (empty? accounts) show-actions? creating?)
:custom-content [toolbar-content-view]
:custom-action [toolbar-action]
:style (get-in platform-specific [:component-styles :toolbar])}]
:style (get-in platform-specific [:component-styles :toolbar])
:custom-action [toolbar-action]}]
[add-contact-bar]])
(defn get-intro-status-message [all-messages]

View File

@ -37,8 +37,8 @@
:title (label :t/chats)
:search-placeholder (label :t/search-for)
:nav-action (act/hamburger open-drawer)
:actions actions
:style (st/toolbar chats-scrolled?)}]))
:style (st/toolbar chats-scrolled?)
:actions actions}]))
(defn chats-action-button []
[action-button {:button-color color-blue

View File

@ -17,6 +17,7 @@
toolbar-background2)}
(get-in p/platform-specific [:component-styles :toolbar])))
(def gradient-top-bottom-shadow
["rgba(24, 52, 76, 0.165)"
"rgba(24, 52, 76, 0.03)"

View File

@ -166,28 +166,3 @@
(reg-handler ::clear-commands-callbacks
(fn [db [chat-id]]
(assoc-in db [::commands-callbacks chat-id] nil)))
(reg-handler :load-default-contacts!
(u/side-effect!
(fn [{:keys [chats groups]}]
(let [default-contacts js-res/default-contacts
default-dapps-group-contacts (mapv #(hash-map :identity (clojure.core/name (first %)))
(filter #(true? (:dapp? (second %))) default-contacts))]
(doseq [[id {:keys [name photo-path public-key add-chat?
dapp? dapp-url dapp-hash]}] default-contacts]
(let [id' (clojure.core/name id)]
(when-not (chats id')
(when add-chat?
(dispatch [:add-chat id' {:name (:en name)}]))
(dispatch [:add-contacts [{:whisper-identity id'
:name (:en name)
:photo-path photo-path
:public-key public-key
:dapp? dapp?
:dapp-url (:en dapp-url)
:dapp-hash dapp-hash}]]))))
(dispatch [:add-groups [{:group-id "dapps"
:name (label :t/contacts-group-dapps)
:order 0
:timestamp (random/timestamp)
:contacts default-dapps-group-contacts}]])))))

View File

@ -24,15 +24,14 @@
(get resources/contacts))
{:uri photo-path})]
[image {:source photo
:style (merge st/default-image-style
(st/image-style size))}]))
:style (st/image-style size)}]))
(defn dapp-badge [styles]
[view (:online-view-wrapper styles)
[view (:online-view styles)
(defn dapp-badge [{:keys [online-view-wrapper online-view online-dot-left online-dot-right]}]
[view online-view-wrapper
[view online-view
[view
[view (:online-dot-left styles)]
[view (:online-dot-right styles)]]]])
[view online-dot-left]
[view online-dot-right]]]])
(defn contact-badge [type styles]
(when (= type :edit)
@ -127,19 +126,19 @@
:default-chat-icon (st/default-chat-icon-message-status color)
:default-chat-icon-text st/message-status-icon-text}])
(defn contact-icon-view [contact styles]
(let [photo-path (:photo-path contact)
;; TODO: stub
type :online]
[view (:container styles)
(defn contact-icon-view [{:keys [photo-path name dapp?]} {:keys [container] :as styles}]
(let [photo-path photo-path]
[view container
(if-not (s/blank? photo-path)
[chat-icon photo-path styles]
[default-chat-icon (:name contact) styles])
[contact-badge type styles]]))
[default-chat-icon name styles])
(when dapp?
[dapp-badge styles])]))
(defn contact-icon-contacts-tab [contact]
[contact-icon-view contact
{:container st/container-chat-list
:online-view-wrapper st/online-view-wrapper
:online-view st/online-view
:online-dot-left st/online-dot-left
:online-dot-right st/online-dot-right

View File

@ -89,10 +89,10 @@
(def online-view-wrapper
{:position :absolute
:bottom -1
:right 0
:width 22
:height 22
:bottom -2
:right -2
:width 17
:height 17
:border-radius 11
:background-color :white})
@ -109,8 +109,8 @@
{:position :absolute
:bottom 2
:right 2
:width 18
:height 18
:width 13
:height 13
:border-radius 9
:background-color online-color})
@ -130,13 +130,13 @@
(def online-dot
{:position :absolute
:top 7
:width 4
:height 4
:top 5
:width 3
:height 3
:border-radius 2
:background-color color-white})
(def online-dot-left (merge online-dot {:left 4}))
(def online-dot-right (merge online-dot {:left 10}))
(def online-dot-left (merge online-dot {:left 2.8}))
(def online-dot-right (merge online-dot {:left 7.2}))
(def photo-pencil
{:margin-left 8
@ -172,8 +172,8 @@
:height 44})
(def container-chat-list
{:width 48
:height 48})
{:width 40
:height 40})
(def container-menu-item
{:width 32

View File

@ -1,5 +1,6 @@
(ns status-im.components.confirm-button
(:require [status-im.components.styles :as st]
[status-im.utils.platform :refer [platform-specific]]
[status-im.components.react :refer [view
text
touchable-highlight]]))
@ -7,4 +8,6 @@
(defn confirm-button [label on-press]
[touchable-highlight {:on-press on-press}
[view st/confirm-button
[text {:style st/confirm-button-label} label]]])
[text {:style (get-in platform-specific [:component-styles :confirm-button-label])
:uppercase? (get-in platform-specific [:uppercase?])}
label]]])

View File

@ -4,7 +4,7 @@
[status-im.i18n :refer [label]]
[status-im.utils.platform :refer [platform-specific ios?]]
[re-frame.core :refer [dispatch]]
[status-im.components.react :refer [view touchable-highlight]]))
[status-im.components.react :refer [view touchable-highlight text]]))
(def react-native-popup-menu (js/require "react-native-popup-menu"))
@ -43,7 +43,9 @@
trigger]]
[menu {:onSelect #(when % (do (%) nil))}
[menu-trigger trigger]
[menu-options st/context-menu
(for [option options]
[menu-options st/context-menu-options
(for [{:keys [style value] :as option} options]
^{:key option}
[menu-option option])]]))
[menu-option {:value value}
[text {:style (merge st/context-menu-text style)}
(:text option)]])]]))

View File

@ -0,0 +1,20 @@
(ns status-im.components.sortable-list-view
(:require [reagent.core :as r]
[status-im.components.react :refer [view
touchable-highlight
list-item]]))
(def sortable-list-view-class (r/adapt-react-class (js/require "react-native-sortable-listview")))
(defn sortable-list-view [{:keys [on-row-moved render-row] :as props}]
[sortable-list-view-class
(assoc props :on-row-moved #(on-row-moved (js->clj % :keywordize-keys true))
:render-row #(render-row (js->clj % :keywordize-keys true)))])
(defn touchable [inner]
[touchable-highlight (js->clj (.-props (r/current-component)))
[view
inner]])
(defn sortable-item [inner]
(list-item [touchable inner]))

View File

@ -3,7 +3,7 @@
(def color-transparent "transparent")
(def color-blue "#7099e6")
(def color-blue-transparent "#7099e632")
(def color-black "#000000de")
(def color-black "#000000")
(def color-purple "#a187d5")
(def color-gray "#838c93de")
(def color-gray2 "#8f838c93")
@ -24,12 +24,12 @@
(def text1-disabled-color "#555555")
(def text2-color color-gray)
(def text3-color color-blue)
(def online-color color-blue)
(def online-color color-light-blue)
(def new-messages-count-color color-blue-transparent)
(def chat-background color-light-gray)
(def selected-message-color "#E4E9ED")
(def selected-contact-color color-light-blue2)
(def separator-color color-gray4)
(def separator-color "#0000001f")
(def default-chat-color color-purple)
(def flex
@ -45,8 +45,8 @@
:color :white})
(def icon-back
{:width 24
:height 24})
{:width 8
:height 14})
(def icon-default
{:width 24
@ -96,17 +96,18 @@
:align-items :center
:background-color color-light-blue})
(def confirm-button-label
{:color color-white
:font-size 17
:line-height 20
:letter-spacing -0.2})
(def context-menu
{:customStyles {:optionsContainer {:padding-top 8
(def context-menu-options
{:customStyles {:optionsContainer {:elevation 2
:margin-top 30
:padding-top 8
:width 164
:padding-bottom 8}
:optionWrapper {:padding-left 16
:optionWrapper {:padding-left 16
:padding-right 16
:justify-content :center
:height 48}
:text {:font-size 15
:line-height 20}}})
:height 48}}})
(def context-menu-text
{:font-size 15
:line-height 20
:color text1-color})

View File

@ -29,12 +29,11 @@
(defn underline-container [background-color]
{:background-color background-color
:height 1
:align-items :center})
(defn underline [background-color width]
(defn underline [background-color width height]
{:background-color background-color
:height 1
:height height
:width width})
(defn error-text [color]

View File

@ -29,6 +29,7 @@
:label-color "#838c93"
:line-color separator-color
:focus-line-color separator-color
:focus-line-height 1
:error-color "#d50000"
:secure-text-entry false
:on-focus #()
@ -38,14 +39,16 @@
:auto-capitalize :sentences})
(defn field-animation [{:keys [top to-top font-size to-font-size
line-width to-line-width]}]
line-width to-line-width line-height to-line-height]}]
(let [duration (:label-animation-duration config)
animation (anim/parallel [(anim/timing top {:toValue to-top
:duration duration})
(anim/timing font-size {:toValue to-font-size
:duration duration})
(anim/timing line-width {:toValue to-line-width
:duration duration})])]
:duration duration})
(anim/timing line-height {:toValue to-line-height
:duration duration})])]
(anim/start animation (fn [arg]
(when (.-finished arg)
(log/debug "Field animation finished"))))))
@ -58,6 +61,7 @@
:label-top 0
:label-font-size 0
:line-width (anim/create-value 0)
:line-height (anim/create-value 1)
:max-line-width 100})
; Invoked once, both on the client and server, immediately before the initial
@ -80,7 +84,8 @@
(log/debug "input focused")
(r/set-state component {:has-focus true
:float-label? true})
(field-animation animation)
(field-animation (merge animation
{:to-line-width (:max-line-width (r/state component))}))
(when onFocus (onFocus))))
(defn on-input-blur [{:keys [component value animation onBlur]}]
@ -101,14 +106,14 @@
label-top
label-font-size
line-width
line-height
current-value
max-line-width
valid-value
temp-value
max-length]} (r/state component)
{:keys [wrapper-style input-style label-hidden? line-color focus-line-color secure-text-entry
label-color error-color error label value on-focus on-blur validator auto-focus
on-change-text on-change on-end-editing editable placeholder auto-capitalize]}
{:keys [wrapper-style input-style label-hidden? line-color focus-line-color focus-line-height
secure-text-entry label-color error-color error label value on-focus on-blur validator
auto-focus on-change-text on-change on-end-editing editable placeholder auto-capitalize]}
(merge default-props (r/props component))
line-color (if error error-color line-color)
focus-line-color (if error error-color focus-line-color)
@ -125,21 +130,24 @@
:secure-text-entry secure-text-entry
:auto-capitalize auto-capitalize
:on-focus #(on-input-focus {:component component
:animation {:top label-top
:to-top (:label-top config)
:font-size label-font-size
:to-font-size (:label-font-small config)
:line-width line-width
:to-line-width max-line-width}
:animation {:top label-top
:to-top (:label-top config)
:font-size label-font-size
:to-font-size (:label-font-small config)
:line-width line-width
:line-height line-height
:to-line-height focus-line-height}
:onFocus on-focus})
:on-blur #(on-input-blur {:component component
:value (or current-value value)
:animation {:top label-top
:to-top (:label-bottom config)
:font-size label-font-size
:to-font-size (:label-font-large config)
:line-width line-width
:to-line-width 0}
:animation {:top label-top
:to-top (:label-bottom config)
:font-size label-font-size
:to-font-size (:label-font-large config)
:line-width line-width
:line-height line-height
:to-line-width 0
:to-line-height 1}
:onBlur on-blur})
:on-change-text (fn [text]
(r/set-state component {:current-value text})
@ -159,7 +167,7 @@
:auto-focus (true? auto-focus)}]
[view {:style (st/underline-container line-color)
:onLayout #(r/set-state component {:max-line-width (get-width %)})}
[animated-view {:style (st/underline focus-line-color line-width)}]]
[animated-view {:style (st/underline focus-line-color line-width line-height)}]]
[text {:style (st/error-text error-color)} error]]))
(defn text-field [_ _]

View File

@ -3,34 +3,29 @@
(def nothing
{:image {:source nil
:style st/action-default}})
:style st/action-search}})
(defn hamburger [handler]
{:image {:source {:uri :icon_hamburger_dark}
:style st/action-default}
{:image {:source {:uri :icon_hamburger}
:style st/action-hamburger}
:handler handler})
(defn add [handler]
{:image {:source {:uri :icon_add}
:style st/action-default}
:handler handler})
(defn opts [handler]
{:image {:source {:uri :icon_options_dark}
:style st/action-default}
:style st/action-add}
:handler handler})
(defn search [handler]
{:image {:source {:uri :icon_search_dark}
:style st/action-default}
{:image {:source {:uri :icon_search}
:style st/action-search}
:handler handler})
(defn back [handler]
{:image {:source {:uri :icon_back_dark}
:style st/action-default}
:style st/action-back}
:handler handler})
(defn back-white [handler]
{:image {:source {:uri :icon_back_white}
:style st/action-default}
:style st/action-back}
:handler handler})

View File

@ -2,17 +2,15 @@
(:require [status-im.components.styles :refer [text1-color
color-white
color-light-gray
color-gray5
color-blue
color-black]]
[status-im.utils.platform :as p]))
color-black]]))
(def toolbar-background1 color-white)
(def toolbar-background2 color-light-gray)
(def toolbar-height 56)
(def toolbar-icon-width 24)
(def toolbar-icon-spacing 24)
(def toolbar-icon-width 32)
(def toolbar-icon-spacing 8)
(def toolbar-gradient
{:height 4})
@ -25,11 +23,6 @@
{:flex-direction :row
:height toolbar-height})
(def toolbar-line
{:height 1
:background-color color-gray5
:opacity 0.4})
(defn toolbar-nav-actions-container [actions]
{:width (when (and actions (> (count actions) 0))
(-> (+ toolbar-icon-width toolbar-icon-spacing)
@ -45,9 +38,9 @@
:padding-right 12})
(def toolbar-title-container
(merge (get-in p/platform-specific [:component-styles :toolbar-title-container])
{:flex 1
:justifyContent :center}))
{:flex 1
:alignItems :center
:justifyContent :center})
(def toolbar-title-text
{:margin-top 0
@ -68,11 +61,12 @@
:justify-content :center})
(def toolbar-with-search
{:background-color toolbar-background1
{:background-color toolbar-background2
:elevation 0})
(def toolbar-with-search-content
{:flex 1
:align-items :center
:justify-content :center})
(def toolbar-search-input
@ -85,8 +79,25 @@
(def toolbar-with-search-title
{:color color-black
:align-self :center
:text-align :center
:font-size 16})
(def action-default
;; Specific actions
(def action-hamburger
{:width 16
:height 12})
(def action-add
{:width 17
:height 17})
(def action-search
{:width 17
:height 17})
(def action-back
{:width 24
:height 24})

View File

@ -7,7 +7,7 @@
image
touchable-highlight]]
[status-im.components.sync-state.gradient :refer [sync-state-gradient-view]]
[status-im.components.styles :refer [icon-default
[status-im.components.styles :refer [icon-back
icon-search]]
[status-im.components.toolbar.actions :as act]
[status-im.components.toolbar.styles :as st]
@ -34,8 +34,8 @@
[touchable-highlight {:on-press #(dispatch [:navigate-back])
:accessibility-label id/toolbar-back-button}
[view (get-in platform-specific [:component-styles :toolbar-nav-action])
[image {:source {:uri :icon_back_dark}
:style icon-default}]]]))]
[image {:source {:uri :icon_back}
:style icon-back}]]]))]
(or custom-content
[view {:style st/toolbar-title-container}
[text {:style st/toolbar-title-text
@ -50,8 +50,7 @@
[view st/toolbar-action
[image action-image]]])
custom-action)]]
[sync-state-gradient-view]
[view st/toolbar-line]]))
[sync-state-gradient-view]]))
(defn- toolbar-search-submit [on-search-submit]
(let [text @(subscribe [:get-in [:toolbar-search :text]])]
@ -68,7 +67,10 @@
{:style st/toolbar-search-input
:auto-focus true
:placeholder search-placeholder
:on-change-text #(dispatch [:set-in [:toolbar-search :text] %])}]
:return-key-type "search"
:on-blur #(dispatch [:set-in [:toolbar-search :show] nil])
:on-change-text #(dispatch [:set-in [:toolbar-search :text] %])
:on-submit-editing #(toolbar-search-submit on-search-submit)}]
[view
[text {:style st/toolbar-with-search-title
:font :toolbar-title}
@ -81,11 +83,9 @@
style
on-search-submit]
:as opts}]
(let [toggle-search-fn #(do
(dispatch [:set-in [:toolbar-search :show] %])
(dispatch [:set-in [:toolbar-search :text] ""]))
(let [toggle-search-fn #(dispatch [:set-in [:toolbar-search :show] %])
actions (if-not show-search?
(into [(act/search #(toggle-search-fn search-key))] actions))]
(into actions [(act/search #(toggle-search-fn search-key))]))]
[toolbar {:style (merge st/toolbar-with-search style)
:nav-action (if show-search?
(act/back #(toggle-search-fn nil))

View File

@ -0,0 +1,47 @@
(ns status-im.components.toolbar-new.actions
(:require [status-im.components.toolbar-new.styles :as st]))
(def nothing
{:image {:source nil
:style st/action-default}})
(defn hamburger [handler]
{:image {:source {:uri :icon_hamburger_dark}
:style st/action-default}
:handler handler})
(defn add [handler]
{:image {:source {:uri :icon_add}
:style st/action-default}
:handler handler})
(defn opts [options]
{:image {:source {:uri :icon_options_dark}
:style st/action-default}
:options options})
(defn search [handler]
{:image {:source {:uri :icon_search_dark}
:style st/action-default}
:handler handler})
(defn search-icon []
{:image {:source {:uri :icon_search_dark}
:style (merge st/action-default
{:opacity 0.4})}})
(defn back [handler]
{:image {:source {:uri :icon_back_dark}
:style st/action-default}
:handler handler})
(defn back-white [handler]
{:image {:source {:uri :icon_back_white}
:style st/action-default}
:handler handler})
(defn close [handler]
{:image {:source {:uri :icon_close_dark}
:style st/action-default}
:handler handler})

View File

@ -0,0 +1,82 @@
(ns status-im.components.toolbar-new.styles
(:require [status-im.components.styles :refer [text1-color
color-white
color-light-gray
color-gray5
color-blue
color-black]]
[status-im.utils.platform :as p]))
(def toolbar-background1 color-white)
(def toolbar-icon-width 24)
(def toolbar-icon-height 24)
(def toolbar-icon-spacing 24)
(def toolbar-gradient
{:height 4})
(defn toolbar-wrapper [background-color]
{:backgroundColor (or background-color toolbar-background1)
:elevation 2})
(def toolbar
(merge {:flex-direction :row}
(get-in p/platform-specific [:component-styles :toolbar-new])))
(defn toolbar-nav-actions-container [actions]
(let [center? (get-in p/platform-specific [:component-styles :toolbar-title-center?])]
(merge {:flex-direction :row}
(when center?
{:width (when (and actions (pos? (count actions)))
(-> (+ toolbar-icon-width toolbar-icon-spacing)
(* (count actions))))}))))
(def toolbar-title-container
(merge (get-in p/platform-specific [:component-styles :toolbar-title-container])
{:flex 1
:align-self :stretch}))
(def toolbar-title-text
{:color text1-color
:letter-spacing -0.2
:font-size 17})
(def toolbar-border-container
(get-in p/platform-specific [:component-styles :toolbar-border-container]))
(def toolbar-border
(get-in p/platform-specific [:component-styles :toolbar-border]))
(defn toolbar-actions-container [actions-count custom]
(merge {:flex-direction :row}
(when (and (zero? actions-count) (not custom))
{:width (+ toolbar-icon-width toolbar-icon-spacing)})))
(def toolbar-action
{:width toolbar-icon-width
:height toolbar-icon-height
:margin-left toolbar-icon-spacing
:align-items :center
:justify-content :center})
(def toolbar-with-search
{:background-color toolbar-background1})
(def toolbar-with-search-content
(merge (get-in p/platform-specific [:component-styles :toolbar-with-search-content])
{:flex 1}))
(def toolbar-search-input
(merge (get-in p/platform-specific [:component-styles :toolbar-search-input])
{:flex 1
:padding-bottom 10
:font-size 17
:padding-top 0
:align-self :stretch
:color color-black}))
(def action-default
{:width 24
:height 24})

View File

@ -0,0 +1,114 @@
(ns status-im.components.toolbar-new.view
(:require [re-frame.core :refer [subscribe dispatch]]
[status-im.components.react :refer [view
icon
text
text-input
image
touchable-highlight]]
[status-im.components.sync-state.gradient :refer [sync-state-gradient-view]]
[status-im.components.styles :refer [icon-default
icon-search]]
[status-im.components.context-menu :refer [context-menu]]
[status-im.components.toolbar-new.actions :as act]
[status-im.components.toolbar-new.styles :as st]
[status-im.accessibility-ids :as id]
[status-im.utils.platform :refer [platform-specific]]
[reagent.core :as r]))
(defn toolbar [{title :title
nav-action :nav-action
hide-nav? :hide-nav?
actions :actions
custom-action :custom-action
background-color :background-color
custom-content :custom-content
style :style}]
(let [style (merge (st/toolbar-wrapper background-color) style)]
[view {:style style}
[view st/toolbar
[view (st/toolbar-nav-actions-container actions)
(when-not hide-nav?
(if nav-action
[touchable-highlight {:on-press (:handler nav-action)}
[view
[image (:image nav-action)]]]
[touchable-highlight {:on-press #(dispatch [:navigate-back])
:accessibility-label id/toolbar-back-button}
[view
[image {:source {:uri :icon_back_dark}
:style icon-default}]]]))]
(or custom-content
[view {:style st/toolbar-title-container}
[text {:style st/toolbar-title-text
:font :toolbar-title}
title]])
[view (st/toolbar-actions-container (count actions) custom-action)
(if actions
(for [{action-image :image
action-options :options
action-handler :handler} actions]
(with-meta
(cond (= action-image :blank)
[view st/toolbar-action]
action-options
[context-menu
[view st/toolbar-action
[image action-image]]
action-options]
:else
[touchable-highlight {:on-press action-handler}
[view st/toolbar-action
[image action-image]]])
{:key (str "action-" action-image)}))
custom-action)]]
[sync-state-gradient-view]
[view st/toolbar-border-container
[view st/toolbar-border]]]))
(def search-text-input (r/atom nil))
(defn- toolbar-with-search-content [{:keys [show-search?
search-placeholder
title
custom-title
on-search-submit]}]
[view st/toolbar-with-search-content
(if show-search?
[text-input
{:style st/toolbar-search-input
:ref #(reset! search-text-input %)
:auto-focus true
:placeholder search-placeholder
:on-change-text #(dispatch [:set-in [:toolbar-search :text] %])}]
(or custom-title
[view
[text {:style st/toolbar-title-text
:font :toolbar-title}
title]]))])
(defn toolbar-with-search [{:keys [show-search?
search-text
search-key
nav-action
actions
style
on-search-submit]
:as opts}]
(let [toggle-search-fn #(do
(dispatch [:set-in [:toolbar-search :show] %])
(dispatch [:set-in [:toolbar-search :text] ""]))
actions (if show-search?
(if (pos? (count search-text))
[(act/close #(do
(.clear @search-text-input)
(dispatch [:set-in [:toolbar-search :text] ""])))]
[(act/search-icon)])
(into [(act/search #(toggle-search-fn search-key))] actions))]
[toolbar {:style style
:nav-action (if show-search?
(act/back #(toggle-search-fn nil))
nav-action)
:custom-content [toolbar-with-search-content opts]
:actions actions}]))

View File

@ -46,8 +46,16 @@
[db [_ _ click-handler]]
(-> db
(assoc-in [:toolbar-search :show] nil)
(assoc-in [:contact-list-ui-props :edit?] false)
(assoc :contacts-click-handler click-handler)))
(defmethod nav/preload-data! :reorder-groups
[db [_ _]]
(assoc db :groups-order (->> (vals (:contact-groups db))
(remove :pending?)
(sort-by :order >)
(map :group-id))))
(register-handler :remove-contacts-click-handler
(fn [db]
(dissoc db
@ -208,21 +216,29 @@
(register-handler :load-default-contacts!
(u/side-effect!
(fn [{:keys [chats]}]
(doseq [[id {:keys [name photo-path public-key add-chat?
dapp? dapp-url dapp-hash]}] js-res/default-contacts]
(let [id' (clojure.core/name id)]
(when-not (chats id')
(when add-chat?
(dispatch [:add-chat id' {:name (:en name)}]))
(dispatch [:add-contacts [{:whisper-identity id'
:address (public-key->address id')
:name (:en name)
:photo-path photo-path
:public-key public-key
:dapp? dapp?
:dapp-url (:en dapp-url)
:dapp-hash dapp-hash}]])))))))
(fn [{:keys [chats groups]}]
(let [default-contacts js-res/default-contacts
default-dapps-group-contacts (mapv #(hash-map :identity (clojure.core/name (first %)))
(filter #(true? (:dapp? (second %))) default-contacts))]
(doseq [[id {:keys [name photo-path public-key add-chat?
dapp? dapp-url dapp-hash]}] default-contacts]
(let [id' (clojure.core/name id)]
(when-not (chats id')
(when add-chat?
(dispatch [:add-chat id' {:name (:en name)}]))
(dispatch [:add-contacts [{:whisper-identity id'
:address (public-key->address id')
:name (:en name)
:photo-path photo-path
:public-key public-key
:dapp? dapp?
:dapp-url (:en dapp-url)
:dapp-hash dapp-hash}]]))))
(dispatch [:add-groups [{:group-id "dapps"
:name (label :t/contacts-group-dapps)
:order 0
:timestamp (random/timestamp)
:contacts default-dapps-group-contacts}]])))))
(register-handler :add-contacts
(after save-contacts!)
@ -326,8 +342,8 @@
(register-handler :remove-contact-from-group
(u/side-effect!
(fn [_ [_ {:keys [whisper-identity]} group]]
(let [group' (update group :contacts (remove-contact-from-group whisper-identity))]
(fn [{:keys [contact-groups]} [_ {:keys [whisper-identity]} {:keys [group-id]}]]
(let [group' (update (contact-groups group-id) :contacts (remove-contact-from-group whisper-identity))]
(dispatch [:update-group group'])))))
(register-handler :remove-contact

View File

@ -15,9 +15,9 @@
[status-im.components.action-button :refer [action-button
action-button-item]]
[status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar.view :refer [toolbar-with-search toolbar]]
[status-im.components.toolbar.actions :as act]
[status-im.components.toolbar.styles :as tst]
[status-im.components.toolbar-new.view :refer [toolbar]]
[status-im.components.toolbar-new.actions :as act]
[status-im.components.toolbar-new.styles :as tst]
[status-im.components.drawer.view :refer [open-drawer]]
[status-im.components.icons.custom-icons :refer [ion-icon]]
[status-im.components.context-menu :refer [context-menu]]
@ -31,31 +31,24 @@
(def contacts-limit 5)
(def toolbar-options
[{:text (label :t/new-contact) :value #(dispatch [:navigate-to :new-contact])}
{:text (label :t/edit) :value #(dispatch [:set-in [:contacts-ui-props :edit?] true])}
{:text (label :t/new-group) :value #(dispatch [:open-contact-group-list])}])
[{:text (label :t/new-contact) :value #(dispatch [:navigate-to :new-contact])}
{:text (label :t/edit) :value #(dispatch [:set-in [:contacts-ui-props :edit?] true])}
{:text (label :t/new-group) :value #(dispatch [:open-contact-group-list])}
{:text (label :t/reorder-groups) :value #(dispatch [:navigate-to :reorder-groups])}])
(defn toolbar-actions []
(let [new-contact? (get-in platform-specific [:contacts :new-contact-in-toolbar?])]
[view st/toolbar-actions
[touchable-highlight
{:on-press #(dispatch [:navigate-to :group-contacts nil :show-search])}
[view st/search-btn
[icon :search_dark]]]
[view st/more-btn
[context-menu
[icon :options_dark]
(if new-contact? toolbar-options (rest toolbar-options))]]]))
[(act/search #(dispatch [:navigate-to :group-contacts nil :show-search]))
(act/opts (if new-contact? toolbar-options (rest toolbar-options)))]))
(defn toolbar-view []
[toolbar {:style tst/toolbar-with-search
:title (label :t/contacts)
[toolbar {:title (label :t/contacts)
:nav-action (act/hamburger open-drawer)
:custom-action (toolbar-actions)}])
:actions (toolbar-actions)}])
(defn toolbar-edit []
[toolbar {:style tst/toolbar-with-search
:nav-action (act/back #(dispatch [:set-in [:contacts-ui-props :edit?] false]))
[toolbar {:nav-action (act/back #(dispatch [:set-in [:contacts-ui-props :edit?] false]))
:actions [{:image :blank}]
:title (label :t/edit-contacts)}])
(defn options-btn [group]
@ -67,16 +60,15 @@
(defn subtitle-view [subtitle contacts-count group extended?]
[view (get-in platform-specific [:component-styles :contacts :group-header])
[text {:style (merge st/contact-group-subtitle
(get-in platform-specific [:component-styles :contacts :subtitle]))
:uppercase? (get-in platform-specific [:contacts :uppercase-subtitles?])
[text {:style (get-in platform-specific [:component-styles :contacts :subtitle])
:font :medium}
subtitle]
[text {:style (merge st/contact-group-count
(get-in platform-specific [:component-styles :contacts :subtitle]))
(get-in platform-specific [:component-styles :contacts :subtitle-count]))
:uppercase? (get-in platform-specific [:contacts :uppercase-subtitles?])
:font :medium}
(str contacts-count)]
[view {:flex 1}]
(when extended?
[options-btn group])])
@ -88,10 +80,6 @@
[linear-gradient {:style st/contact-group-header-gradient-top
:colors st/contact-group-header-gradient-top-colors}])
(defn on-scroll-animation [e show-toolbar-shadow?]
(let [offset (.. e -nativeEvent -contentOffset -y)]
(reset! show-toolbar-shadow? (pos? offset))))
(defn contact-group-form [{:keys [contacts contacts-count group edit? click-handler]}]
(let [shadows? (get-in platform-specific [:contacts :group-block-shadows?])
subtitle (:name group)]
@ -100,27 +88,36 @@
[subtitle-view subtitle contacts-count group edit?])
(when (and subtitle shadows?)
[group-top-view])
[view
[view st/contacts-list
(doall
(map (fn [contact]
^{:key contact}
[contact-view
{:contact contact
:extended? edit?
:on-click (when-not edit? click-handler)
:extend-options (when group
[{:value #(dispatch [:hide-contact contact])
:text (label :t/delete-contact)}
{:value #(dispatch [:remove-contact-from-group contact group])
:text (label :t/remove-from-group)}])}])
[view
[contact-view
{:contact contact
:extended? edit?
:on-click (when-not edit? click-handler)
:extend-options (when group
[{:value #(dispatch [:hide-contact contact])
:text (label :t/delete-contact)
:style st/delete-contact-text}
{:value #(dispatch [:remove-contact-from-group contact group])
:text (label :t/remove-from-group)}])}]
(when-not (= contact (last contacts))
[view st/contact-item-separator-wrapper
[view st/contact-item-separator]])])
contacts))]
(when (< contacts-limit contacts-count)
[view st/show-all
[touchable-highlight (when-not edit? {:on-press #(dispatch [:navigate-to :group-contacts group])})
[view
[text {:style st/show-all-text
:font :medium}
(str (- contacts-count contacts-limit) " " (label :t/more))]]]])
[view
[view st/contact-item-separator-wrapper
[view st/contact-item-separator]]
[view st/show-all
[touchable-highlight (when-not edit? {:on-press #(dispatch [:navigate-to :group-contacts group])})
[view
[text {:style st/show-all-text
:uppercase? (get-in platform-specific [:uppercase?])
:font (get-in platform-specific [:component-styles :contacts :show-all-text-font])}
(str (- contacts-count contacts-limit) " " (label :t/more))]]]]])
(when shadows?
[group-bottom-view])]))
@ -148,18 +145,13 @@
contacts-count [:added-contacts-count]
click-handler [:get :contacts-click-handler]
edit? [:get-in [:contacts-ui-props :edit?]]
groups [:all-added-groups]
show-toolbar-shadow? (r/atom false)]
groups [:all-added-groups]]
[view st/contacts-list-container
(if edit?
[toolbar-edit]
[toolbar-view])
(when @show-toolbar-shadow?
[linear-gradient {:style st/contact-group-header-gradient-bottom
:colors st/contact-group-header-gradient-bottom-colors}])
(if (pos? (+ (count groups) contacts-count))
[scroll-view {:style st/contact-groups
:onScroll #(on-scroll-animation % show-toolbar-shadow?)}
[scroll-view {:style st/contact-groups}
(when (pos? contacts-count)
[contact-group-form {:contacts contacts
:contacts-count contacts-count

View File

@ -5,16 +5,15 @@
color-white
color-separator
color-gray2
color-gray4
color-blue
color-light-red
color-gray]]
[status-im.components.toolbar.styles :refer [toolbar-background1 toolbar-background2]]
[status-im.utils.platform :as p]))
;; Contacts list
(def toolbar-shadow
{:height 2
:background-color toolbar-background2})
(def toolbar-actions
{:flex-direction :row})
@ -26,6 +25,10 @@
(merge (get-in p/platform-specific [:component-styles :main-tab-list])
{:flex 1}))
(def contacts-list
(merge (get-in p/platform-specific [:component-styles :contacts :contacts-list-container])
{:background-color color-white}))
(def empty-contact-groups
(merge contact-groups
{:align-items :center
@ -40,18 +43,11 @@
:font-size 16
:color color-gray2})
(def contacts-list
{:backgroundColor color-white})
(def contact-group
{:flex-direction :column})
(def contact-group-subtitle
{:margin-left 16})
(def contact-group-count
{:flex 1
:margin-left 8
{:margin-left 8
:opacity 0.6})
(def contact-group-header-gradient-top
@ -74,24 +70,25 @@
"rgba(24, 52, 76, 0.05)"])
(def show-all
{:flexDirection :row
:alignItems :center
:height 56
:backgroundColor color-white})
(merge (get-in p/platform-specific [:component-styles :contacts :show-all])
{:flexDirection :row
:alignItems :center
:backgroundColor color-white}))
(def show-all-text
{:marginLeft 72
:fontSize 14
:color text3-color
;; ios only:
:letterSpacing 0.5})
(get-in p/platform-specific [:component-styles :contacts :show-all-text]))
(def contact-separator-container
(def contact-item-separator-wrapper
{:background-color color-white})
(def contact-item-separator
(get-in p/platform-specific [:component-styles :contacts :separator]))
(def contact-container
{:flex-direction :row
:background-color color-white})
(merge (get-in p/platform-specific [:component-styles :contacts :contact-container])
{:flex-direction :row
:align-items :center
:background-color color-white}))
(def letter-container
{:paddingTop 11
@ -102,10 +99,6 @@
{:fontSize 24
:color text3-color})
(def contact-photo-container
{:marginTop 4
:marginLeft 12})
(def option-inner-container
{:flex 1
:flex-direction :row
@ -139,21 +132,20 @@
:height 8})
(def contact-inner-container
{:flex 1
:flexDirection :row
:height 56
:margin-right 16
:backgroundColor color-white})
(merge (get-in p/platform-specific [:component-styles :contacts :contact-inner-container])
{:flex 1
:flexDirection :row
:align-items :center
:padding-left 16
:backgroundColor color-white}))
(def info-container
{:flex 1
:flexDirection :column
:margin-left 12
:justifyContent :center})
(merge (get-in p/platform-specific [:component-styles :contacts :info-container])
{:flex 1
:flexDirection :column}))
(def name-text
{:fontSize 15
:color text1-color})
(get-in p/platform-specific [:component-styles :contacts :name-text]))
(def info-text
{:marginTop 1
@ -162,8 +154,7 @@
(def more-btn
{:width 24
:height 56
:margin-right 14
:height 24
:alignItems :center
:justifyContent :center})
@ -231,3 +222,6 @@
:background-color color-white
:align-items :center
:justify-content :center})
(def delete-contact-text
{:color color-light-red})

View File

@ -30,12 +30,15 @@
(sort-contacts)
(reaction)))))
(defn filter-group-contacts [group-contacts contacts]
(filter #(group-contacts (:whisper-identity %)) contacts))
(register-sub :all-added-group-contacts
(fn [db [_ group-id]]
(let [contacts (subscribe [:all-added-contacts])
group-contacts (reaction (into #{} (map #(:identity %)
(get-in @db [:contact-groups group-id :contacts]))))]
(reaction (filter #(@group-contacts (:whisper-identity %)) @contacts)))))
(reaction (filter-group-contacts @group-contacts @contacts)))))
(register-sub :all-added-group-contacts-with-limit
(fn [db [_ group-id limit]]

View File

@ -18,7 +18,8 @@
[text {:style st/letter-text} letter])])
(defn options-btn [contact more-options]
(let [options [{:value #(dispatch [:hide-contact contact]) :text (label :t/delete-contact)}]]
(let [options [{:value #(dispatch [:hide-contact contact]) :text (label :t/delete-contact)
:style st/delete-contact-text}]]
[view st/more-btn
[context-menu
[icon :options_gray]
@ -26,7 +27,7 @@
;;TODO: maybe it's better to have only one global component contact-view with the types: default, extended and toggle
;;TODO: at the moment toggle in the other component new-group-contact
(defview contact-view [{{:keys [whisper-identity letter dapp?] :as contact} :contact
(defview contact-view [{{:keys [whisper-identity letter] :as contact} :contact
:keys [extended? letter? on-click extend-options info]}]
[chat [:get-chat whisper-identity]]
[touchable-highlight
@ -38,6 +39,4 @@
[letter-view letter])
[contact-inner-view {:contact contact :info info}]
(when extended?
[options-btn contact extend-options])]
[view st/contact-separator-container
[view (get-in platform-specific [:component-styles :contacts :separator])]]]])
[options-btn contact extend-options])]]])

View File

@ -6,7 +6,7 @@
[status-im.i18n :refer [get-contact-translated label]]))
(defn contact-photo [contact]
[view st/contact-photo-container
[view
[contact-icon-contacts-tab contact]])
(defn contact-inner-view

View File

@ -3,15 +3,16 @@
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[status-im.components.react :refer [view text
image
icon
touchable-highlight
list-view
list-item]]
[status-im.contacts.views.contact :refer [contact-view]]
[status-im.components.text-field.view :refer [text-field]]
[status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar.view :refer [toolbar-with-search toolbar]]
[status-im.components.toolbar.actions :as act]
[status-im.components.toolbar.styles :refer [toolbar-background1]]
[status-im.components.toolbar-new.view :refer [toolbar-with-search toolbar]]
[status-im.components.toolbar-new.actions :as act]
[status-im.components.toolbar-new.styles :refer [toolbar-background1]]
[status-im.components.drawer.view :refer [drawer-view open-drawer]]
[status-im.components.image-button.view :refer [scan-button]]
[status-im.contacts.styles :as st]
@ -42,14 +43,20 @@
[text {:style st/name-text}
(label :t/new-public-group-chat)]]]]]])
(defn render-row [chat-modal click-handler action params]
(defn render-row [chat-modal click-handler action params group edit?]
(fn [row _ _]
(list-item
^{:key row}
[contact-view {:contact row
:letter? chat-modal
:on-click (when click-handler
#(click-handler row action params))}])))
[contact-view {:contact row
:letter? chat-modal
:extended? edit?
:extend-options (when group
[{:value #(dispatch [:hide-contact row])
:text (label :t/delete-contact)}
{:value #(dispatch [:remove-contact-from-group row group])
:text (label :t/remove-from-group)}])
:on-click (when (and (not edit?) click-handler)
#(click-handler row action params))}])))
(defn contact-list-entry [{:keys [click-handler icon icon-style label]}]
[touchable-highlight
@ -63,23 +70,36 @@
:number-of-lines 1}
label]]]]])
(defview contact-list-toolbar []
[group [:get :contacts-group]
modal [:get :modal]
show-search [:get-in [:toolbar-search :show]]]
[view
[status-bar]
(toolbar-with-search
{:show-search? (= show-search :contact-list)
: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-for)
:actions (when modal
(act/back #(dispatch [:navigate-back])))})])
(defview contact-list-toolbar-edit [group]
[toolbar {:nav-action (act/back #(dispatch [:set-in [:contact-list-ui-props :edit?] false]))
:actions [{:image :blank}]
:title (if-not group
(label :t/contacts)
(or (:name group) (label :t/contacts-group-new-chat)))}])
(defview contacts-list-view [group modal click-handler action]
(defview contact-list-toolbar [group]
[modal [:get :modal]
show-search [:get-in [:toolbar-search :show]]
search-text [:get-in [:toolbar-search :text]]]
(toolbar-with-search
{:show-search? (= show-search :contact-list)
: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 (if modal
(act/back #(dispatch [:navigate-back]))
[(act/opts [{:text (label :t/edit)
:value #(dispatch [:set-in [:contact-list-ui-props :edit?] true])}])])}))
(defn render-separator [_ row-id _]
(list-item ^{:key row-id}
[view st/contact-item-separator-wrapper
[view st/contact-item-separator]]))
(defview contacts-list-view [group modal click-handler action edit?]
[contacts [:all-added-group-contacts-filtered (:group-id group)]
params [:get :contacts-click-params]]
(let [show-new-group-chat? (and (= group :people)
@ -87,25 +107,30 @@
(when contacts
[list-view {:dataSource (lw/to-datasource contacts)
:enableEmptySections true
:renderRow (render-row modal click-handler action params)
:renderRow (render-row modal click-handler action params group edit?)
:bounces false
:keyboardShouldPersistTaps true
:renderHeader #(list-item
[view
(if show-new-group-chat?
[new-group-chat-view])
[view st/spacing-top]])
(when show-new-group-chat?
[new-group-chat-view])])
:renderFooter #(list-item [view st/spacing-bottom])
:renderSeparator render-separator
:style st/contacts-list}])))
(defview contact-list []
[action [:get :contacts-click-action]
modal [:get :modal]
edit? [:get-in [:contact-list-ui-props :edit?]]
click-handler [:get :contacts-click-handler]
group [:get :contacts-group]]
[drawer-view
[view st/contacts-list-container
[contact-list-toolbar]
[view {:flex 1}
[view
[status-bar]
(if edit?
[contact-list-toolbar-edit group]
[contact-list-toolbar group])]
;; todo add stub
(when modal
[view
@ -122,4 +147,4 @@
:label (label (if (= :request action)
:t/show-qr
:t/scan-qr))}]])
[contacts-list-view group modal click-handler action]]])
[contacts-list-view group modal click-handler action edit?]]])

View File

@ -24,6 +24,7 @@
[status-im.chats-list.screen :refer [chats-list]]
[status-im.new-group.screen-private :refer [new-group contact-group]]
[status-im.new-group.views.contact-list :refer [contact-group-list]]
[status-im.new-group.views.reorder-groups :refer [reorder-groups]]
[status-im.new-group.screen-public :refer [new-public-group]]
[status-im.participants.views.add :refer [new-participants]]
[status-im.participants.views.remove :refer [remove-participants]]
@ -93,6 +94,7 @@
:contact-list main-tabs
:contact-list-search-results contacts-search-results
:group-contacts contact-list
:reorder-groups reorder-groups
:contact-group contact-group
:contact-group-list contact-group-list
:new-contact new-contact

View File

@ -16,6 +16,13 @@
:color "#2f3031"}}
:toolbar {:border-bottom-color styles/color-gray3
:border-bottom-width 0.5}
:toolbar-new {:height 56
:padding-top 20
:padding-left 16
:padding-right 16}
:toolbar-title-container {:align-items :center}
:toolbar-title-center? true
:toolbar-with-search-content {:align-items :center}
:sized-text {:margin-top -5
:additional-height 5}
:actions-list-view {:border-bottom-color styles/color-gray3
@ -40,34 +47,87 @@
:icon {:padding-top 0
:bottom -4
:justify-content :flex-end}}}
:contacts {:subtitle {:color styles/color-black
:contacts {:subtitle {:color styles/text1-color
:font-size 16
:letter-spacing -0.2}
:separator {:margin-left 68
:subtitle-count {:color styles/color-gray4
:font-size 16
:letter-spacing -0.2}
:separator {:margin-left 72
:height 1
:background-color styles/color-gray5
:opacity 0.4}
:opacity 0.5}
:info-container {:margin-left 16}
:contact-inner-container {:height 63}
:icon-check {:border-radius 50
:width 24
:height 24}
:group-header {:flexDirection :row
:alignItems :center
:margin-top 24
:padding-left 16
:padding-right 16
:height 53
:backgroundColor styles/color-white}}
:backgroundColor styles/color-white}
:show-all {:padding-left 72
:height 64}
:show-all-text {:fontSize 16
:color styles/color-gray4
:letter-spacing -0.2}
:show-all-text-font :default
:contact-container {:padding-right 16}
:name-text {:fontSize 17
:line-height 20
:letter-spacing -0.2
:color styles/text1-color}}
:new-group {:group-name-text {:font-size 13}
:members-text {:letter-spacing -0.2
:font-size 16}
:members-text-count {:letter-spacing -0.2
:font-size 16}
:add-text {:margin-left 14
:letter-spacing -0.2
:font-size 17
:line-height 20}
:delete-group-text {:letter-spacing -0.2
:font-size 17
:line-height 20}
:delete-group-prompt-text {:font-size 13
:letter-spacing -0.1}
:contact-container {:height 63}
:delete-group-container {:padding-left 68}}
:reorder-groups {:order-item-separator {:margin-left 16
:opacity 0.5}
:order-item-container {:height 63}
:order-item-icon {:padding-right 20}
:order-item-label {:padding-left 16
:font-size 17
:line-height 20
:letter-spacing -0.2}
:order-item-contacts {:font-size 17
:line-height 20
:letter-spacing -0.2}}
:confirm-button-label {:color styles/color-white
:font-size 17
:line-height 20
:letter-spacing -0.2}
:bottom-gradient {:height 1}
:input-label {:left 0}
:input-error-text {:margin-left 0}
:main-tab-list {:margin-bottom 72}
:toolbar-search-input {:padding-left 10}
:toolbar-nav-action {:width 46
:height 56
:align-items :center
:justify-content :center}
:toolbar-border-container {:background-color styles/color-white}
:toolbar-border {:height 1
:background-color styles/color-gray5
:opacity 0.5}
:toolbar-last-activity {:color styles/text2-color
:background-color :transparent
:top 0
:font-size 14}
:toolbar-title-container {:align-items :center}})
:font-size 14}})
(def fonts
{:light {:font-family "SFUIText-Light"}
@ -75,7 +135,7 @@
:medium {:font-family "SFUIText-Medium"}
:bold {:font-family "SFUIText-Bold"}
:toolbar-title {:font-family "SFUIText-Medium"}})
:toolbar-title {:font-family "SFUIText-Semibold"}})
;; Dialogs
@ -96,12 +156,14 @@
:tabs {:tab-shadows? false}
:chats {:action-button? false
:new-chat-in-toolbar? true}
:uppercase? false
:contacts {:action-button? false
:new-contact-in-toolbar? true
:uppercase-subtitles? true
:group-block-shadows? false}
:discover {:uppercase-subtitles? true}
:public-group-icon-container {:margin-top 2}
:private-group-icon-container {:margin-top 2}
:group-chat-focus-line-color styles/color-gray5
:group-chat-focus-line-height 1
:public-group-chat-hash-style {:top 6 :left 3}})

View File

@ -218,8 +218,7 @@
(-> (fn [db [_ new-group]]
(assoc db :new-group new-group))
((enrich update-group))
((after update-group!))
((after show-contact-list!))))
((after update-group!))))
(defn save-groups! [{:keys [new-groups]} _]
(groups/save-all new-groups))
@ -258,3 +257,35 @@
(defmethod nav/preload-data! :new-public-group
[db]
(dissoc db :public-group/topic))
(defn move-item [v from to]
(if (< from to)
(concat (subvec v 0 from)
(subvec v (inc from) (inc to))
[(v from)]
(subvec v (inc to)))
(concat (subvec v 0 to)
[(v from)]
(subvec v to from)
(subvec v (inc from)))))
(register-handler :change-group-order
(fn [{:keys [groups-order] :as db} [_ from to]]
(if (>= to 0)
(assoc db :groups-order (move-item (vec groups-order) from to))
db)))
(register-handler :update-groups
(after save-groups!)
(fn [db [_ new-groups]]
(-> db
(update :contact-groups merge (map #(vector (:group-id %) %) new-groups))
(assoc db :new-groups new-groups))))
(register-handler :save-group-order
(u/side-effect!
(fn [{:keys [groups-order contact-groups] :as db} _]
(let [new-groups (mapv #(assoc (contact-groups (second %)) :order (first %))
(map-indexed vector (reverse groups-order)))]
(dispatch [:update-groups new-groups])
(dispatch [:navigate-to-clean :contact-list])))))

View File

@ -3,6 +3,7 @@
(:require [re-frame.core :refer [subscribe dispatch]]
[status-im.resources :as res]
[status-im.contacts.views.contact :refer [contact-view]]
[status-im.contacts.styles :as cst]
[status-im.components.react :refer [view
text
image
@ -12,10 +13,9 @@
list-item]]
[status-im.components.text-field.view :refer [text-field]]
[status-im.components.confirm-button :refer [confirm-button]]
[status-im.components.styles :refer [color-blue
separator-color]]
[status-im.components.styles :refer [color-blue color-gray5]]
[status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar.view :refer [toolbar-with-search toolbar]]
[status-im.components.toolbar-new.view :refer [toolbar]]
[status-im.utils.platform :refer [platform-specific]]
[status-im.utils.listview :refer [to-datasource]]
[status-im.new-group.views.contact :refer [new-group-contact]]
@ -40,17 +40,19 @@
[new-chat-name [:get :new-chat-name]]
[view
[text-field
{:error (when
(not (s/valid? ::v/not-illegal-name new-chat-name))
(label :t/illegal-group-chat-name))
:wrapper-style st/group-chat-name-wrapper
:error-color color-blue
:line-color separator-color
:label-hidden? true
:input-style st/group-chat-name-input
:auto-focus true
:on-change-text #(dispatch [:set :new-chat-name %])
:value new-chat-name}]])
{:error (when
(not (s/valid? ::v/not-illegal-name new-chat-name))
(label :t/illegal-group-chat-name))
:error-color color-blue
:wrapper-style st/group-chat-name-wrapper
:line-color color-gray5
:focus-line-color st/group-chat-focus-line-color
:focus-line-height st/group-chat-focus-line-height
:label-hidden? true
:input-style st/group-chat-name-input
:auto-focus true
:on-change-text #(dispatch [:set :new-chat-name %])
:value new-chat-name}]])
(defview new-group []
[contacts [:all-added-contacts]]
@ -71,35 +73,50 @@
[list-view
{:dataSource (to-datasource contacts)
:renderRow (fn [row _ _]
(list-item [new-group-contact row]))
:style st/contacts-list}]]])
(list-item [new-group-contact row]))}]]])
(defview new-contacts-group-toolbar [edit?]
[view
[status-bar]
[toolbar
{:title (label (if edit? :t/edit-group :t/new-group))}]])
{:title (label (if edit? :t/edit-group :t/new-group))
:actions [{:image :blank}]}]])
(defn chat-name-view [contacts-count]
[view st/chat-name-container
[text {:style st/group-name-text
:font :medium}
[text {:style st/group-name-text}
(label :t/group-name)]
[group-name-input]
[text {:style st/members-text
:font :medium}
(str (label :t/group-members) " " contacts-count)]
[view st/members-container
[text {:style st/members-text
:font :medium}
(label :t/group-members)]
[text {:style st/members-text-count
:font :medium}
contacts-count]]
[touchable-highlight {:on-press #(dispatch [:navigate-forget :contact-group-list])}
[view st/add-container
[icon :add_blue st/add-icon]
[text {:style st/add-text} (label :t/add-members)]]]])
[view st/add-icon-container
[icon :add_blue st/add-icon]]
[text {:style st/add-text
:font :medium
:uppercase? (get-in platform-specific [:uppercase?])}
(label :t/add-members)]]]])
(defn delete-btn [on-press]
[touchable-highlight {:on-press on-press}
[view st/delete-group-container
[text {:style st/delete-group-text} (label :t/delete-group)]
[text {:style st/delete-group-text
:font :medium
:uppercase? (get-in platform-specific [:uppercase?])}
(label :t/delete-group)]
[text {:style st/delete-group-prompt-text} (label :t/delete-group-prompt)]]])
(defn render-separator [_ row-id _]
(list-item ^{:key row-id}
[view cst/contact-item-separator-wrapper
[view cst/contact-item-separator]]))
;;TODO: should be refactored into one common function for group chats and contact groups
(defview contact-group []
[contacts [:selected-group-contacts]
@ -119,9 +136,11 @@
:extend-options [{:value #(dispatch [:deselect-contact (:whisper-identity row)])
:text (label :t/remove-from-group)}]
:extended? true}]))
:style st/contacts-list}]
:renderSeparator render-separator}]
(when group
[delete-btn #(dispatch [:update-group (assoc group :pending? true)])])
[delete-btn #(do
(dispatch [:update-group (assoc group :pending? true)])
(dispatch [:navigate-to-clean :contact-list]))])
(when save-btn-enabled?
[confirm-button (label :t/save) (if group
#(dispatch [:update-group-after-edit group group-name])

View File

@ -11,7 +11,7 @@
list-item]]
[status-im.components.text-field.view :refer [text-field]]
[status-im.components.styles :refer [color-blue
separator-color]]
color-gray4]]
[status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar.view :refer [toolbar]]
[status-im.utils.listview :refer [to-datasource]]
@ -45,7 +45,7 @@
(label :t/topic-format))
:wrapper-style st/group-chat-name-wrapper
:error-color color-blue
:line-color separator-color
:line-color color-gray4
:label-hidden? true
:input-style st/group-chat-topic-input
:auto-focus true

View File

@ -5,9 +5,17 @@
text2-color
color-light-blue
color-light-red
color-light-gray
selected-contact-color
color-gray4]]
[status-im.utils.platform :refer [platform-specific]]))
color-gray4
color-gray5]]
[status-im.utils.platform :refer [platform-specific] :as p]))
(defn ps-reorder [item]
(get-in platform-specific [:component-styles :reorder-groups item]))
(defn ps-new-group [item]
(get-in platform-specific [:component-styles :new-group item]))
(defn toolbar-icon [enabled?]
{:width 20
@ -19,12 +27,23 @@
:flex-direction :column
:background-color color-white})
(def reorder-groups-container
{:flex 1
:flex-direction :column
:background-color color-light-gray})
(def reorder-list-container
(merge {:flex 1}
(ps-reorder :reorder-list-container)))
(def chat-name-container
{:margin-left 16})
{:margin-top 21
:margin-left 16})
(def group-chat-name-input
{:font-size 14
:color text1-color})
{:font-size 17
:letter-spacing -0.2
:color text1-color})
(def group-chat-topic-input
{:font-size 14
@ -38,31 +57,46 @@
:position :absolute}
(get-in platform-specific [:public-group-chat-hash-style])))
(def group-chat-focus-line-color
(get-in platform-specific [:group-chat-focus-line-color]))
(def group-chat-focus-line-height
(get-in platform-specific [:group-chat-focus-line-height]))
(def group-chat-name-wrapper
{:padding-top 0})
{:padding-top 0
:height 40
:padding-bottom 0})
(def group-name-text
{:margin-top 11
:margin-bottom 10
:letter-spacing -0.1
:color color-gray4
:font-size 13
:line-height 20})
(merge (ps-new-group :group-name-text)
{:letter-spacing -0.1
:color color-gray4}))
(def members-container
{:flex-direction :row
:padding-top 20})
(def members-text
{:margin-top 10
:margin-bottom 8
:letter-spacing -0.2
:color color-gray4
:font-size 16
:line-height 19})
(merge (ps-new-group :members-text)
{:color color-gray4}))
(def members-text-count
(merge (ps-new-group :members-text-count)
{:margin-left 8
:color color-gray4
:opacity 0.6}))
(def add-container
{:flex-direction :row
:align-items :center
:margin-top 16
:margin-bottom 16
:margin-right 20})
:height 64
:margin-top 12})
(def add-icon-container
{:width 40
:align-items :center
:justify-content :center})
(def add-icon
{:align-items :center
@ -70,31 +104,22 @@
:height 24})
(def add-text
{:margin-left 32
:color color-light-blue
:letter-spacing -0.2
:font-size 17
:line-height 20})
(merge (ps-new-group :add-text)
{:color color-light-blue}))
(def delete-group-text
{:color color-light-red
:letter-spacing 0.5
:font-size 14
:line-height 20})
(merge (ps-new-group :delete-group-text)
{:color color-light-red}))
(def delete-group-prompt-text
{:color color-gray4
:font-size 14
:line-height 20})
(def contacts-list
{:background-color :white})
(merge (ps-new-group :delete-group-prompt-text)
{:color color-gray4}))
(def contact-container
{:flex-direction :row
:justify-content :center
:align-items :center
:height 56})
(merge (ps-new-group :contact-container)
{:flex-direction :row
:justify-content :center
:align-items :center}))
(def selected-contact
{:background-color selected-contact-color})
@ -115,6 +140,52 @@
:height 12})
(def delete-group-container
{:height 56
:padding-left 72
:margin-top 15})
(merge (ps-new-group :delete-group-container)
{:height 64
:padding-top 12}))
(def order-item-container
{:background-color color-white})
(def order-item-inner-container
(merge {:flex-direction :row
:align-items :center}
(ps-reorder :order-item-container)))
(def order-item-label
(ps-reorder :order-item-label))
(def order-item-contacts
(merge (ps-reorder :order-item-contacts)
{:padding-left 8
:color color-gray4}))
(def order-item-icon
(ps-reorder :order-item-icon))
(def order-item-separator-wrapper
{:background-color color-white})
(def order-item-separator
(merge {:height 1
:background-color color-gray5}
(ps-reorder :order-item-separator)))
(def toolbar-title-with-count-text
{:color text1-color
:letter-spacing -0.2
:font-size 17})
(def toolbar-title-with-count-text-count
(merge toolbar-title-with-count-text
{:color "#628fe3"}))
(def toolbar-title-with-count
{:flex-direction :row})
(def toolbar-title-with-count-container
{:padding-left 6})

View File

@ -11,9 +11,11 @@
(let [contacts (subscribe [:get :selected-contacts])]
(reaction (count @contacts)))))
(defn filter-contacts [selected-contacts added-contacts]
(filter #(selected-contacts (:whisper-identity %)) added-contacts))
(register-sub :selected-group-contacts
(fn [_ _]
(let [selected-contacts (subscribe [:get :selected-contacts])
added-contacts (subscribe [:all-added-contacts])]
(reaction (do @selected-contacts ;;TODO: doesn't work without this line :(
(filter #(@selected-contacts (:whisper-identity %)) @added-contacts))))))
(reaction (filter-contacts @selected-contacts @added-contacts)))))

View File

@ -24,6 +24,4 @@
[view (merge st/icon-check-container
{:background-color (if checked color-light-blue color-gray5)})
(when checked
[icon :check_on st/check-icon])]]]
[view cst/contact-separator-container
[view (get-in platform-specific [:component-styles :contacts :separator])]]]])
[icon :check_on st/check-icon])]]]]])

View File

@ -7,32 +7,52 @@
list-item]]
[status-im.components.confirm-button :refer [confirm-button]]
[status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar.view :refer [toolbar-with-search]]
[status-im.components.toolbar-new.view :refer [toolbar-with-search]]
[status-im.utils.listview :refer [to-datasource]]
[status-im.new-group.views.contact :refer [new-group-contact]]
[status-im.new-group.styles :as st]
[status-im.contacts.styles :as cst]
[status-im.i18n :refer [label]]))
(defn contact-list-toolbar [contacts-count show-search?]
(defn title-with-count [title count-value]
[view st/toolbar-title-with-count
[text {:style st/toolbar-title-with-count-text
:font :toolbar-title}
title]
(when (pos? count-value)
[view st/toolbar-title-with-count-container
[text {:style st/toolbar-title-with-count-text-count
:font :toolbar-title}
count-value]])])
(defn contact-list-toolbar [contacts-count show-search? search-text]
(toolbar-with-search
{:show-search? (= show-search? :contact-group-list)
:search-text search-text
:search-key :contact-group-list
:title (str (label :t/new-group) " (" contacts-count ")")
:search-placeholder (label :t/search-for)}))
:custom-title (title-with-count (label :t/new-group) contacts-count)
:search-placeholder (label :t/search-contacts)}))
(defn render-separator [_ row-id _]
(list-item ^{:key row-id}
[view cst/contact-item-separator-wrapper
[view cst/contact-item-separator]]))
(defview contact-group-list []
[contacts [:all-added-group-contacts-filtered]
selected-contacts-count [:selected-contacts-count]
show-search [:get-in [:toolbar-search :show]]]
show-search [:get-in [:toolbar-search :show]]
search-text [:get-in [:toolbar-search :text]]]
[view st/new-group-container
[status-bar]
[contact-list-toolbar selected-contacts-count show-search]
[contact-list-toolbar selected-contacts-count show-search search-text]
[view {:flex 1}
[list-view
{:dataSource (to-datasource contacts)
:renderRow (fn [row _ _]
(list-item ^{:key row} [new-group-contact row]))
:style st/contacts-list
:renderSeparator render-separator
:style cst/contacts-list
:keyboardShouldPersistTaps true}]]
(when (pos? selected-contacts-count)
[confirm-button (label :t/next) #(dispatch [:navigation-replace :contact-group])])])

View File

@ -0,0 +1,76 @@
(ns status-im.new-group.views.reorder-groups
(:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [dispatch dispatch-sync]]
[status-im.components.react :refer [view
text
icon
linear-gradient
touchable-highlight
list-item]]
[status-im.components.confirm-button :refer [confirm-button]]
[status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar-new.view :refer [toolbar]]
[status-im.components.sortable-list-view :refer [sortable-list-view sortable-item]]
[status-im.utils.listview :refer [to-datasource]]
[status-im.utils.platform :refer [android?]]
[status-im.new-group.styles :as st]
[status-im.contacts.styles :as cst]
[status-im.i18n :refer [label label-pluralize]]
[status-im.utils.platform :refer [platform-specific]]
[reagent.core :as r]))
(defn toolbar-view []
[toolbar {:actions [{:image :blank}]
:title (label :t/reorder-groups)}])
(defn group-item [{:keys [name contacts] :as group}]
(let [cnt (count contacts)]
[view st/order-item-container
[view st/order-item-inner-container
[text {:style st/order-item-label}
name]
[text {:style st/order-item-contacts}
(str cnt " " (label-pluralize cnt :t/contact-s))]
[view {:flex 1}]
[view st/order-item-icon
[icon :grab_gray]]]]))
(defn top-shaddow []
[linear-gradient {:style cst/contact-group-header-gradient-bottom
:colors cst/contact-group-header-gradient-bottom-colors}])
(defn bottom-shaddow []
[linear-gradient {:style cst/contact-group-header-gradient-top
:colors cst/contact-group-header-gradient-top-colors}])
(defn render-separator [last shadows?]
(fn [_ row-id _]
(list-item
(if (= row-id last)
(when shadows?
^{:key "bottom-shaddow"}
[bottom-shaddow])
^{:key row-id}
[view st/order-item-separator-wrapper
[view st/order-item-separator]]))))
(defview reorder-groups []
[groups [:get :contact-groups]
order [:get :groups-order]
shadows? (get-in platform-specific [:contacts :group-block-shadows?])]
(let [this (r/current-component)]
[view st/reorder-groups-container
[status-bar]
[toolbar-view]
[view st/reorder-list-container
(when shadows?
[top-shaddow])
[sortable-list-view
{:data groups
:order order
:on-row-moved #(do (dispatch-sync [:change-group-order (:from %) (:to %)])
(.forceUpdate this))
:render-row (fn [row]
(sortable-item [group-item row]))
:render-separator (render-separator (last order) shadows?)}]]
[confirm-button (label :t/save) #(dispatch [:save-group-order])]]))

View File

@ -1,6 +1,7 @@
(ns status-im.qr-scanner.styles
(:require [status-im.components.styles :refer [color-white]]
[status-im.components.toolbar.styles :refer [toolbar-height]]))
[status-im.components.toolbar.styles :refer [toolbar-height]]
[status-im.utils.platform :as p]))
(def barcode-scanner-container
{:flex 1

View File

@ -146,6 +146,7 @@
:delete-contact "Delete contact"
:remove-from-group "Remove from group"
:edit-contacts "Edit contacts"
:search-contacts "Search contacts"
:show-all "SHOW ALL"
:contacts-group-dapps "ÐApps"
:contacts-group-people "People"
@ -189,14 +190,15 @@
:group-chat-name "Chat name"
:empty-group-chat-name "Please enter a name"
:illegal-group-chat-name "Please select another name"
:new-group "New Group"
:reorder-groups "Reorder Group"
:new-group "New group"
:reorder-groups "Reorder groups"
:group-name "Group name"
:edit-group "Edit Group"
:delete-group "DELETE GROUP"
:edit-group "Edit group"
:delete-group "Delete group"
:delete-group-prompt "This will not affect group members"
:group-members "Group members"
:contact-s {:one "contact"
:other "contacts"}
;participants
:add-participants "Add Participants"
:remove-participants "Remove Participants"