[ui only] Mobile network bottom sheet

This commit is contained in:
Roman Volosovskyi 2019-01-30 15:34:43 +02:00
parent 00b5ad2af6
commit 7b0f68fcdb
No known key found for this signature in database
GPG Key ID: 0238A4B5ECEE70DE
15 changed files with 371 additions and 34 deletions

View File

@ -12,7 +12,8 @@
[status-im.utils.fx :as fx] [status-im.utils.fx :as fx]
[status-im.utils.handlers :as handlers] [status-im.utils.handlers :as handlers]
[status-im.utils.http :as http] [status-im.utils.http :as http]
[status-im.utils.types :as types])) [status-im.utils.types :as types]
[status-im.ui.components.bottom-sheet.core :as bottom-sheet]))
(def url-regex (def url-regex
#"https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}(\.[a-z]{2,6})?\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)") #"https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}(\.[a-z]{2,6})?\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)")
@ -237,8 +238,14 @@
:content (not-supported-warning fleet)}}))) :content (not-supported-warning fleet)}})))
(fx/defn handle-network-status-change (fx/defn handle-network-status-change
[cofx data] [cofx {:keys [type] :as data}]
{:network/notify-status-go data}) (fx/merge
cofx
{:network/notify-status-go data}
(if (= type "cellular")
(bottom-sheet/show-bottom-sheet
{:view :mobile-network})
(bottom-sheet/hide-bottom-sheet))))
(re-frame/reg-fx (re-frame/reg-fx
:network/listen-to-network-status :network/listen-to-network-status

View File

@ -0,0 +1,10 @@
(ns status-im.ui.components.bottom-sheet.core
(:require [status-im.ui.components.bottom-sheet.view :as view]
[status-im.ui.components.bottom-sheet.events :as events]
status-im.ui.components.bottom-sheet.subs
status-im.ui.components.bottom-sheet.db))
(def show-bottom-sheet events/show-bottom-sheet)
(def hide-bottom-sheet events/hide-bottom-sheet)
(def bottom-sheet view/bottom-sheet)

View File

@ -0,0 +1,5 @@
(ns status-im.ui.components.bottom-sheet.db
(:require [cljs.spec.alpha :as spec]))
(spec/def :bottom-sheet/show? (spec/nilable boolean?))
(spec/def :bottom-sheet/view (spec/nilable keyword?))

View File

@ -0,0 +1,12 @@
(ns status-im.ui.components.bottom-sheet.events
(:require [status-im.utils.fx :as fx]))
(fx/defn show-bottom-sheet
[{:keys [db]} {:keys [view]}]
{:db (assoc db
:bottom-sheet/show? true
:bottom-sheet/view view)})
(fx/defn hide-bottom-sheet
[{:keys [db]}]
{:db (assoc db :bottom-sheet/show? false)})

View File

@ -0,0 +1,8 @@
(ns status-im.ui.components.bottom-sheet.subs
(:require [re-frame.core :as re-frame]))
(re-frame/reg-sub
:bottom-sheet
(fn [{:bottom-sheet/keys [show? view]}]
{:show? show?
:view view}))

View File

@ -113,12 +113,13 @@
{:style (styles/content-container height bottom-value)} {:style (styles/content-container height bottom-value)}
[react/view styles/content-header [react/view styles/content-header
[react/view styles/handle]] [react/view styles/handle]]
content [react/view {:style {:flex 1
:height height}}
[content]]
[react/view {:style styles/bottom-view}]]])})) [react/view {:style styles/bottom-view}]]])}))
(defn bottom-sheet (defn bottom-sheet
[{:keys [show? content-height on-cancel]} _] [{:keys [show? content-height on-cancel]}]
{:pre [(fn? on-cancel) (pos? content-height)]}
(let [show-sheet? (reagent/atom show?) (let [show-sheet? (reagent/atom show?)
total-content-height (+ content-height styles/border-radius total-content-height (+ content-height styles/border-radius
styles/bottom-padding) styles/bottom-padding)
@ -132,15 +133,28 @@
(reagent.core/create-class (reagent.core/create-class
{:component-will-update {:component-will-update
(fn [this [_ new-args]] (fn [this [_ new-args]]
(let [old-args (second (.-argv (.-props this))) (let [old-args (second (.-argv (.-props this)))
old-show? (:show? old-args) old-show? (:show? old-args)
new-show? (:show? new-args)] new-show? (:show? new-args)
old-height (:content-height old-args)
new-height (:content-height new-args)
total-content-height (+ new-height
styles/border-radius
styles/bottom-padding)
opts' (assoc opts :height total-content-height)]
(when (not= old-height new-height)
(animation/set-value bottom-value new-height))
(cond (and (not old-show?) new-show?) (cond (and (not old-show?) new-show?)
(reset! show-sheet? true) (reset! show-sheet? true)
(and old-show? (not new-show?) (true? @show-sheet?)) (and old-show? (not new-show?) (true? @show-sheet?))
(cancel opts)))) (cancel opts'))))
:reagent-render :reagent-render
(fn [_ content] (fn [{:keys [content content-height]}]
(when @show-sheet? (let [total-content-height (+ content-height
[bottom-sheet-view (assoc opts :content content)]))}))) styles/border-radius
styles/bottom-padding)]
(when @show-sheet?
[bottom-sheet-view (assoc opts
:content content
:height total-content-height)])))})))

View File

@ -3,21 +3,28 @@
[status-im.ui.components.react :as react] [status-im.ui.components.react :as react]
[status-im.utils.platform :as platform])) [status-im.utils.platform :as platform]))
(defn- checkbox-generic [{:keys [on-value-change checked? accessibility-label disabled? style] :or {accessibility-label :checkbox}} plain?] (defn- checkbox-generic [{:keys [on-value-change checked? accessibility-label
disabled? style icon-style native?]
:or {accessibility-label :checkbox
native? true}} plain?]
(let [icon-check-container (if plain? #() styles/icon-check-container) (let [icon-check-container (if plain? #() styles/icon-check-container)
check-icon (if plain? styles/plain-check-icon styles/check-icon)] check-icon (merge (if plain? styles/plain-check-icon styles/check-icon) icon-style)]
(if (or platform/android? (if (and (or platform/android?
platform/desktop?) platform/desktop?)
native?)
[react/view (merge styles/wrapper style) [react/view (merge styles/wrapper style)
[react/check-box {:on-value-change on-value-change [react/check-box {:on-value-change on-value-change
:value checked? :value checked?
:disabled (and (not checked?) :disabled (and (not checked?)
disabled?) disabled?)
:accessibility-label accessibility-label}]] :accessibility-label accessibility-label}]]
[react/touchable-highlight (merge {:style (merge styles/wrapper style) [react/touchable-highlight (merge {:style (merge
(icon-check-container checked?)
styles/wrapper
style)
:accessibility-label accessibility-label} :accessibility-label accessibility-label}
(when on-value-change {:on-press #(on-value-change (not checked?))})) (when on-value-change {:on-press #(on-value-change (not checked?))}))
[react/view (icon-check-container checked?) [react/view {}
(when checked? (when checked?
[react/icon :check_on check-icon])]]))) [react/icon :check_on check-icon])]])))

View File

@ -0,0 +1,52 @@
(ns status-im.ui.components.lists.cell.styles
(:require [status-im.ui.components.styles :as common-styles]
[status-im.ui.components.colors :as colors]))
(def cell-container
{:height 64
:align-self :stretch
:flex-direction :row})
(def icon-container
{:width 72
:justify-content :center
:align-items :center})
(defn- get-color [color]
(get
{:blue colors/blue
:red colors/red
:red-light colors/red-light
:blue-light colors/blue-light}
color
color))
(defn icon [color background-color]
{:width 24
:height 24
:color (get-color color)
:container-style {:width 40
:height 40
:border-radius 20
:background-color (get-color background-color)
:justify-content :center
:align-items :center}})
(def description
{:flex 1
:padding-top 8
:padding-bottom 8})
(def cell-text
{:height 18
:justify-content :center
:margin-top 3
:margin-bottom 3})
(defn item-title [color]
(merge common-styles/text-main-medium
{:color (get-color color)}))
(def item-details
(merge common-styles/text-main
{:color colors/gray}))

View File

@ -0,0 +1,20 @@
(ns status-im.ui.components.lists.cell.view
(:require [status-im.ui.components.react :as react]
[status-im.ui.components.lists.cell.styles :as styles]
[status-im.ui.components.icons.vector-icons :as icons]))
(defn cell [{:keys [title details icon]
{:keys [title-color
icon-color
icon-background]} :style}]
[react/view
{:style styles/cell-container}
[react/view {:style styles/icon-container}
[icons/icon icon (styles/icon icon-color icon-background)]]
[react/view {:style styles/description}
[react/view {:style styles/cell-text}
[react/text {:style (styles/item-title title-color)}
title]]
[react/view {:style styles/cell-text}
[react/text {:style styles/item-details}
details]]]])

View File

@ -19,4 +19,15 @@
(def icon-default (def icon-default
{:width 24 {:width 24
:height 24}) :height 24})
(def text-title-bold
{:font-size 17
:font-weight "700"})
(def text-main
{:font-size 15})
(def text-main-medium
{:font-size 15
:font-weight "500"})

View File

@ -15,7 +15,8 @@
status-im.mailserver.db status-im.mailserver.db
status-im.browser.db status-im.browser.db
status-im.ui.screens.add-new.db status-im.ui.screens.add-new.db
status-im.ui.screens.add-new.new-public-chat.db)) status-im.ui.screens.add-new.new-public-chat.db
status-im.ui.components.bottom-sheet.core))
;; initial state of app-db ;; initial state of app-db
(def app-db {:keyboard-height 0 (def app-db {:keyboard-height 0
@ -268,7 +269,9 @@
:stickers/packs :stickers/packs
:stickers/packs-installed :stickers/packs-installed
:stickers/selected-pack :stickers/selected-pack
:stickers/recent] :stickers/recent
:bottom-sheet/show?
:bottom-sheet/view]
:opt-un [::modal :opt-un [::modal
::was-modal? ::was-modal?
::rpc-url ::rpc-url

View File

@ -0,0 +1,96 @@
(ns status-im.ui.screens.mobile-network-settings.style
(:require [status-im.ui.components.colors :as colors]
[status-im.ui.components.styles :as common-styles]))
(def container
{:flex 1
:align-items :center})
(def title
{:height 21
:margin-top 8})
(def title-text
(merge
common-styles/text-title-bold
{:color colors/black}))
(def details
{:height 66
:width 311
:margin-left 32
:margin-right 32
:margin-top 6
:margin-bottom 10})
(def details-text
(merge
common-styles/text-main
{:color colors/gray
:text-align :center
:line-height 22}))
(def network-icon
{:title-color :blue
:icon-color :blue
:icon-background :blue-light})
(def cancel-icon
{:title-color :red
:icon-color :red
:icon-background :red-light})
(def separator
{:background-color colors/gray-lighter
:margin-left 72
:align-self :stretch
:height 1
:margin-top 8})
(def checkbox-line-container
{:margin-left 71
:margin-top 13
:height 29
:flex-direction :row
:justify-content :center})
(def checkbox
{:padding 0
:justify-content :center
:align-items :center
:width 18
:height 18
:border-radius 2
:margin-top 6})
(def checkbox-icon
{:tint-color colors/white})
(def checkbox-text-container
{:justify-content :center
:flex 1
:margin-left 13})
(def checkbox-text
(merge
common-styles/text-main
{:color colors/black
:line-height 19}))
(def settings-container
{:margin-left 69
:height 44
:margin-top 6
:align-items :flex-start})
(def settings-text
(merge
common-styles/text-main
{:color colors/gray
:line-height 22}))
(def settings-link
(merge
common-styles/text-main
{:color colors/blue
:line-height 22}))

View File

@ -0,0 +1,68 @@
(ns status-im.ui.screens.mobile-network-settings.view
(:require-macros [status-im.utils.views :as views])
(:require [status-im.ui.components.react :as react]
[status-im.ui.screens.mobile-network-settings.style :as styles]
[status-im.ui.components.checkbox.view :as checkbox]
[status-im.i18n :as i18n]
[reagent.core :as reagent]
[status-im.ui.components.lists.cell.view :as cell]))
(defn title []
[react/view {:style styles/title}
[react/text
{:style styles/title-text}
(i18n/label :mobile-syncing-sheet-title)]])
(defn details []
[react/view
{:style styles/details}
[react/text
{:style styles/details-text}
(i18n/label :mobile-syncing-sheet-details)]])
(defn separator []
[react/view {:style styles/separator}])
(defn checkbox []
(let [checked? (reagent/atom false)]
(fn []
[react/view
{:style styles/checkbox-line-container}
[checkbox/checkbox
{:checked? @checked?
:style styles/checkbox
:icon-style styles/checkbox-icon
:on-value-change #(swap! checked? not)
:native? false}]
[react/view
{:style styles/checkbox-text-container}
[react/text {:style styles/checkbox-text}
(i18n/label :mobile-network-sheet-remember-choice)]]])))
(defn settings []
[react/view
{:style styles/settings-container}
[react/text {:style styles/settings-text}
(i18n/label :mobile-network-sheet-configure)
[react/text {:style styles/settings-link}
(str " " (i18n/label :mobile-network-sheet-settings))]]])
(views/defview mobile-network-settings-sheet []
[react/view {:style styles/container}
[title]
[details]
[cell/cell
{:title (i18n/label :mobile-network-continue-syncing)
:details (i18n/label :mobile-network-continue-syncing-details)
:icon :main-icons/network
:style styles/network-icon}]
[cell/cell
{:title (i18n/label :mobile-network-stop-syncing)
:details (i18n/label :mobile-network-stop-syncing-details)
:icon :main-icons/cancel
:style styles/cancel-icon}]
[separator]
[react/view {:flex 1
:align-self :stretch}
[checkbox]
[settings]]])

View File

@ -1,3 +1,4 @@
(ns status-im.ui.screens.views (ns status-im.ui.screens.views
(:require-macros [status-im.utils.views :refer [defview letsubs] :as views]) (:require-macros [status-im.utils.views :refer [defview letsubs] :as views])
(:require [re-frame.core :refer [dispatch]] (:require [re-frame.core :refer [dispatch]]
@ -68,6 +69,7 @@
[status-im.ui.screens.about-app.views :as about-app] [status-im.ui.screens.about-app.views :as about-app]
[status-im.ui.screens.stickers.views :as stickers] [status-im.ui.screens.stickers.views :as stickers]
[status-im.ui.screens.dapps-permissions.views :as dapps-permissions] [status-im.ui.screens.dapps-permissions.views :as dapps-permissions]
[status-im.ui.components.bottom-sheet.core :as bottom-sheet]
[status-im.utils.navigation :as navigation] [status-im.utils.navigation :as navigation]
[reagent.core :as reagent] [reagent.core :as reagent]
[cljs-react-navigation.reagent :as nav-reagent] [cljs-react-navigation.reagent :as nav-reagent]
@ -75,7 +77,8 @@
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[taoensso.timbre :as log] [taoensso.timbre :as log]
[status-im.utils.platform :as platform] [status-im.utils.platform :as platform]
[status-im.utils.config :as config])) [status-im.utils.config :as config]
[status-im.ui.screens.mobile-network-settings.view :as mobile-network-settings]))
(defn wrap [view-id component] (defn wrap [view-id component]
(fn [] (fn []
@ -380,6 +383,16 @@
(defonce initial-view-id (atom nil)) (defonce initial-view-id (atom nil))
(views/defview bottom-sheet []
(views/letsubs [{:keys [show? view]} [:bottom-sheet]]
(let [opts (cond-> {:show? show?
:on-cancel (fn [])}
(= view :mobile-network)
(merge {:content mobile-network-settings/mobile-network-settings-sheet
:content-height 340}))]
[bottom-sheet/bottom-sheet opts])))
(defn main [] (defn main []
(let [view-id (re-frame/subscribe [:get :view-id]) (let [view-id (re-frame/subscribe [:get :view-id])
main-component (atom nil)] main-component (atom nil)]
@ -418,13 +431,15 @@
:reagent-render :reagent-render
(fn [] (fn []
(when (and @view-id main-component) (when (and @view-id main-component)
[:> @main-component [react/view {:flex 1}
{:ref (fn [r] [:> @main-component
(navigation/set-navigator-ref r) {:ref (fn [r]
(when (and (navigation/set-navigator-ref r)
platform/android? (when (and
(not js/goog.DEBUG) platform/android?
(not (contains? #{:intro :login :progress} @view-id))) (not js/goog.DEBUG)
(navigation/navigate-to @view-id))) (not (contains? #{:intro :login :progress} @view-id)))
;; see https://reactnavigation.org/docs/en/state-persistence.html#development-mode (navigation/navigate-to @view-id)))
:persistenceKey (when js/goog.DEBUG rand-label)}]))}))) ;; see https://reactnavigation.org/docs/en/state-persistence.html#development-mode
:persistenceKey (when js/goog.DEBUG rand-label)}]
[bottom-sheet]]))})))

View File

@ -919,5 +919,14 @@
"mailserver-error-title": "Error connecting to mailserver", "mailserver-error-title": "Error connecting to mailserver",
"mailserver-error-content": "The mailserver you selected couldn't be reached.", "mailserver-error-content": "The mailserver you selected couldn't be reached.",
"dapps-permissions": "Dapps permissions", "dapps-permissions": "Dapps permissions",
"revoke-access": "Revoke access" "revoke-access": "Revoke access",
"mobile-syncing-sheet-title": "Sync using the mobile network",
"mobile-syncing-sheet-details": "Status tends to use a lot of data when syncing chats. You can choose not to sync when on mobile network",
"mobile-network-continue-syncing": "Continue syncing",
"mobile-network-continue-syncing-details": "You can change this later in settings",
"mobile-network-stop-syncing": "Stop syncing",
"mobile-network-stop-syncing-details": "Until connected to wi-fi?",
"mobile-network-sheet-configure": "You can configure syncing in more \ndetail in",
"mobile-network-sheet-settings": "settings",
"mobile-network-sheet-remember-choice": "Remember my choice"
} }