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-fs",
"react-native-dialogs", "react-native-dialogs",
"react-native-popup-menu", "react-native-popup-menu",
"react-native-sortable-listview",
"react-native-image-resizer", "react-native-image-resizer",
"react-native-image-crop-picker", "react-native-image-crop-picker",
"react-native-webview-bridge", "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 */; }; E0AD9E8F495A4907B65104BF /* libRCTImageResizer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BEE3436791D42248F853999 /* libRCTImageResizer.a */; };
EC8998BFE2C04023A860C065 /* libRNNetworkInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 74B7BDFF464F43D3BA8EA040 /* libRNNetworkInfo.a */; }; EC8998BFE2C04023A860C065 /* libRNNetworkInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 74B7BDFF464F43D3BA8EA040 /* libRNNetworkInfo.a */; };
EF2B5857B4A34E0C9707FB3F /* Octicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B3B19223008342D096AA356E /* Octicons.ttf */; }; 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 */; }; FD4F213C3873473CB703B1D2 /* libRNFS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674B3D9595A047AB8D518F4E /* libRNFS.a */; };
/* End PBXBuildFile section */ /* 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>"; }; 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>"; }; 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>"; }; 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; }; FC1CBCFE6C906043D6CCEEE1 /* libPods-StatusImTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-StatusImTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -671,6 +673,7 @@
2028E0111D4275BD00227DCD /* SF */ = { 2028E0111D4275BD00227DCD /* SF */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
F9238D6B1E5F055900C047B9 /* SF-UI-Text-Semibold.otf */,
9ED2F4601D9D577B00B36508 /* SF-UI-Text-Bold.otf */, 9ED2F4601D9D577B00B36508 /* SF-UI-Text-Bold.otf */,
9E0B01A01DDC5DA7002B0359 /* SF-UI-Text-Light.otf */, 9E0B01A01DDC5DA7002B0359 /* SF-UI-Text-Light.otf */,
9ED2F45D1D9D52DD00B36508 /* SF-UI-Text-Regular.otf */, 9ED2F45D1D9D52DD00B36508 /* SF-UI-Text-Regular.otf */,
@ -1471,6 +1474,7 @@
9ED2F45F1D9D535A00B36508 /* SF-UI-Text-Medium.otf in Resources */, 9ED2F45F1D9D535A00B36508 /* SF-UI-Text-Medium.otf in Resources */,
2028DFFA1D4275B600227DCD /* SF-UI-Display-Regular.otf in Resources */, 2028DFFA1D4275B600227DCD /* SF-UI-Display-Regular.otf in Resources */,
2028DFF91D4275B600227DCD /* SF-UI-Display-Medium.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 */, 2028DFFC1D4275B600227DCD /* SF-UI-Display-Thin.otf in Resources */,
2028DFFB1D4275B600227DCD /* SF-UI-Display-Semibold.otf in Resources */, 2028DFFB1D4275B600227DCD /* SF-UI-Display-Semibold.otf in Resources */,
D28AEFB4C39548EB80416889 /* Entypo.ttf 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" : [ "images" : [
{ {
"idiom" : "universal", "idiom" : "universal",
"filename" : "icon_dots_horizontal_dark.png", "filename" : "icon_options_dark.png",
"scale" : "1x" "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" : [ "images" : [
{ {
"idiom" : "universal", "idiom" : "universal",
"filename" : "icon_dots_horizontal_gray.png", "filename" : "icon_options_gray.png",
"scale" : "1x" "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> </dict>
</dict> </dict>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for Instabug and Audio Messages</string> <string>Need microphone access for Instabug and Audio Messages</string>
<key>NSCameraUsageDescription</key> <key>NSCameraUsageDescription</key>
<string>We need to access your camera</string> <string>We need to access your camera</string>
<key>NSContactsUsageDescription</key> <key>NSContactsUsageDescription</key>
@ -58,6 +58,7 @@
<string>We need to access your photo storage to give you an ability to select photos</string> <string>We need to access your photo storage to give you an ability to select photos</string>
<key>UIAppFonts</key> <key>UIAppFonts</key>
<array> <array>
<string>SF-UI-Text-Semibold.otf</string>
<string>SF-UI-Text-Bold.otf</string> <string>SF-UI-Text-Bold.otf</string>
<string>SF-UI-Text-Regular.otf</string> <string>SF-UI-Text-Regular.otf</string>
<string>SF-UI-Text-Medium.otf</string> <string>SF-UI-Text-Medium.otf</string>

View File

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

View File

@ -25,8 +25,9 @@
[status-im.transactions.screen :refer [confirm]] [status-im.transactions.screen :refer [confirm]]
[status-im.chats-list.screen :refer [chats-list]] [status-im.chats-list.screen :refer [chats-list]]
[status-im.new-group.screen-public :refer [new-public-group]] [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.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.add :refer [new-participants]]
[status-im.participants.views.remove :refer [remove-participants]] [status-im.participants.views.remove :refer [remove-participants]]
[status-im.group-settings.screen :refer [group-settings]] [status-im.group-settings.screen :refer [group-settings]]
@ -114,6 +115,7 @@
:contact-list main-tabs :contact-list main-tabs
:contact-list-search-results contacts-search-results :contact-list-search-results contacts-search-results
:group-contacts contact-list :group-contacts contact-list
:reorder-groups reorder-groups
:new-contact new-contact :new-contact new-contact
:qr-scanner qr-scanner :qr-scanner qr-scanner
:chat chat :chat chat

View File

@ -8,6 +8,9 @@
:main {:height 0 :main {:height 0
:bar-style "dark-content" :bar-style "dark-content"
:color styles/color-white} :color styles/color-white}
:gray {:height 0
:bar-style "dark-content"
:color styles/color-light-gray}
:transparent {:height 20 :transparent {:height 20
:bar-style "light-content" :bar-style "light-content"
:translucent? true :translucent? true
@ -15,6 +18,13 @@
:modal {:height 0 :modal {:height 0
:bar-style "light-content" :bar-style "light-content"
:color styles/color-black}} :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 :sized-text {:margin-top 0
:additional-height 0} :additional-height 0}
:chat {:new-message {:border-top-color styles/color-transparent :chat {:new-message {:border-top-color styles/color-transparent
@ -35,6 +45,12 @@
:font-size 14}}} :font-size 14}}}
:contacts {:subtitle {:color styles/color-gray4 :contacts {:subtitle {:color styles/color-gray4
:font-size 14} :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} :separator {:height 0}
:icon-check {:border-radius 2 :icon-check {:border-radius 2
:width 17 :width 17
@ -43,7 +59,43 @@
:alignItems :center :alignItems :center
:height 56 :height 56
:padding-top 10 :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} :bottom-gradient {:height 3}
:input-label {:left 4} :input-label {:left 4}
:input-error-text {:margin-left 4} :input-error-text {:margin-left 4}
@ -55,8 +107,7 @@
:toolbar-last-activity {:color styles/text2-color :toolbar-last-activity {:color styles/text2-color
:background-color :transparent :background-color :transparent
:top 0 :top 0
:font-size 12} :font-size 12}})
:toolbar-title-container {:padding-left 16}})
(def fonts (def fonts
{:light {:font-family "sans-serif-light"} {:light {:font-family "sans-serif-light"}
@ -86,11 +137,13 @@
:tabs {:tab-shadows? true} :tabs {:tab-shadows? true}
:chats {:action-button? true :chats {:action-button? true
:new-chat-in-toolbar? false} :new-chat-in-toolbar? false}
:uppercase? true
:contacts {:action-button? true :contacts {:action-button? true
:new-contact-in-toolbar? false :new-contact-in-toolbar? false
:uppercase-subtitles? false
:group-block-shadows? true} :group-block-shadows? true}
:discover {:uppercase-subtitles? false} :discover {:uppercase-subtitles? false}
:public-group-icon-container {:margin-top 4} :public-group-icon-container {:margin-top 4}
:private-group-icon-container {:margin-top 6} :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}}) :public-group-chat-hash-style {:top 10 :left 4}})

View File

@ -117,8 +117,8 @@
[status-bar] [status-bar]
[toolbar {:hide-nav? (or (empty? accounts) show-actions? creating?) [toolbar {:hide-nav? (or (empty? accounts) show-actions? creating?)
:custom-content [toolbar-content-view] :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]]) [add-contact-bar]])
(defn get-intro-status-message [all-messages] (defn get-intro-status-message [all-messages]

View File

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

View File

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

View File

@ -166,28 +166,3 @@
(reg-handler ::clear-commands-callbacks (reg-handler ::clear-commands-callbacks
(fn [db [chat-id]] (fn [db [chat-id]]
(assoc-in db [::commands-callbacks chat-id] nil))) (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)) (get resources/contacts))
{:uri photo-path})] {:uri photo-path})]
[image {:source photo [image {:source photo
:style (merge st/default-image-style :style (st/image-style size)}]))
(st/image-style size))}]))
(defn dapp-badge [styles] (defn dapp-badge [{:keys [online-view-wrapper online-view online-dot-left online-dot-right]}]
[view (:online-view-wrapper styles) [view online-view-wrapper
[view (:online-view styles) [view online-view
[view [view
[view (:online-dot-left styles)] [view online-dot-left]
[view (:online-dot-right styles)]]]]) [view online-dot-right]]]])
(defn contact-badge [type styles] (defn contact-badge [type styles]
(when (= type :edit) (when (= type :edit)
@ -127,19 +126,19 @@
:default-chat-icon (st/default-chat-icon-message-status color) :default-chat-icon (st/default-chat-icon-message-status color)
:default-chat-icon-text st/message-status-icon-text}]) :default-chat-icon-text st/message-status-icon-text}])
(defn contact-icon-view [contact styles] (defn contact-icon-view [{:keys [photo-path name dapp?]} {:keys [container] :as styles}]
(let [photo-path (:photo-path contact) (let [photo-path photo-path]
;; TODO: stub [view container
type :online]
[view (:container styles)
(if-not (s/blank? photo-path) (if-not (s/blank? photo-path)
[chat-icon photo-path styles] [chat-icon photo-path styles]
[default-chat-icon (:name contact) styles]) [default-chat-icon name styles])
[contact-badge type styles]])) (when dapp?
[dapp-badge styles])]))
(defn contact-icon-contacts-tab [contact] (defn contact-icon-contacts-tab [contact]
[contact-icon-view contact [contact-icon-view contact
{:container st/container-chat-list {:container st/container-chat-list
:online-view-wrapper st/online-view-wrapper
:online-view st/online-view :online-view st/online-view
:online-dot-left st/online-dot-left :online-dot-left st/online-dot-left
:online-dot-right st/online-dot-right :online-dot-right st/online-dot-right

View File

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

View File

@ -1,5 +1,6 @@
(ns status-im.components.confirm-button (ns status-im.components.confirm-button
(:require [status-im.components.styles :as st] (:require [status-im.components.styles :as st]
[status-im.utils.platform :refer [platform-specific]]
[status-im.components.react :refer [view [status-im.components.react :refer [view
text text
touchable-highlight]])) touchable-highlight]]))
@ -7,4 +8,6 @@
(defn confirm-button [label on-press] (defn confirm-button [label on-press]
[touchable-highlight {:on-press on-press} [touchable-highlight {:on-press on-press}
[view st/confirm-button [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.i18n :refer [label]]
[status-im.utils.platform :refer [platform-specific ios?]] [status-im.utils.platform :refer [platform-specific ios?]]
[re-frame.core :refer [dispatch]] [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")) (def react-native-popup-menu (js/require "react-native-popup-menu"))
@ -43,7 +43,9 @@
trigger]] trigger]]
[menu {:onSelect #(when % (do (%) nil))} [menu {:onSelect #(when % (do (%) nil))}
[menu-trigger trigger] [menu-trigger trigger]
[menu-options st/context-menu [menu-options st/context-menu-options
(for [option options] (for [{:keys [style value] :as option} options]
^{:key option} ^{: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-transparent "transparent")
(def color-blue "#7099e6") (def color-blue "#7099e6")
(def color-blue-transparent "#7099e632") (def color-blue-transparent "#7099e632")
(def color-black "#000000de") (def color-black "#000000")
(def color-purple "#a187d5") (def color-purple "#a187d5")
(def color-gray "#838c93de") (def color-gray "#838c93de")
(def color-gray2 "#8f838c93") (def color-gray2 "#8f838c93")
@ -24,12 +24,12 @@
(def text1-disabled-color "#555555") (def text1-disabled-color "#555555")
(def text2-color color-gray) (def text2-color color-gray)
(def text3-color color-blue) (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 new-messages-count-color color-blue-transparent)
(def chat-background color-light-gray) (def chat-background color-light-gray)
(def selected-message-color "#E4E9ED") (def selected-message-color "#E4E9ED")
(def selected-contact-color color-light-blue2) (def selected-contact-color color-light-blue2)
(def separator-color color-gray4) (def separator-color "#0000001f")
(def default-chat-color color-purple) (def default-chat-color color-purple)
(def flex (def flex
@ -45,8 +45,8 @@
:color :white}) :color :white})
(def icon-back (def icon-back
{:width 24 {:width 8
:height 24}) :height 14})
(def icon-default (def icon-default
{:width 24 {:width 24
@ -96,17 +96,18 @@
:align-items :center :align-items :center
:background-color color-light-blue}) :background-color color-light-blue})
(def confirm-button-label (def context-menu-options
{:color color-white {:customStyles {:optionsContainer {:elevation 2
:font-size 17 :margin-top 30
:line-height 20 :padding-top 8
:letter-spacing -0.2}) :width 164
(def context-menu
{:customStyles {:optionsContainer {:padding-top 8
:padding-bottom 8} :padding-bottom 8}
:optionWrapper {:padding-left 16 :optionWrapper {:padding-left 16
:padding-right 16
:justify-content :center :justify-content :center
:height 48} :height 48}}})
:text {:font-size 15
:line-height 20}}}) (def context-menu-text
{:font-size 15
:line-height 20
:color text1-color})

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@
image image
touchable-highlight]] touchable-highlight]]
[status-im.components.sync-state.gradient :refer [sync-state-gradient-view]] [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]] icon-search]]
[status-im.components.toolbar.actions :as act] [status-im.components.toolbar.actions :as act]
[status-im.components.toolbar.styles :as st] [status-im.components.toolbar.styles :as st]
@ -34,8 +34,8 @@
[touchable-highlight {:on-press #(dispatch [:navigate-back]) [touchable-highlight {:on-press #(dispatch [:navigate-back])
:accessibility-label id/toolbar-back-button} :accessibility-label id/toolbar-back-button}
[view (get-in platform-specific [:component-styles :toolbar-nav-action]) [view (get-in platform-specific [:component-styles :toolbar-nav-action])
[image {:source {:uri :icon_back_dark} [image {:source {:uri :icon_back}
:style icon-default}]]]))] :style icon-back}]]]))]
(or custom-content (or custom-content
[view {:style st/toolbar-title-container} [view {:style st/toolbar-title-container}
[text {:style st/toolbar-title-text [text {:style st/toolbar-title-text
@ -50,8 +50,7 @@
[view st/toolbar-action [view st/toolbar-action
[image action-image]]]) [image action-image]]])
custom-action)]] custom-action)]]
[sync-state-gradient-view] [sync-state-gradient-view]]))
[view st/toolbar-line]]))
(defn- toolbar-search-submit [on-search-submit] (defn- toolbar-search-submit [on-search-submit]
(let [text @(subscribe [:get-in [:toolbar-search :text]])] (let [text @(subscribe [:get-in [:toolbar-search :text]])]
@ -68,7 +67,10 @@
{:style st/toolbar-search-input {:style st/toolbar-search-input
:auto-focus true :auto-focus true
:placeholder search-placeholder :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 [view
[text {:style st/toolbar-with-search-title [text {:style st/toolbar-with-search-title
:font :toolbar-title} :font :toolbar-title}
@ -81,11 +83,9 @@
style style
on-search-submit] on-search-submit]
:as opts}] :as opts}]
(let [toggle-search-fn #(do (let [toggle-search-fn #(dispatch [:set-in [:toolbar-search :show] %])
(dispatch [:set-in [:toolbar-search :show] %])
(dispatch [:set-in [:toolbar-search :text] ""]))
actions (if-not show-search? 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) [toolbar {:style (merge st/toolbar-with-search style)
:nav-action (if show-search? :nav-action (if show-search?
(act/back #(toggle-search-fn nil)) (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 [_ _ click-handler]]
(-> db (-> db
(assoc-in [:toolbar-search :show] nil) (assoc-in [:toolbar-search :show] nil)
(assoc-in [:contact-list-ui-props :edit?] false)
(assoc :contacts-click-handler click-handler))) (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 (register-handler :remove-contacts-click-handler
(fn [db] (fn [db]
(dissoc db (dissoc db
@ -208,21 +216,29 @@
(register-handler :load-default-contacts! (register-handler :load-default-contacts!
(u/side-effect! (u/side-effect!
(fn [{:keys [chats]}] (fn [{:keys [chats groups]}]
(doseq [[id {:keys [name photo-path public-key add-chat? (let [default-contacts js-res/default-contacts
dapp? dapp-url dapp-hash]}] js-res/default-contacts] default-dapps-group-contacts (mapv #(hash-map :identity (clojure.core/name (first %)))
(let [id' (clojure.core/name id)] (filter #(true? (:dapp? (second %))) default-contacts))]
(when-not (chats id') (doseq [[id {:keys [name photo-path public-key add-chat?
(when add-chat? dapp? dapp-url dapp-hash]}] default-contacts]
(dispatch [:add-chat id' {:name (:en name)}])) (let [id' (clojure.core/name id)]
(dispatch [:add-contacts [{:whisper-identity id' (when-not (chats id')
:address (public-key->address id') (when add-chat?
:name (:en name) (dispatch [:add-chat id' {:name (:en name)}]))
:photo-path photo-path (dispatch [:add-contacts [{:whisper-identity id'
:public-key public-key :address (public-key->address id')
:dapp? dapp? :name (:en name)
:dapp-url (:en dapp-url) :photo-path photo-path
:dapp-hash dapp-hash}]]))))))) :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 (register-handler :add-contacts
(after save-contacts!) (after save-contacts!)
@ -326,8 +342,8 @@
(register-handler :remove-contact-from-group (register-handler :remove-contact-from-group
(u/side-effect! (u/side-effect!
(fn [_ [_ {:keys [whisper-identity]} group]] (fn [{:keys [contact-groups]} [_ {:keys [whisper-identity]} {:keys [group-id]}]]
(let [group' (update group :contacts (remove-contact-from-group whisper-identity))] (let [group' (update (contact-groups group-id) :contacts (remove-contact-from-group whisper-identity))]
(dispatch [:update-group group']))))) (dispatch [:update-group group'])))))
(register-handler :remove-contact (register-handler :remove-contact

View File

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

View File

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

View File

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

View File

@ -18,7 +18,8 @@
[text {:style st/letter-text} letter])]) [text {:style st/letter-text} letter])])
(defn options-btn [contact more-options] (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 [view st/more-btn
[context-menu [context-menu
[icon :options_gray] [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: 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 ;;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]}] :keys [extended? letter? on-click extend-options info]}]
[chat [:get-chat whisper-identity]] [chat [:get-chat whisper-identity]]
[touchable-highlight [touchable-highlight
@ -38,6 +39,4 @@
[letter-view letter]) [letter-view letter])
[contact-inner-view {:contact contact :info info}] [contact-inner-view {:contact contact :info info}]
(when extended? (when extended?
[options-btn contact extend-options])] [options-btn contact extend-options])]]])
[view st/contact-separator-container
[view (get-in platform-specific [:component-styles :contacts :separator])]]]])

View File

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

View File

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

View File

@ -16,6 +16,13 @@
:color "#2f3031"}} :color "#2f3031"}}
:toolbar {:border-bottom-color styles/color-gray3 :toolbar {:border-bottom-color styles/color-gray3
:border-bottom-width 0.5} :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 :sized-text {:margin-top -5
:additional-height 5} :additional-height 5}
:actions-list-view {:border-bottom-color styles/color-gray3 :actions-list-view {:border-bottom-color styles/color-gray3
@ -40,34 +47,87 @@
:icon {:padding-top 0 :icon {:padding-top 0
:bottom -4 :bottom -4
:justify-content :flex-end}}} :justify-content :flex-end}}}
:contacts {:subtitle {:color styles/color-black :contacts {:subtitle {:color styles/text1-color
:font-size 16 :font-size 16
:letter-spacing -0.2} :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 :height 1
:background-color styles/color-gray5 :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 :icon-check {:border-radius 50
:width 24 :width 24
:height 24} :height 24}
:group-header {:flexDirection :row :group-header {:flexDirection :row
:alignItems :center :alignItems :center
:margin-top 24 :margin-top 24
:padding-left 16
:padding-right 16
:height 53 :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} :bottom-gradient {:height 1}
:input-label {:left 0} :input-label {:left 0}
:input-error-text {:margin-left 0} :input-error-text {:margin-left 0}
:main-tab-list {:margin-bottom 72} :main-tab-list {:margin-bottom 72}
:toolbar-search-input {:padding-left 10}
:toolbar-nav-action {:width 46 :toolbar-nav-action {:width 46
:height 56 :height 56
:align-items :center :align-items :center
:justify-content :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 :toolbar-last-activity {:color styles/text2-color
:background-color :transparent :background-color :transparent
:top 0 :top 0
:font-size 14} :font-size 14}})
:toolbar-title-container {:align-items :center}})
(def fonts (def fonts
{:light {:font-family "SFUIText-Light"} {:light {:font-family "SFUIText-Light"}
@ -75,7 +135,7 @@
:medium {:font-family "SFUIText-Medium"} :medium {:font-family "SFUIText-Medium"}
:bold {:font-family "SFUIText-Bold"} :bold {:font-family "SFUIText-Bold"}
:toolbar-title {:font-family "SFUIText-Medium"}}) :toolbar-title {:font-family "SFUIText-Semibold"}})
;; Dialogs ;; Dialogs
@ -96,12 +156,14 @@
:tabs {:tab-shadows? false} :tabs {:tab-shadows? false}
:chats {:action-button? false :chats {:action-button? false
:new-chat-in-toolbar? true} :new-chat-in-toolbar? true}
:uppercase? false
:contacts {:action-button? false :contacts {:action-button? false
:new-contact-in-toolbar? true :new-contact-in-toolbar? true
:uppercase-subtitles? true
:group-block-shadows? false} :group-block-shadows? false}
:discover {:uppercase-subtitles? true} :discover {:uppercase-subtitles? true}
:public-group-icon-container {:margin-top 2} :public-group-icon-container {:margin-top 2}
:private-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}}) :public-group-chat-hash-style {:top 6 :left 3}})

View File

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

View File

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

View File

@ -5,9 +5,17 @@
text2-color text2-color
color-light-blue color-light-blue
color-light-red color-light-red
color-light-gray
selected-contact-color selected-contact-color
color-gray4]] color-gray4
[status-im.utils.platform :refer [platform-specific]])) 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?] (defn toolbar-icon [enabled?]
{:width 20 {:width 20
@ -19,12 +27,23 @@
:flex-direction :column :flex-direction :column
:background-color color-white}) :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 (def chat-name-container
{:margin-left 16}) {:margin-top 21
:margin-left 16})
(def group-chat-name-input (def group-chat-name-input
{:font-size 14 {:font-size 17
:color text1-color}) :letter-spacing -0.2
:color text1-color})
(def group-chat-topic-input (def group-chat-topic-input
{:font-size 14 {:font-size 14
@ -38,31 +57,46 @@
:position :absolute} :position :absolute}
(get-in platform-specific [:public-group-chat-hash-style]))) (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 (def group-chat-name-wrapper
{:padding-top 0}) {:padding-top 0
:height 40
:padding-bottom 0})
(def group-name-text (def group-name-text
{:margin-top 11 (merge (ps-new-group :group-name-text)
:margin-bottom 10 {:letter-spacing -0.1
:letter-spacing -0.1 :color color-gray4}))
:color color-gray4
:font-size 13 (def members-container
:line-height 20}) {:flex-direction :row
:padding-top 20})
(def members-text (def members-text
{:margin-top 10 (merge (ps-new-group :members-text)
:margin-bottom 8 {:color color-gray4}))
:letter-spacing -0.2
:color color-gray4 (def members-text-count
:font-size 16 (merge (ps-new-group :members-text-count)
:line-height 19}) {:margin-left 8
:color color-gray4
:opacity 0.6}))
(def add-container (def add-container
{:flex-direction :row {:flex-direction :row
:align-items :center :align-items :center
:margin-top 16 :height 64
:margin-bottom 16 :margin-top 12})
:margin-right 20})
(def add-icon-container
{:width 40
:align-items :center
:justify-content :center})
(def add-icon (def add-icon
{:align-items :center {:align-items :center
@ -70,31 +104,22 @@
:height 24}) :height 24})
(def add-text (def add-text
{:margin-left 32 (merge (ps-new-group :add-text)
:color color-light-blue {:color color-light-blue}))
:letter-spacing -0.2
:font-size 17
:line-height 20})
(def delete-group-text (def delete-group-text
{:color color-light-red (merge (ps-new-group :delete-group-text)
:letter-spacing 0.5 {:color color-light-red}))
:font-size 14
:line-height 20})
(def delete-group-prompt-text (def delete-group-prompt-text
{:color color-gray4 (merge (ps-new-group :delete-group-prompt-text)
:font-size 14 {:color color-gray4}))
:line-height 20})
(def contacts-list
{:background-color :white})
(def contact-container (def contact-container
{:flex-direction :row (merge (ps-new-group :contact-container)
:justify-content :center {:flex-direction :row
:align-items :center :justify-content :center
:height 56}) :align-items :center}))
(def selected-contact (def selected-contact
{:background-color selected-contact-color}) {:background-color selected-contact-color})
@ -115,6 +140,52 @@
:height 12}) :height 12})
(def delete-group-container (def delete-group-container
{:height 56 (merge (ps-new-group :delete-group-container)
:padding-left 72 {:height 64
:margin-top 15}) :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])] (let [contacts (subscribe [:get :selected-contacts])]
(reaction (count @contacts))))) (reaction (count @contacts)))))
(defn filter-contacts [selected-contacts added-contacts]
(filter #(selected-contacts (:whisper-identity %)) added-contacts))
(register-sub :selected-group-contacts (register-sub :selected-group-contacts
(fn [_ _] (fn [_ _]
(let [selected-contacts (subscribe [:get :selected-contacts]) (let [selected-contacts (subscribe [:get :selected-contacts])
added-contacts (subscribe [:all-added-contacts])] added-contacts (subscribe [:all-added-contacts])]
(reaction (do @selected-contacts ;;TODO: doesn't work without this line :( (reaction (filter-contacts @selected-contacts @added-contacts)))))
(filter #(@selected-contacts (:whisper-identity %)) @added-contacts))))))

View File

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

View File

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

View File

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