Introduced onboarding sign in
Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
parent
8b1288e20b
commit
eb8557dde8
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="46" height="46" viewBox="0 0 144 152">
|
||||
<g stroke="none" stroke-width="1" fill-rule="evenodd">
|
||||
<path fill="" d="M41.85,82.81 C61.54,81.7 73.88,86.18 93.57,85.07 C98.4541022,84.8006381 103.305626,84.1080412 108.07,83 C105.16,118.58 79.34,149.68 44.34,151.68 C22.83,152.86 1.33,139.92 0.16,118.86 C-0.98,98.16 15.18,84.31 41.85,82.81 Z M99.53,73.91 C79,75.1 66.1,70.31 45.54,71.5 C40.4407254,71.7827279 35.3770963,72.5223591 30.41,73.71 C33.44,35.69 60.35,2.43 96.94,0.32 C119.39,-0.98 141.83,12.89 143.05,35.39 C144.24,57.51 127.38,72.31 99.53,73.91 Z"></path>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 633 B |
Binary file not shown.
After Width: | Height: | Size: 5.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
|
@ -570,66 +570,6 @@ status.command({
|
|||
}
|
||||
});
|
||||
|
||||
status.response({
|
||||
name: "password",
|
||||
color: "#7099e6",
|
||||
scope: ["personal-chats", "anonymous", "dapps"],
|
||||
description: I18n.t('password_description'),
|
||||
icon: "lock_white",
|
||||
sequentialParams: true,
|
||||
params: [
|
||||
{
|
||||
name: "password",
|
||||
type: status.types.PASSWORD,
|
||||
placeholder: I18n.t('password_placeholder'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
name: "password-confirmation",
|
||||
type: status.types.PASSWORD,
|
||||
placeholder: I18n.t('password_placeholder2'),
|
||||
hidden: true
|
||||
}
|
||||
],
|
||||
validator: function (params, context) {
|
||||
if (!params.hasOwnProperty("password-confirmation") || params["password-confirmation"].length === 0) {
|
||||
if (params.password === null || params.password.length < 6) {
|
||||
var error = status.components.validationMessage(
|
||||
I18n.t('password_validation_title'),
|
||||
I18n.t('password_error')
|
||||
);
|
||||
return {markup: error};
|
||||
}
|
||||
} else {
|
||||
if (params.password !== params["password-confirmation"]) {
|
||||
var error = status.components.validationMessage(
|
||||
I18n.t('password_validation_title'),
|
||||
I18n.t('password_error1')
|
||||
);
|
||||
return {markup: error};
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
preview: function (params, context) {
|
||||
var style = {
|
||||
marginTop: 5,
|
||||
marginHorizontal: 0,
|
||||
fontSize: 14,
|
||||
color: "black"
|
||||
};
|
||||
|
||||
if (context.platform == "ios") {
|
||||
style.fontSize = 8;
|
||||
style.marginTop = 10;
|
||||
style.marginBottom = 2;
|
||||
style.letterSpacing = 1;
|
||||
}
|
||||
|
||||
return {markup: status.components.text({style: style}, "●●●●●●●●●●")};
|
||||
}
|
||||
});
|
||||
|
||||
status.response({
|
||||
name: "grant-permissions",
|
||||
scope: ["personal-chats", "anonymous", "registered", "dapps"],
|
||||
|
|
|
@ -22,11 +22,9 @@
|
|||
;; this listener and handle application's closing
|
||||
;; in handlers
|
||||
(let [stack (subscribe [:get :navigation-stack])
|
||||
creating? (subscribe [:get :accounts/creating-account?])
|
||||
result-box (subscribe [:get-current-chat-ui-prop :result-box])
|
||||
webview (subscribe [:get :webview-bridge])]
|
||||
(cond
|
||||
@creating? true
|
||||
|
||||
(and @webview (:can-go-back? @result-box))
|
||||
(do (.goBack @webview) true)
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
(:require [status-im.ui.components.styles :refer [default-chat-color]]
|
||||
[status-im.utils.random :as random]
|
||||
[status-im.constants :as const]
|
||||
[status-im.chat.constants :as chat-const]
|
||||
[status-im.i18n :as i18n]
|
||||
[clojure.string :as string]))
|
||||
|
||||
|
@ -16,51 +15,6 @@
|
|||
:content content
|
||||
:content-type content-type})
|
||||
|
||||
(def shake-your-phone-message
|
||||
(console-message {:content (i18n/label :t/shake-your-phone)
|
||||
:content-type const/text-content-type}))
|
||||
|
||||
(def account-generation-message
|
||||
(console-message {:message-id chat-const/crazy-math-message-id
|
||||
:content (i18n/label :t/account-generation-message)
|
||||
:content-type const/text-content-type}))
|
||||
|
||||
(def move-to-internal-failure-message
|
||||
(console-message {:message-id chat-const/move-to-internal-failure-message-id
|
||||
:content {:command "grant-permissions"
|
||||
:content (i18n/label :t/move-to-internal-failure-message)}
|
||||
:content-type const/content-type-command-request}))
|
||||
|
||||
(defn passphrase-messages [mnemonic signing-phrase crazy-math-message?]
|
||||
[(console-message {:message-id chat-const/passphrase-message-id
|
||||
:content (if crazy-math-message?
|
||||
(i18n/label :t/phew-here-is-your-passphrase)
|
||||
(i18n/label :t/here-is-your-passphrase))
|
||||
:content-type const/text-content-type})
|
||||
|
||||
(console-message {:message-id (random/id)
|
||||
:content mnemonic
|
||||
:content-type const/text-content-type})
|
||||
|
||||
(console-message {:message-id chat-const/signing-phrase-message-id
|
||||
:content (i18n/label :t/here-is-your-signing-phrase)
|
||||
:content-type const/text-content-type})
|
||||
|
||||
(console-message {:message-id (random/id)
|
||||
:content signing-phrase
|
||||
:content-type const/text-content-type})])
|
||||
|
||||
(def intro-status-message
|
||||
(console-message {:message-id chat-const/intro-status-message-id
|
||||
:content (i18n/label :t/intro-status)
|
||||
:content-type const/content-type-status}))
|
||||
|
||||
(def intro-message1
|
||||
(console-message {:message-id chat-const/intro-message1-id
|
||||
:content {:command "password"
|
||||
:content (i18n/label :t/intro-message1)}
|
||||
:content-type const/content-type-command-request}))
|
||||
|
||||
(def chat
|
||||
{:chat-id const/console-chat-id
|
||||
:name (string/capitalize const/console-chat-id)
|
||||
|
|
|
@ -5,18 +5,10 @@
|
|||
(def arg-wrapping-char "\"")
|
||||
|
||||
(def input-height 56)
|
||||
(def max-input-height 66)
|
||||
(def input-spacing-top 16)
|
||||
|
||||
(def console-chat-id "console")
|
||||
(def crazy-math-message-id "crazy-math-message")
|
||||
(def move-to-internal-failure-message-id "move-to-internal-failure-message")
|
||||
(def passphrase-message-id "passphraze-message")
|
||||
(def signing-phrase-message-id "signing-phrase-message")
|
||||
(def intro-status-message-id "intro-status")
|
||||
(def intro-message1-id "intro-message1")
|
||||
|
||||
;; TODO(janherich): figure out something better then this
|
||||
(def send-command-ref ["transactor" :command 83 "send"])
|
||||
(def request-command-ref ["transactor" :command 83 "request"])
|
||||
(def phone-command-ref ["console" :command 50 "phone"])
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
[status-im.protocol.core :as protocol]
|
||||
[status-im.chat.models :as models]
|
||||
[status-im.chat.console :as console]
|
||||
[status-im.chat.constants :as chat.constants]
|
||||
[status-im.data-store.chats :as chats]
|
||||
[status-im.data-store.messages :as messages]
|
||||
[status-im.data-store.pending-messages :as pending-messages]
|
||||
|
@ -153,18 +152,15 @@
|
|||
(update-in db [:chats chat-id :messages message-id] assoc :appearing? false)))
|
||||
|
||||
(defn init-console-chat
|
||||
[{:keys [chats] :accounts/keys [current-account-id] :as db}]
|
||||
[{:keys [chats] :as db}]
|
||||
(if (chats constants/console-chat-id)
|
||||
{:db db}
|
||||
(cond-> {:db (-> db
|
||||
{:db (-> db
|
||||
(assoc :current-chat-id constants/console-chat-id)
|
||||
(update :chats assoc constants/console-chat-id console/chat))
|
||||
:dispatch-n [[:add-contacts [console/contact]]]
|
||||
:dispatch [:add-contacts [console/contact]]
|
||||
:save-chat console/chat
|
||||
:save-all-contacts [console/contact]}
|
||||
|
||||
(not current-account-id)
|
||||
(update :dispatch-n concat [[:chat-received-message/add-when-commands-loaded console/intro-message1]]))))
|
||||
:save-all-contacts [console/contact]}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:init-console-chat
|
||||
|
@ -186,11 +182,6 @@
|
|||
get-stored-messages
|
||||
stored-unviewed-messages
|
||||
stored-message-ids]} _]
|
||||
(let [{:accounts/keys [account-creation?]} db
|
||||
load-default-contacts-event [:load-default-contacts!]]
|
||||
(if account-creation?
|
||||
{:db db
|
||||
:dispatch load-default-contacts-event}
|
||||
(let [chat->message-id->request (reduce (fn [acc {:keys [chat-id message-id] :as request}]
|
||||
(assoc-in acc [chat-id message-id] request))
|
||||
{}
|
||||
|
@ -210,7 +201,7 @@
|
|||
(assoc :chats chats
|
||||
:deleted-chats inactive-chat-ids)
|
||||
init-console-chat
|
||||
(update :dispatch-n conj load-default-contacts-event)))))))
|
||||
(update :dispatch-n conj [:load-default-contacts!])))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:send-seen!
|
||||
|
@ -232,28 +223,6 @@
|
|||
:message-id message-id}
|
||||
group-chat (assoc :group-id chat-id))})))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:show-mnemonic
|
||||
[re-frame/trim-v]
|
||||
(fn [{:keys [db]} [mnemonic signing-phrase]]
|
||||
(let [crazy-math-message? (contains? (get-in db [:chats chat.constants/console-chat-id]) chat.constants/crazy-math-message-id)
|
||||
messages-events (->> (console/passphrase-messages mnemonic signing-phrase crazy-math-message?)
|
||||
(mapv #(vector :chat-received-message/add %)))]
|
||||
{:dispatch-n messages-events})))
|
||||
|
||||
;; TODO(alwx): can be simplified
|
||||
(handlers/register-handler-fx
|
||||
:account-generation-message
|
||||
(fn [{:keys [db]} _]
|
||||
(when-not (contains? (get-in db [:chats chat.constants/console-chat-id]) chat.constants/passphrase-message-id)
|
||||
{:dispatch [:chat-received-message/add console/account-generation-message]})))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:move-to-internal-failure-message
|
||||
(fn [{:keys [db]} _]
|
||||
(when-not (contains? (get-in db [:chats chat.constants/console-chat-id]) chat.constants/move-to-internal-failure-message-id)
|
||||
{:dispatch [:chat-received-message/add console/move-to-internal-failure-message]})))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:browse-link-from-message
|
||||
(fn [_ [_ link]]
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
(ns status-im.chat.events.console
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.utils.handlers :as handlers]
|
||||
[status-im.constants :as const]
|
||||
(:require [status-im.constants :as constants]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.chat.console :as console-chat]
|
||||
[status-im.ui.screens.accounts.events :as accounts-events]
|
||||
|
@ -24,13 +22,13 @@
|
|||
(console-chat/console-message
|
||||
{:message-id id
|
||||
:content (str type ": " message)
|
||||
:content-type const/text-content-type}))
|
||||
:content-type constants/text-content-type}))
|
||||
messages random-id-seq)]
|
||||
(conj message-events
|
||||
(console-chat/console-message
|
||||
{:message-id (first random-id-seq)
|
||||
:content (str content)
|
||||
:content-type const/text-content-type})))
|
||||
:content-type constants/text-content-type})))
|
||||
(log/debug "ignoring command: " name))))))
|
||||
|
||||
(defn faucet-base-url->url [url]
|
||||
|
@ -40,15 +38,11 @@
|
|||
[:chat-received-message/add
|
||||
(console-chat/console-message {:message-id message-id
|
||||
:content content
|
||||
:content-type const/text-content-type})])
|
||||
:content-type constants/text-content-type})])
|
||||
|
||||
(def console-commands->fx
|
||||
{"password"
|
||||
(fn [{:keys [db]} {:keys [params]}]
|
||||
(accounts-events/create-account db (:password params)))
|
||||
|
||||
"faucet"
|
||||
(fn [{:keys [db random-id]} {:keys [params id]}]
|
||||
{"faucet"
|
||||
(fn [{:keys [db random-id]} {:keys [params]}]
|
||||
(let [{:accounts/keys [accounts current-account-id]} db
|
||||
current-address (get-in accounts [current-account-id :address])
|
||||
faucet-url (faucet-base-url->url (:url params))]
|
||||
|
@ -64,7 +58,7 @@
|
|||
(i18n/label :t/faucet-error)))}}))
|
||||
|
||||
"debug"
|
||||
(fn [{:keys [db random-id now] :as cofx} {:keys [params id]}]
|
||||
(fn [{:keys [db random-id now]} {:keys [params]}]
|
||||
(let [debug? (= "On" (:mode params))]
|
||||
(-> {:db db}
|
||||
(accounts-events/account-update {:debug? debug?
|
||||
|
@ -75,10 +69,10 @@
|
|||
(console-chat/console-message
|
||||
{:message-id random-id
|
||||
:content (i18n/label :t/debug-enabled)
|
||||
:content-type const/text-content-type})]]
|
||||
:content-type constants/text-content-type})]]
|
||||
[[:stop-debugging]])))))})
|
||||
|
||||
(def commands-names (set (keys console-commands->fx)))
|
||||
|
||||
(def commands-with-delivery-status
|
||||
(disj commands-names "password" "faucet" "debug"))
|
||||
(disj commands-names "faucet" "debug"))
|
||||
|
|
|
@ -41,16 +41,6 @@
|
|||
;; regular non command message, we can add it right away
|
||||
(message-model/receive cofx message)))))
|
||||
|
||||
;; TODO janherich: get rid of this special case once they hacky app start-up sequence is refactored
|
||||
(handlers/register-handler-fx
|
||||
:chat-received-message/add-when-commands-loaded
|
||||
message-model/receive-interceptors
|
||||
(fn [{:keys [db] :as cofx} [{:keys [chat-id] :as message}]]
|
||||
(if (and (:status-node-started? db)
|
||||
(get-in db [:contacts/contacts chat-id :jail-loaded?]))
|
||||
(message-model/receive cofx message)
|
||||
{:dispatch-later [{:ms 400 :dispatch [:chat-received-message/add-when-commands-loaded message]}]})))
|
||||
|
||||
;; TODO(alwx): refactor this when status-im.commands.handlers.jail is refactored
|
||||
(handlers/register-handler-fx
|
||||
:chat-received-message/bot-response
|
||||
|
|
|
@ -35,16 +35,11 @@
|
|||
|
||||
(defview chat-toolbar [public?]
|
||||
(letsubs [accounts [:get-accounts]
|
||||
creating? [:get :accounts/creating-account?]
|
||||
{:keys [group-chat name chat-id]} [:get-current-chat]]
|
||||
[react/view
|
||||
[status-bar/status-bar]
|
||||
[toolbar/toolbar {}
|
||||
(when-not creating?
|
||||
(if (empty? accounts)
|
||||
[toolbar/nav-clear-text {:handler #(re-frame/dispatch [:navigate-to-modal :recover-modal])}
|
||||
(i18n/label :t/recover)]
|
||||
toolbar/default-nav-back))
|
||||
toolbar/default-nav-back
|
||||
[toolbar-content/toolbar-content-view]
|
||||
[toolbar/actions [{:icon :icons/options
|
||||
:icon-opts {:color :black}
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
[status-im.commands.utils :as commands-utils]
|
||||
[status-im.utils.datetime :as time]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.i18n :as i18n]))
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.constants :as const]))
|
||||
|
||||
(reg-sub :get-chats :chats)
|
||||
|
||||
|
@ -51,11 +52,15 @@
|
|||
platform/ios? kb-height
|
||||
:default 0)))
|
||||
|
||||
(defn active-chats [[_ chat]]
|
||||
;;TODO (andrey) console should be shown in dev mode only, will be done soon
|
||||
(and (:is-active chat))) ;(not= const/console-chat-id (:chat-id chat))))
|
||||
|
||||
(reg-sub
|
||||
:get-active-chats
|
||||
:<- [:get-chats]
|
||||
(fn [chats]
|
||||
(into {} (filter (comp :is-active second)) chats)))
|
||||
(into {} (filter active-chats chats))))
|
||||
|
||||
(reg-sub
|
||||
:get-chat
|
||||
|
|
|
@ -66,11 +66,9 @@
|
|||
show-actions? [:get-current-chat-ui-prop :show-actions?]
|
||||
accounts [:get-accounts]
|
||||
contact [:get-in [:contacts/contacts @chat-id]]
|
||||
sync-state [:sync-state]
|
||||
creating? [:get :accounts/creating-account?]]
|
||||
sync-state [:sync-state]]
|
||||
[react/view (st/chat-name-view (or (empty? accounts)
|
||||
show-actions?
|
||||
creating?))
|
||||
show-actions?))
|
||||
(let [chat-name (if (string/blank? name)
|
||||
(generate-gfy public-key)
|
||||
(or (i18n/get-contact-translated chat-id :name name)
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
[status-im.data-store.realm.schemas.base.v3.core :as v3]
|
||||
[status-im.data-store.realm.schemas.base.v4.core :as v4]
|
||||
[status-im.data-store.realm.schemas.base.v5.core :as v5]
|
||||
[status-im.data-store.realm.schemas.base.v6.core :as v6]))
|
||||
[status-im.data-store.realm.schemas.base.v6.core :as v6]
|
||||
[status-im.data-store.realm.schemas.base.v7.core :as v7]))
|
||||
|
||||
;; put schemas ordered by version
|
||||
(def schemas [{:schema v1/schema
|
||||
|
@ -24,4 +25,7 @@
|
|||
:migration v5/migration}
|
||||
{:schema v6/schema
|
||||
:schemaVersion 6
|
||||
:migration v6/migration}])
|
||||
:migration v6/migration}
|
||||
{:schema v7/schema
|
||||
:schemaVersion 7
|
||||
:migration v7/migration}])
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
(ns status-im.data-store.realm.schemas.base.v7.account)
|
||||
|
||||
(def schema {:name :account
|
||||
:primaryKey :address
|
||||
:properties {:address :string
|
||||
:public-key :string
|
||||
:updates-public-key {:type :string
|
||||
:optional true}
|
||||
:updates-private-key {:type :string
|
||||
:optional true}
|
||||
:name {:type :string :optional true}
|
||||
:email {:type :string :optional true}
|
||||
:status {:type :string :optional true}
|
||||
:debug? {:type :bool :default false}
|
||||
:photo-path :string
|
||||
:signing-phrase {:type :string}
|
||||
:last-updated {:type :int :default 0}
|
||||
:last-sign-in {:type :int :default 0}
|
||||
:signed-up? {:type :bool
|
||||
:default false}
|
||||
:network :string
|
||||
:networks {:type :list
|
||||
:objectType :network}
|
||||
:wnode :string
|
||||
:settings {:type :string}
|
||||
:sharing-usage-data? {:type :bool :default false}}})
|
|
@ -0,0 +1,10 @@
|
|||
(ns status-im.data-store.realm.schemas.base.v7.core
|
||||
(:require [status-im.data-store.realm.schemas.base.v4.network :as network]
|
||||
[status-im.data-store.realm.schemas.base.v7.account :as account]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def schema [network/schema
|
||||
account/schema])
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating v7 base database: " old-realm new-realm))
|
|
@ -22,4 +22,6 @@
|
|||
|
||||
(def ui
|
||||
{:empty-hashtags (js/require "./resources/images/ui/empty-hashtags.png")
|
||||
:empty-recent (js/require "./resources/images/ui/empty-recent.png")})
|
||||
:empty-recent (js/require "./resources/images/ui/empty-recent.png")
|
||||
:analytics-image (js/require "./resources/images/ui/analytics-image.png")
|
||||
:welcome-image (js/require "./resources/images/ui/welcome-image.png")})
|
|
@ -28,6 +28,26 @@
|
|||
:camera-access-error "To grant the required camera permission, please go to your system settings and make sure that Status > Camera is selected."
|
||||
:photos-access-error "To grant the required photos permission, please go to your system settings and make sure that Status > Photos is selected."
|
||||
|
||||
;;sign in
|
||||
:intro-text "Status is an open source decentralized chat and Ethereum browser"
|
||||
:intro-text-description "Status is built with the help of the community to help you use all the benefits of decentralized web in your mobile phone"
|
||||
:create-account "Create account"
|
||||
:already-have-account "I already have an account"
|
||||
:creating-your-account "Creating your account on the blockchain. We can't touch it, no one can, except for you!"
|
||||
:password-placeholder "Type your password"
|
||||
:password-placeholder2 "Confirm your password"
|
||||
:name-placeholder "Enter your full name…"
|
||||
:password_error1 "Password confirmation doesn't match password."
|
||||
:password-description "You'll need this password to open the app, confirm transactions and whenever you need to regain access on a new device or install."
|
||||
:name-description "This will be the name everybody who uses Status will see. You can change it later."
|
||||
:other-accounts "Other accounts"
|
||||
:sign-you-in "Signing you in…"
|
||||
|
||||
:help-improve "Help improve Status \n by sharing usage data"
|
||||
:help-improve-description "We strive to collect only what we need to understand how and where we can improve Status"
|
||||
:share-usage-data "Share usage data"
|
||||
:dont-want-to-share "No, i don't want to share"
|
||||
|
||||
;;drawer
|
||||
:switch-users "Switch users"
|
||||
:logout-title "Log out?"
|
||||
|
@ -37,6 +57,9 @@
|
|||
|
||||
;;home
|
||||
:home "Home"
|
||||
:no-recent-chats "There are no recent Chats or DApps here yet.\nUse the “Plus” button to see the list of Dapps or discover people to chat with"
|
||||
:welcome-to-status "Welcome to Status"
|
||||
:welcome-to-status-description "Here you can chat with people in a secure private chat, browse and interact with DApps. Use the “Plus” icon above to explore Status"
|
||||
|
||||
;;chat
|
||||
:is-typing "is typing"
|
||||
|
@ -271,6 +294,7 @@
|
|||
:password "Password"
|
||||
:sign-in-to-status "Sign in to Status"
|
||||
:sign-in "Sign in"
|
||||
:sign-in-to-another "Sign in to another account"
|
||||
:wrong-password "Wrong password"
|
||||
:enter-password "Enter password"
|
||||
|
||||
|
@ -278,10 +302,13 @@
|
|||
:passphrase "Passphrase"
|
||||
:recover "Recover"
|
||||
:twelve-words-in-correct-order "12 words in correct order"
|
||||
:enter-12-words "Enter the 12 words of your seed phrase"
|
||||
|
||||
|
||||
;;accounts
|
||||
:recover-access "Recover access"
|
||||
:create-new-account "Create new account"
|
||||
:add-existing-account "Add existing account"
|
||||
|
||||
;;wallet-qr-code
|
||||
:done "Done"
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
:android {:padding-top 8
|
||||
:padding-bottom 8}})
|
||||
|
||||
|
||||
(def action-button-label-disabled
|
||||
(merge action-button-label
|
||||
{:color styles/color-gray4}))
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
(ns status-im.ui.components.colors)
|
||||
(ns status-im.ui.components.colors
|
||||
(:require [clojure.string :as string]))
|
||||
|
||||
(def white "#ffffff")
|
||||
(def white-light-transparent "rgba(255, 255, 255, 0.1)") ;; Used as icon background color for a dark foreground
|
||||
|
@ -7,11 +8,19 @@
|
|||
(def black "#000000") ;; Used as the default text color
|
||||
(def black-transparent "#00000020") ;; Used as background color for rounded button on dark background
|
||||
(def gray "#939ba1") ;; Used as a background for a light foreground and as section header and secondary text color
|
||||
(def gray-icon "#6e777e") ;; Used for forward icon in accounts
|
||||
(def gray-light "#e8ebec") ;; Used as divider color
|
||||
(def gray-lighter "#eef2f5") ;; Used as a background or shadow
|
||||
(def blue "#4360df") ;; Used as main wallet color
|
||||
(def blue-transparent "rgba(67, 96, 223, 0.10)") ;;used as shadow for blue elements
|
||||
(def blue "#4360df") ;; Used as main wallet color, and ios home add button
|
||||
(def red "#ff2d55") ;; Used to highlight errors or "dangerous" actions
|
||||
(def red-light "#ffe5ea") ;; error tooltip
|
||||
(def text-light-gray "#212121") ;; Used for labels (home items)
|
||||
|
||||
(defn alpha [hex opacity]
|
||||
(let [hex (string/replace hex #"#" "")
|
||||
r (js/parseInt (subs hex 0 2) 16)
|
||||
g (js/parseInt (subs hex 2 4) 16)
|
||||
b (js/parseInt (subs hex 4 6) 16)]
|
||||
(str "rgba(" r "," g "," b "," opacity")")))
|
||||
|
||||
(def text black)
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
[status-im.utils.platform :as platform]))
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.components.colors :as colors]))
|
||||
|
||||
(defn top-shadow []
|
||||
(when platform/android?
|
||||
|
@ -63,3 +65,25 @@
|
|||
(if (ethereum/testnet? network-id)
|
||||
(i18n/label :t/testnet-text {:testnet (get-in ethereum/chains [(ethereum/chain-id->chain-keyword network-id) :name] "Unknown")})
|
||||
(i18n/label :t/mainnet-text))]]]))
|
||||
|
||||
(defn logo
|
||||
([] (logo nil))
|
||||
([{:keys [size icon-size shadow?] :or {shadow? true}}]
|
||||
[react/view {:style (styles/logo-container size shadow?)}
|
||||
[icons/icon :icons/logo (styles/logo icon-size)]]))
|
||||
|
||||
(defn bottom-button [{:keys [label disabled? on-press forward?]}]
|
||||
[react/touchable-highlight {:on-press on-press :disabled disabled?}
|
||||
[react/view (styles/bottom-button disabled?)
|
||||
[react/text {:style styles/bottom-button-label
|
||||
:uppercase? platform/android?}
|
||||
(or label (i18n/label :t/next))]
|
||||
(when forward?
|
||||
[icons/icon :icons/forward {:color colors/blue}])]])
|
||||
|
||||
(defn button [{:keys [on-press label background? style] :or {background? true}}]
|
||||
[react/touchable-highlight {:on-press on-press}
|
||||
[react/view {:style (styles/button style background?)}
|
||||
[react/text {:uppercase? platform/android?
|
||||
:style styles/button-label}
|
||||
label]]])
|
|
@ -1,5 +1,5 @@
|
|||
(ns status-im.ui.components.common.styles
|
||||
(:require-macros [status-im.utils.styles :refer [defstyle]])
|
||||
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
|
||||
(:require [status-im.ui.components.styles :as styles]
|
||||
[status-im.ui.components.colors :as colors]))
|
||||
|
||||
|
@ -50,15 +50,6 @@
|
|||
:padding-bottom 17
|
||||
:margin-top 8}})
|
||||
|
||||
(defstyle form-title-extend-container
|
||||
{:ios {:margin-top 16
|
||||
:background-color colors/white}
|
||||
:android {:margin-top 8
|
||||
:background-color colors/gray-lighter}})
|
||||
|
||||
(def form-title-extend-button
|
||||
{:padding 16})
|
||||
|
||||
(defstyle form-title
|
||||
{:flex-shrink 1
|
||||
:ios {:color styles/text1-color
|
||||
|
@ -109,3 +100,51 @@
|
|||
:color colors/blue
|
||||
:ios {:font-size 15}
|
||||
:android {:font-size 14}})
|
||||
|
||||
(defstyle logo-shaddow
|
||||
{:ios {:shadowColor colors/black
|
||||
:shadowOffset {:height 5}
|
||||
:shadowRadius 10
|
||||
:shadowOpacity 0.14}
|
||||
:android {:elevation 2}})
|
||||
|
||||
(defn logo-container [size shadow?]
|
||||
(merge
|
||||
{:width size
|
||||
:height size
|
||||
:border-radius size
|
||||
:background-color colors/blue
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
(when shadow?
|
||||
logo-shaddow)))
|
||||
|
||||
(defn logo [icon-size]
|
||||
{:color :white
|
||||
:width icon-size
|
||||
:height icon-size})
|
||||
|
||||
(defn bottom-button [disabled?]
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:opacity (if disabled? 0.4 1)})
|
||||
|
||||
(def bottom-button-label
|
||||
{:font-size 15
|
||||
:letter-spacing -0.2
|
||||
:color colors/blue})
|
||||
|
||||
(defn button [style background?]
|
||||
(merge
|
||||
{:padding-vertical 12
|
||||
:padding-horizontal 42
|
||||
:border-radius 8}
|
||||
style
|
||||
(when background?
|
||||
{:background-color (colors/alpha colors/blue 0.1)})))
|
||||
|
||||
(def button-label
|
||||
{:font-size 15
|
||||
:letter-spacing -0.2
|
||||
:text-align :center
|
||||
:color colors/blue})
|
||||
|
|
|
@ -77,7 +77,8 @@
|
|||
:icons/network (slurp/slurp-svg "./resources/icons/network.svg")
|
||||
:icons/wnode (slurp/slurp-svg "./resources/icons/wnode.svg")
|
||||
:icons/refresh (slurp/slurp-svg "./resources/icons/refresh.svg")
|
||||
:icons/newchat (slurp/slurp-svg "./resources/icons/newchat.svg")})
|
||||
:icons/newchat (slurp/slurp-svg "./resources/icons/newchat.svg")
|
||||
:icons/logo (slurp/slurp-svg "./resources/icons/logo.svg")})
|
||||
|
||||
(defn normalize-property-name [n]
|
||||
(if (= n :icons/options)
|
||||
|
@ -86,13 +87,13 @@
|
|||
|
||||
(defn icon
|
||||
([name] (icon name nil))
|
||||
([name {:keys [color container-style style accessibility-label]
|
||||
([name {:keys [color container-style style accessibility-label width height]
|
||||
:or {accessibility-label :icon}}]
|
||||
^{:key name}
|
||||
[react/view {:style container-style
|
||||
:accessibility-label accessibility-label}
|
||||
(if-let [icon-fn (get icons (normalize-property-name name))]
|
||||
(icon-fn
|
||||
(let [icon-vec (icon-fn
|
||||
(cond
|
||||
(keyword? color)
|
||||
(case color
|
||||
|
@ -106,5 +107,8 @@
|
|||
(string? color)
|
||||
color
|
||||
:else
|
||||
styles/icon-dark-color))
|
||||
styles/icon-dark-color))]
|
||||
(if width
|
||||
(update icon-vec 1 assoc :width width :height height)
|
||||
icon-vec))
|
||||
(throw (js/Error. (str "Unknown icon: " name))))]))
|
||||
|
|
|
@ -242,11 +242,10 @@
|
|||
:wallet-send-transaction-request
|
||||
:wallet-transaction-fee
|
||||
:contact-code) styles/color-blue4
|
||||
(:accounts
|
||||
:login) styles/color-blue2
|
||||
(:qr-viewer
|
||||
:recipient-qr-code) "#2f3031"
|
||||
(:wallet-transactions-filter
|
||||
(:accounts :login
|
||||
:wallet-transactions-filter
|
||||
:contact-list-modal) styles/color-white
|
||||
:transparent)})
|
||||
children (cond-> children
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
(:require [status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.status-bar.styles :as styles]))
|
||||
|
||||
(defn status-bar [{type :type}]
|
||||
(defn status-bar [{:keys [type flat?]}]
|
||||
(let [[status-bar-style view-style]
|
||||
(case type
|
||||
:main [styles/status-bar-main styles/view-main]
|
||||
|
@ -15,5 +15,5 @@
|
|||
:wallet-tab [styles/status-bar-wallet-tab styles/view-wallet-tab]
|
||||
[styles/status-bar-default styles/view-default])]
|
||||
[react/view
|
||||
[react/status-bar status-bar-style]
|
||||
[react/view {:style view-style}]]))
|
||||
[react/status-bar (cond-> status-bar-style flat? (assoc :elevation 0))]
|
||||
[react/view {:style (cond-> view-style flat? (assoc :elevation 0))}]]))
|
||||
|
|
|
@ -99,10 +99,10 @@
|
|||
:height 24})
|
||||
|
||||
(def icon-add
|
||||
{:width 14
|
||||
:height 14
|
||||
{:width 24
|
||||
:height 24
|
||||
:color colors/blue
|
||||
:container-style {:background-color colors/blue-transparent
|
||||
:container-style {:background-color (colors/alpha colors/blue 0.12)
|
||||
:border-radius 32
|
||||
:width 32
|
||||
:height 32
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
(ns status-im.ui.components.text-input.styles
|
||||
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
|
||||
(:require [status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def label
|
||||
{:font-size 14
|
||||
:letter-spacing -0.2
|
||||
:color colors/black})
|
||||
|
||||
(defn input-container [height]
|
||||
{:padding 16
|
||||
:justify-content :center
|
||||
:margin-vertical 8
|
||||
:height (or height 52)
|
||||
:border-radius 8
|
||||
:background-color colors/gray-lighter})
|
||||
|
||||
(def input
|
||||
{:font-size 15
|
||||
:letter-spacing -0.2
|
||||
:color colors/black
|
||||
:padding 0})
|
||||
|
||||
(def error
|
||||
{:bottom-value -20
|
||||
:color colors/red-light
|
||||
:font-size 12})
|
|
@ -0,0 +1,20 @@
|
|||
(ns status-im.ui.components.text-input.view
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.text-input.styles :as styles]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.tooltip.views :as tooltip]))
|
||||
|
||||
(defn text-input-with-label [{:keys [label error style height] :as props}]
|
||||
[react/view
|
||||
[react/text {:style styles/label}
|
||||
label]
|
||||
[react/view {:style (styles/input-container height)}
|
||||
[react/text-input
|
||||
(merge
|
||||
{:style (merge styles/input style)
|
||||
:placeholder-text-color colors/gray
|
||||
:auto-focus true
|
||||
:auto-capitalize :none}
|
||||
(dissoc props :style :height))]]
|
||||
(when error
|
||||
[tooltip/tooltip error styles/error])])
|
|
@ -1,32 +0,0 @@
|
|||
(ns status-im.ui.components.text-input-with-label.animation
|
||||
(:require [status-im.ui.components.animation :as animation]
|
||||
[clojure.string :as string]))
|
||||
|
||||
(def anim-duration 200)
|
||||
|
||||
(defn animate-underline [underline-width to-line-width underline-height to-line-height]
|
||||
(let [anim (animation/parallel [(animation/timing underline-width {:toValue to-line-width
|
||||
:duration anim-duration})
|
||||
(animation/timing underline-height {:toValue to-line-height
|
||||
:duration anim-duration})])]
|
||||
(animation/start anim)))
|
||||
|
||||
(defn text-input-on-focus [{:keys [underline-width underline-max-width* underline-height underline-max-height]}]
|
||||
(animate-underline underline-width @underline-max-width* underline-height underline-max-height))
|
||||
|
||||
(defn text-input-on-blur [{:keys [underline-width underline-height]}]
|
||||
(animate-underline underline-width 0 underline-height 1))
|
||||
|
||||
(defn animate-label [text {:keys [value* label-top label-font-size
|
||||
label-top-top label-top-bottom label-font-size-top label-font-size-bottom]}]
|
||||
(when (or (string/blank? text) (string/blank? @value*))
|
||||
(let [was-blank? (string/blank? @value*)
|
||||
anim (animation/parallel [(animation/timing label-top {:toValue (if was-blank?
|
||||
label-top-top
|
||||
label-top-bottom)
|
||||
:duration anim-duration})
|
||||
(animation/timing label-font-size {:toValue (if was-blank?
|
||||
label-font-size-top
|
||||
label-font-size-bottom)
|
||||
:duration anim-duration})])]
|
||||
(animation/start anim))))
|
|
@ -1,68 +0,0 @@
|
|||
(ns status-im.ui.components.text-input-with-label.styles
|
||||
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
|
||||
(:require [status-im.utils.platform :as platform]
|
||||
[status-im.ui.components.styles :as common]))
|
||||
|
||||
(defstyle text-input
|
||||
{:placeholder ""
|
||||
:android {:padding-top 0
|
||||
:padding-bottom 0
|
||||
:padding-left 0
|
||||
:margin-top 26
|
||||
:margin-bottom 4
|
||||
:font-size 16}
|
||||
:ios {:margin-top 24
|
||||
:margin-bottom 6
|
||||
:font-size 17
|
||||
:letter-spacing -0.2}})
|
||||
|
||||
(defstyle content-height
|
||||
{:android {:height 24}
|
||||
:ios {:height 26}})
|
||||
|
||||
(defstyle component-container
|
||||
{:margin-left 16
|
||||
:android {:min-height 76}
|
||||
:ios {:min-height 78}})
|
||||
|
||||
(defnstyle label-animated-text [{:keys [label-top label-font-size]}]
|
||||
{:position :absolute
|
||||
:top label-top
|
||||
:font-size label-font-size
|
||||
:color common/color-gray4
|
||||
:ios {:letter-spacing -0.2}})
|
||||
|
||||
(defstyle description-text
|
||||
{:color common/color-gray4
|
||||
:android {:margin-top 6
|
||||
:font-size 12}
|
||||
:ios {:margin-top 4
|
||||
:font-size 14
|
||||
:letter-spacing -0.2}})
|
||||
|
||||
(defstyle error-text
|
||||
{:color common/color-red-2
|
||||
:android {:margin-top 6
|
||||
:font-size 12}
|
||||
:ios {:margin-top 4
|
||||
:font-size 14
|
||||
:letter-spacing -0.2}})
|
||||
|
||||
(defn underline-blured [error]
|
||||
{:background-color (if error common/color-red-2 common/color-light-gray2)
|
||||
:align-items :center})
|
||||
|
||||
(defn underline-focused [underline-width underline-height error]
|
||||
{:height underline-height
|
||||
:width underline-width
|
||||
:background-color (if error common/color-red-2 common/color-light-blue)})
|
||||
|
||||
(def label-top-top (if platform/ios? 6 6))
|
||||
|
||||
(def label-top-bottom (if platform/ios? 26 26))
|
||||
|
||||
(def label-font-size-top (if platform/ios? 14 12))
|
||||
|
||||
(def label-font-size-bottom (if platform/ios? 17 16))
|
||||
|
||||
(def underline-max-height (if platform/ios? 1 2))
|
|
@ -1,72 +0,0 @@
|
|||
(ns status-im.ui.components.text-input-with-label.view
|
||||
(:require [reagent.core :as reagent]
|
||||
[status-im.ui.components.animation :as animation]
|
||||
[status-im.ui.components.text-input-with-label.animation :as label-animation]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.text-input-with-label.styles :as styles]
|
||||
[clojure.string :as string]))
|
||||
|
||||
(defn get-init-props [{:keys [default-value]}]
|
||||
(let [blank? (string/blank? default-value)]
|
||||
{:underline-width (animation/create-value 0)
|
||||
:underline-height (animation/create-value 1)
|
||||
:label-top (animation/create-value (if blank?
|
||||
styles/label-top-bottom
|
||||
styles/label-top-top))
|
||||
:label-font-size (animation/create-value (if blank?
|
||||
styles/label-font-size-bottom
|
||||
styles/label-font-size-top))
|
||||
:label-top-top styles/label-top-top
|
||||
:label-top-bottom styles/label-top-bottom
|
||||
:label-font-size-top styles/label-font-size-top
|
||||
:label-font-size-bottom styles/label-font-size-bottom
|
||||
:underline-max-height styles/underline-max-height
|
||||
:input-ref* (reagent/atom nil)
|
||||
:value* (reagent/atom default-value)
|
||||
:underline-max-width* (reagent/atom 0)}))
|
||||
|
||||
(defn get-width [event]
|
||||
(.-width (.-layout (.-nativeEvent event))))
|
||||
|
||||
(defn text-input-on-change-text [text props]
|
||||
(label-animation/animate-label text props)
|
||||
(reset! (:value* props) text))
|
||||
|
||||
(defn text-input-handlers [{:keys [on-focus on-blur on-change-text on-change
|
||||
on-submit-editing max-height ref]} props]
|
||||
{:ref #(do
|
||||
(reset! (:input-ref* props) %)
|
||||
(when ref (ref %)))
|
||||
:on-submit-editing #(do
|
||||
(.blur @(:input-ref* props))
|
||||
(when on-submit-editing (on-submit-editing)))
|
||||
:on-focus #(do
|
||||
(label-animation/text-input-on-focus props)
|
||||
(when on-focus (on-focus)))
|
||||
:on-blur #(do
|
||||
(label-animation/text-input-on-blur props)
|
||||
(when on-blur (on-blur)))
|
||||
:on-change-text #(do
|
||||
(text-input-on-change-text % props)
|
||||
(when on-change-text (on-change-text %)))})
|
||||
|
||||
(defn text-input-with-label [options]
|
||||
(let [props (get-init-props options)]
|
||||
(fn [{:keys [label description error hide-underline? auto-expanding multiline] :as options}]
|
||||
[react/view styles/component-container
|
||||
[react/animated-text {:style (styles/label-animated-text props)} label]
|
||||
[react/text-input (merge styles/text-input
|
||||
(when-not (and auto-expanding multiline)
|
||||
styles/content-height)
|
||||
(dissoc options :label :description :error :auto-expanding :hide-underline?)
|
||||
(text-input-handlers options props))]
|
||||
(when-not hide-underline?
|
||||
[react/view {:style (styles/underline-blured error)
|
||||
:on-layout #(reset! (:underline-max-width* props) (get-width %))}
|
||||
[react/animated-view {:style (styles/underline-focused (:underline-width props)
|
||||
(:underline-height props)
|
||||
error)}]])
|
||||
(cond error
|
||||
[react/text {:style styles/error-text} error]
|
||||
description
|
||||
[react/text {:style styles/description-text} description])])))
|
|
@ -19,15 +19,13 @@
|
|||
:android {:height 55}
|
||||
:ios {:height 56}})
|
||||
|
||||
(defnstyle toolbar-nav-actions-container
|
||||
[actions]
|
||||
(def toolbar-nav-actions-container
|
||||
{:flex-direction :row
|
||||
:margin-left 4})
|
||||
|
||||
(defstyle toolbar-container
|
||||
{:flex 1
|
||||
:android {:padding-left 18}
|
||||
:ios {:align-items :center}})
|
||||
:align-items :center})
|
||||
|
||||
(def toolbar-title-container
|
||||
{:flex 1
|
||||
|
@ -38,15 +36,7 @@
|
|||
{:color styles/text1-color
|
||||
:letter-spacing -0.2
|
||||
:font-size 17
|
||||
:ios {:text-align "center"}})
|
||||
|
||||
(defstyle toolbar-border-container
|
||||
{:ios {:background-color styles/color-white}})
|
||||
|
||||
(defstyle toolbar-border
|
||||
{:ios {:height 1
|
||||
:background-color styles/color-gray5
|
||||
:opacity 0.5}})
|
||||
:text-align :center})
|
||||
|
||||
(def toolbar-actions
|
||||
{:flex 0
|
||||
|
@ -72,10 +62,6 @@
|
|||
{:padding-vertical 16
|
||||
:padding-horizontal 12})
|
||||
|
||||
(def nav-item-text
|
||||
{:padding-vertical 18
|
||||
:padding-horizontal 16})
|
||||
|
||||
(defstyle item
|
||||
{:ios {:margin-horizontal 12
|
||||
:margin-vertical 16}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
(ns status-im.ui.components.toolbar.view
|
||||
(:require [reagent.core :as reagent]
|
||||
[re-frame.core :as re-frame]
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.list-selection :as list-selection]
|
||||
[status-im.ui.components.react :as react]
|
||||
|
@ -110,21 +108,17 @@
|
|||
|
||||
(defn toolbar
|
||||
([props nav-item content-item] (toolbar props nav-item content-item [actions [{:image :blank}]]))
|
||||
([{:keys [background-color style flat? title-centered?]}
|
||||
([{:keys [background-color style flat?]}
|
||||
nav-item
|
||||
content-item
|
||||
action-items]
|
||||
[react/view {:style (merge (styles/toolbar background-color flat?) style)}
|
||||
;; On iOS title must be centered. Current solution is a workaround and eventually this will be sorted out using flex
|
||||
(when (or title-centered? platform/ios?)
|
||||
[react/view styles/ios-content-item
|
||||
content-item])
|
||||
content-item]
|
||||
(when nav-item
|
||||
[react/view {:style (styles/toolbar-nav-actions-container 0)}
|
||||
[react/view {:style styles/toolbar-nav-actions-container}
|
||||
nav-item])
|
||||
(if (or title-centered? platform/ios?)
|
||||
[react/view components.styles/flex]
|
||||
content-item)
|
||||
action-items]))
|
||||
|
||||
(defn simple-toolbar
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
(ns status-im.ui.components.tooltip.animations
|
||||
(:require [status-im.ui.components.animation :as animation]))
|
||||
|
||||
(defn animate-tooltip [bottom-value bottom-anim-value opacity-value]
|
||||
(fn []
|
||||
(animation/start
|
||||
(animation/parallel
|
||||
[(animation/timing opacity-value {:toValue 1
|
||||
:duration 500})
|
||||
(animation/timing bottom-anim-value {:toValue (- bottom-value 10)
|
||||
:easing (.bezier (animation/easing) 0.685, 0.000, 0.025, 1.185)
|
||||
:duration 500})]))))
|
|
@ -0,0 +1,31 @@
|
|||
(ns status-im.ui.components.tooltip.styles
|
||||
(:require [status-im.ui.components.styles :as styles]))
|
||||
|
||||
(def tooltip-container
|
||||
{:position :absolute
|
||||
:align-items :center
|
||||
:left 0
|
||||
:right 0
|
||||
:top 0})
|
||||
|
||||
(defn tooltip-animated [bottom-value opacity-value]
|
||||
{:position :absolute
|
||||
:align-items :center
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom bottom-value
|
||||
:opacity opacity-value})
|
||||
|
||||
(defn tooltip-text-container [color]
|
||||
{:padding-horizontal 16
|
||||
:padding-vertical 9
|
||||
:background-color color
|
||||
:border-radius 8})
|
||||
|
||||
(defn tooltip-text [font-size]
|
||||
{:color styles/color-red-2
|
||||
:font-size font-size})
|
||||
|
||||
(def tooltip-triangle
|
||||
{:width 16
|
||||
:height 8})
|
|
@ -0,0 +1,17 @@
|
|||
(ns status-im.ui.components.tooltip.views
|
||||
(:require-macros [status-im.utils.views :as views])
|
||||
(:require [status-im.ui.components.animation :as animation]
|
||||
[status-im.ui.components.tooltip.animations :as animations]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.tooltip.styles :as styles]))
|
||||
|
||||
(views/defview tooltip [label & [{:keys [bottom-value color font-size] :or {bottom-value -30 color :white font-size 15}}]]
|
||||
(views/letsubs [bottom-anim-value (animation/create-value bottom-value)
|
||||
opacity-value (animation/create-value 0)]
|
||||
{:component-did-mount (animations/animate-tooltip bottom-value bottom-anim-value opacity-value)}
|
||||
[react/view styles/tooltip-container
|
||||
[react/animated-view {:style (styles/tooltip-animated bottom-value opacity-value)}
|
||||
[react/view (styles/tooltip-text-container color)
|
||||
[react/text {:style (styles/tooltip-text font-size)} label]]
|
||||
[vector-icons/icon :icons/tooltip-triangle {:color color :style styles/tooltip-triangle}]]]))
|
|
@ -0,0 +1,9 @@
|
|||
(ns status-im.ui.screens.accounts.create.navigation
|
||||
(:require [status-im.ui.screens.navigation :as nav]))
|
||||
|
||||
(defmethod nav/preload-data! :create-account
|
||||
[db]
|
||||
(update db :accounts/create
|
||||
#(-> %
|
||||
(assoc :step :enter-password)
|
||||
(dissoc :password :password-confirm :name :error))))
|
|
@ -0,0 +1,58 @@
|
|||
(ns status-im.ui.screens.accounts.create.styles
|
||||
(:require [status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def create-account-view
|
||||
{:flex 1
|
||||
:background-color colors/white})
|
||||
|
||||
(def account-creating-view
|
||||
{:flex 1
|
||||
:padding-horizontal 14})
|
||||
|
||||
(def account-creating-logo-container
|
||||
{:margin-top 37
|
||||
:align-items :center})
|
||||
|
||||
(def account-creating-logo
|
||||
{:size 82
|
||||
:icon-size 34})
|
||||
|
||||
(def account-creating-indicatior
|
||||
{:flex 1
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:margin-bottom 100})
|
||||
|
||||
(def account-creating-text
|
||||
{:font-size 14
|
||||
:line-height 21
|
||||
:letter-spacing -0.2
|
||||
:text-align :center
|
||||
:color colors/black
|
||||
:margin-top 16})
|
||||
|
||||
(def logo-container
|
||||
{:position :absolute
|
||||
:top 37
|
||||
:left 0
|
||||
:right 0
|
||||
:align-items :center})
|
||||
|
||||
(def logo
|
||||
{:size 82
|
||||
:icon-size 34})
|
||||
|
||||
(def input-container
|
||||
{:margin-horizontal 16
|
||||
:margin-top 105})
|
||||
|
||||
(def input-description
|
||||
{:font-size 14
|
||||
:letter-spacing -0.2
|
||||
:color colors/gray
|
||||
:line-height 21})
|
||||
|
||||
(def bottom-container
|
||||
{:flex-direction :row
|
||||
:margin-horizontal 12
|
||||
:margin-vertical 15})
|
|
@ -0,0 +1,85 @@
|
|||
(ns status-im.ui.screens.accounts.create.views
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]
|
||||
[status-im.i18n :as i18n]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ui.components.styles :as components.styles]
|
||||
[status-im.ui.components.toolbar.actions :as actions]
|
||||
[status-im.ui.components.react :as components]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.text-input.view :as text-input]
|
||||
[status-im.ui.screens.accounts.create.styles :as styles]))
|
||||
|
||||
(def steps
|
||||
{:enter-password {:input-key :password
|
||||
:input-label (i18n/label :t/password)
|
||||
:input-placeholder (i18n/label :t/password-placeholder)
|
||||
:input-description (i18n/label :t/password-description)}
|
||||
:confirm-password {:input-key :password-confirm
|
||||
:input-label (i18n/label :t/confirm)
|
||||
:input-placeholder (i18n/label :t/password-placeholder2)
|
||||
:input-description (i18n/label :t/password-description)}
|
||||
:account-creating nil
|
||||
:enter-name {:input-key :name
|
||||
:input-label (i18n/label :t/name)
|
||||
:input-placeholder (i18n/label :t/name-placeholder)
|
||||
:input-description (i18n/label :t/name-description)}})
|
||||
|
||||
(defn next-step [step password password-confirm]
|
||||
(case step
|
||||
:enter-password (re-frame/dispatch [:set-in [:accounts/create :step] :confirm-password])
|
||||
:confirm-password (if (= password password-confirm)
|
||||
(re-frame/dispatch [:create-account])
|
||||
(re-frame/dispatch [:set-in [:accounts/create :error] (i18n/label :t/password_error1)]))
|
||||
:enter-name (re-frame/dispatch [:account-set-name])))
|
||||
|
||||
(defn step-back [step]
|
||||
(case step
|
||||
:enter-password (re-frame/dispatch [:navigate-back])
|
||||
:confirm-password (re-frame/dispatch [:reset-account-creation])))
|
||||
|
||||
(defview input [step error]
|
||||
[text-input/text-input-with-label
|
||||
{:label (get-in steps [step :input-label])
|
||||
:placeholder (get-in steps [step :input-placeholder])
|
||||
:on-change-text #(re-frame/dispatch [:set-in [:accounts/create (get-in steps [step :input-key])] %])
|
||||
:secure-text-entry (boolean (#{:enter-password :confirm-password} step))
|
||||
:error error}])
|
||||
|
||||
(defview create-account []
|
||||
(letsubs [step [:get-in [:accounts/create :step]]
|
||||
next-enabled? [:get-account-creation-next-enabled?]
|
||||
error [:get-in [:accounts/create :error]]
|
||||
password [:get-in [:accounts/create :password]]
|
||||
password-confirm [:get-in [:accounts/create :password-confirm]]]
|
||||
[react/keyboard-avoiding-view {:style styles/create-account-view}
|
||||
[status-bar/status-bar {:flat? true}]
|
||||
(when (= :account-creating step)
|
||||
[react/view styles/account-creating-view
|
||||
[react/view styles/account-creating-logo-container
|
||||
[components.common/logo styles/account-creating-logo]]
|
||||
[react/view {:style styles/account-creating-indicatior}
|
||||
[components/activity-indicator {:animating true}]
|
||||
[react/text {:style styles/account-creating-text}
|
||||
(i18n/label :t/creating-your-account)]]])
|
||||
(when (#{:enter-password :confirm-password :enter-name} step)
|
||||
[react/view components.styles/flex
|
||||
[toolbar/toolbar {:flat? true} (when (#{:enter-password :confirm-password} step)
|
||||
(toolbar/nav-button (actions/back #(step-back step)))) nil]
|
||||
[react/view {:style styles/logo-container}
|
||||
[components.common/logo styles/logo]]
|
||||
^{:key (str "step" step)}
|
||||
[react/view components.styles/flex
|
||||
[react/view {:style styles/input-container}
|
||||
[input step error]
|
||||
[react/text {:style styles/input-description}
|
||||
(get-in steps [step :input-description])]]
|
||||
[react/view {:style components.styles/flex}]
|
||||
[react/view {:style styles/bottom-container}
|
||||
[react/view {:style components.styles/flex}]
|
||||
[components.common/bottom-button
|
||||
{:forward? true
|
||||
:disabled? (not next-enabled?)
|
||||
:on-press #(next-step step password password-confirm)}]]]])]))
|
|
@ -2,7 +2,13 @@
|
|||
(:require-macros [status-im.utils.db :refer [allowed-keys]])
|
||||
(:require [cljs.spec.alpha :as spec]
|
||||
status-im.utils.db
|
||||
status-im.ui.screens.network-settings.db))
|
||||
status-im.ui.screens.network-settings.db
|
||||
[status-im.constants :as const]))
|
||||
|
||||
(defn valid-length? [password]
|
||||
(>= (count password) const/min-password-length))
|
||||
|
||||
(spec/def ::password (spec/and :global/not-empty-string valid-length?))
|
||||
|
||||
(spec/def :account/address :global/address)
|
||||
(spec/def :account/name :global/not-empty-string)
|
||||
|
@ -11,6 +17,7 @@
|
|||
(spec/def :account/email nil?)
|
||||
(spec/def :account/signed-up? (spec/nilable boolean?))
|
||||
(spec/def :account/last-updated (spec/nilable int?))
|
||||
(spec/def :account/last-sign-in (spec/nilable int?))
|
||||
(spec/def :account/updates-private-key :global/not-empty-string)
|
||||
(spec/def :account/updates-public-key :global/not-empty-string)
|
||||
(spec/def :account/photo-path (spec/nilable string?))
|
||||
|
@ -21,6 +28,7 @@
|
|||
(spec/def :account/wnode (spec/nilable string?))
|
||||
(spec/def :account/settings (spec/nilable (spec/map-of keyword? any?)))
|
||||
(spec/def :account/signing-phrase :global/not-empty-string)
|
||||
(spec/def :account/sharing-usage-data? (spec/nilable boolean?))
|
||||
|
||||
(spec/def :accounts/account (allowed-keys
|
||||
:req-un [:account/name :account/address :account/public-key
|
||||
|
@ -28,16 +36,16 @@
|
|||
:opt-un [:account/debug? :account/status :account/last-updated
|
||||
:account/updates-private-key :account/updates-public-key
|
||||
:account/email :account/signed-up? :account/network
|
||||
:account/networks :account/settings :account/wnode]))
|
||||
:account/networks :account/settings :account/wnode
|
||||
:account/last-sign-in :account/sharing-usage-data?]))
|
||||
|
||||
(spec/def :accounts/accounts (spec/nilable (spec/map-of :account/address :accounts/account)))
|
||||
|
||||
;;true during creating new account
|
||||
(spec/def :accounts/account-creation? (spec/nilable boolean?))
|
||||
;;true during login just created account
|
||||
(spec/def :accounts/creating-account? (spec/nilable boolean?))
|
||||
;;id of logged in account
|
||||
(spec/def :accounts/current-account-id (spec/nilable string?))
|
||||
|
||||
;;used during creating account
|
||||
(spec/def :accounts/create (spec/nilable map?))
|
||||
;;used during recovering account
|
||||
(spec/def :accounts/recover (spec/nilable map?))
|
||||
;;used during logging
|
||||
|
|
|
@ -13,17 +13,8 @@
|
|||
[status-im.ui.screens.accounts.statuses :as statuses]
|
||||
[status-im.utils.signing-phrase.core :as signing-phrase]
|
||||
[status-im.utils.gfycat.core :refer [generate-gfy]]
|
||||
[status-im.utils.hex :as utils.hex]))
|
||||
|
||||
;;;; Helper fns
|
||||
|
||||
(defn create-account
|
||||
"Takes db and password, creates map of effects describing account creation"
|
||||
[db password]
|
||||
{:db (assoc db :accounts/creating-account? true)
|
||||
::create-account password
|
||||
;; TODO(janherich): get rid of this shitty delayed dispatch once sending commands/msgs is refactored
|
||||
:dispatch-later [{:ms 400 :dispatch [:account-generation-message]}]})
|
||||
[status-im.utils.hex :as utils.hex]
|
||||
status-im.ui.screens.accounts.create.navigation))
|
||||
|
||||
;;;; COFX
|
||||
|
||||
|
@ -90,6 +81,12 @@
|
|||
:private updates-private-key}}}}))))
|
||||
;;;; Handlers
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:create-account
|
||||
(fn [{{:accounts/keys [create] :as db} :db}]
|
||||
{:db (update db :accounts/create assoc :step :account-creating :error nil)
|
||||
::create-account (:password create)}))
|
||||
|
||||
(defn add-account
|
||||
"Takes db and new account, creates map of effects describing adding account to database and realm"
|
||||
[{:keys [network inbox/wnode] :networks/keys [networks] :as db} {:keys [address] :as account}]
|
||||
|
@ -126,15 +123,7 @@
|
|||
(log/debug "account-created")
|
||||
(when-not (str/blank? pubkey)
|
||||
(-> (add-account db account)
|
||||
(assoc :dispatch-n [[:show-mnemonic mnemonic signing-phrase]
|
||||
[:login-account normalized-address password true]]))))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:create-new-account-handler
|
||||
(fn [_ _]
|
||||
{:dispatch-n [[:initialize-db]
|
||||
[:load-accounts]
|
||||
[:check-console-chat true]]}))
|
||||
(assoc :dispatch [:login-account normalized-address password true]))))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:load-accounts
|
||||
|
@ -204,3 +193,20 @@
|
|||
;; TODO(janherich): this is very strange and misleading, need to figure out why it'd necessary to update
|
||||
;; account with network update when last update was more then week ago
|
||||
(account-update {:db db} nil)))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:account-set-name
|
||||
(fn [{{:accounts/keys [create] :as db} :db} _]
|
||||
(-> {:db (assoc-in db [:accounts/create :show-welcome?] true)
|
||||
:dispatch [:navigate-to-clean :usage-data]}
|
||||
(account-update {:name (:name create)}))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:update-sign-in-time
|
||||
(fn [{db :db now :now} _]
|
||||
(account-update {:db db} {:last-sign-in now})))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:reset-account-creation
|
||||
(fn [{db :db} _]
|
||||
{:db (update db :accounts/create assoc :step :enter-password :password nil :password-confirm nil :error nil)}))
|
|
@ -3,11 +3,9 @@
|
|||
[re-frame.core :refer [dispatch reg-fx]]
|
||||
[status-im.utils.handlers :refer [register-handler-db register-handler-fx]]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.chat.console :as console-chat]
|
||||
[status-im.utils.types :refer [json->clj]]
|
||||
[status-im.data-store.core :as data-store]
|
||||
[status-im.native-module.core :as status]
|
||||
[status-im.constants :refer [console-chat-id]]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im.constants :as constants]))
|
||||
|
@ -16,7 +14,6 @@
|
|||
|
||||
(reg-fx ::stop-node (fn [] (status/stop-node)))
|
||||
|
||||
|
||||
(reg-fx
|
||||
::login
|
||||
(fn [[address password]]
|
||||
|
@ -94,11 +91,10 @@
|
|||
(register-handler-fx
|
||||
:login-account
|
||||
(fn [{{:keys [network status-node-started?] :as db} :db}
|
||||
[_ address password account-creation?]]
|
||||
[_ address password]]
|
||||
(let [{account-network :network} (get-network-by-address db address)
|
||||
wnode (get-wnode-by-address db address)
|
||||
db' (-> db
|
||||
(assoc :accounts/account-creation? account-creation?)
|
||||
(assoc :inbox/wnode wnode)
|
||||
(assoc-in [:accounts/login :processing] true))
|
||||
wrap-fn (cond (not status-node-started?)
|
||||
|
@ -113,32 +109,27 @@
|
|||
|
||||
(register-handler-fx
|
||||
:login-handler
|
||||
(fn [{{:accounts/keys [account-creation?] :as db} :db} [_ login-result address]]
|
||||
(fn [{db :db} [_ login-result address]]
|
||||
(let [data (json->clj login-result)
|
||||
error (:error data)
|
||||
success (zero? (count error))
|
||||
db' (assoc-in db [:accounts/login :processing] false)]
|
||||
(log/debug "Logging result: " login-result)
|
||||
(merge
|
||||
{:db (if success db' (assoc-in db' [:accounts/login :error] error))}
|
||||
(when success
|
||||
(log/debug "Logged in" (when account-creation? " new account") ":" address)
|
||||
{::clear-web-data nil
|
||||
::change-account [address account-creation?]})))))
|
||||
(if success
|
||||
{:db db'
|
||||
::clear-web-data nil
|
||||
::change-account [address]}
|
||||
{:db (assoc-in db' [:accounts/login :error] error)}))))
|
||||
|
||||
(register-handler-fx
|
||||
:change-account-handler
|
||||
(fn [{db :db} [_ error address new-account?]]
|
||||
(let [recover-in-progress? (:accounts/recover db)]
|
||||
(fn [{{:keys [view-id] :as db} :db} [_ error address]]
|
||||
(if (nil? error)
|
||||
{:db (dissoc db :accounts/login)
|
||||
:dispatch-n [[:stop-debugging]
|
||||
[:initialize-account
|
||||
address
|
||||
(when (or new-account? recover-in-progress?)
|
||||
[[:chat-received-message/add console-chat/shake-your-phone-message]])]
|
||||
[:navigate-to-clean :home]
|
||||
(if new-account?
|
||||
[:navigate-to-chat console-chat-id]
|
||||
[:navigate-to :home])]}
|
||||
(log/debug "Error changing acount: " error)))))
|
||||
{:db (cond-> (dissoc db :accounts/login)
|
||||
(= view-id :create-account)
|
||||
(assoc-in [:accounts/create :step] :enter-name))
|
||||
:dispatch-n (concat
|
||||
[[:stop-debugging]
|
||||
[:initialize-account address]]
|
||||
(when (not= view-id :create-account)
|
||||
[[:navigate-to-clean :home]]))}
|
||||
(log/debug "Error changing acount: " error))))
|
||||
|
|
|
@ -1,46 +1,44 @@
|
|||
(ns status-im.ui.screens.accounts.login.styles
|
||||
(:require-macros [status-im.utils.styles :refer [defnstyle defstyle]])
|
||||
(:require [status-im.ui.components.styles :as st]))
|
||||
(:require [status-im.ui.components.styles :as st]
|
||||
[status-im.ui.components.colors :as colors]))
|
||||
|
||||
(defstyle login-view
|
||||
{:flex 1
|
||||
:ios {:margin-top 10
|
||||
:margin-bottom 10}
|
||||
:android {:margin-top 16
|
||||
:margin-bottom 16}
|
||||
:margin-horizontal 16})
|
||||
|
||||
(defstyle login-badge-container
|
||||
{:background-color :white
|
||||
:ios {:padding-top 16
|
||||
:height 150}
|
||||
:android {:border-radius 4
|
||||
:padding-top 12
|
||||
:height 144}})
|
||||
|
||||
(defstyle sign-it-text
|
||||
{:color :white
|
||||
:ios {:font-size 17
|
||||
:letter-spacing -0.2}
|
||||
:android {:font-size 16}})
|
||||
|
||||
(def sign-it-disabled-text
|
||||
(merge sign-it-text
|
||||
{:color st/color-gray2}))
|
||||
|
||||
(def sign-in-button
|
||||
{:background-color st/color-blue3
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:height 52
|
||||
:border-radius 8})
|
||||
{:margin-top 24})
|
||||
|
||||
(def processing-view
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:bottom 0
|
||||
:right 0
|
||||
:left 0
|
||||
{:flex 1
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:background-color (str st/color-black "1A")})
|
||||
:justify-content :center})
|
||||
|
||||
(def sign-you-in
|
||||
{:margin-top 16
|
||||
:font-size 13
|
||||
:letter-spacing -0.2
|
||||
:color colors/text-light-gray})
|
||||
|
||||
(def bottom-button-container
|
||||
{:flex-direction :row
|
||||
:margin-horizontal 12
|
||||
:margin-vertical 15
|
||||
:align-items :center})
|
||||
|
||||
(def login-badge
|
||||
{:align-items :center})
|
||||
|
||||
(def login-badge-image
|
||||
{:width 56
|
||||
:height 56
|
||||
:border-radius 28})
|
||||
|
||||
(def login-badge-name
|
||||
{:font-size 15
|
||||
:color colors/text-light-gray
|
||||
:margin-top 8})
|
||||
|
||||
(def password-container
|
||||
{:margin-top 24})
|
|
@ -1,28 +1,30 @@
|
|||
(ns status-im.ui.screens.accounts.login.views
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :refer [dispatch dispatch-sync]]
|
||||
[status-im.ui.screens.accounts.styles :as ast]
|
||||
[status-im.ui.screens.accounts.views :refer [account-badge]]
|
||||
[status-im.ui.components.text-input-with-label.view :refer [text-input-with-label]]
|
||||
[status-im.ui.components.status-bar.view :refer [status-bar]]
|
||||
[status-im.ui.components.text-input.view :as text-input]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.components.toolbar.actions :as act]
|
||||
[status-im.ui.screens.accounts.login.styles :as st]
|
||||
[status-im.ui.screens.accounts.login.styles :as styles]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.react :as components]))
|
||||
[status-im.ui.components.react :as components]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[re-frame.core :as re-frame]
|
||||
[cljs.spec.alpha :as spec]
|
||||
[status-im.ui.screens.accounts.db :as db]))
|
||||
|
||||
(defn login-toolbar []
|
||||
[toolbar/toolbar {:background-color :transparent}
|
||||
[toolbar/nav-button (act/back-white #(dispatch [:navigate-back]))]
|
||||
[toolbar/content-title {:color :white} (i18n/label :t/sign-in-to-status)]])
|
||||
|
||||
(def password-text-input (atom nil))
|
||||
(defn login-toolbar [can-navigate-back?]
|
||||
[toolbar/toolbar
|
||||
nil
|
||||
(when can-navigate-back?
|
||||
[toolbar/nav-button act/default-back])
|
||||
[toolbar/content-title (i18n/label :t/sign-in-to-status)]])
|
||||
|
||||
(defn login-account [password-text-input address password]
|
||||
(.blur @password-text-input)
|
||||
(dispatch [:login-account address password]))
|
||||
(.blur password-text-input)
|
||||
(re-frame/dispatch [:login-account address password]))
|
||||
|
||||
(defn- error-key [error]
|
||||
;; TODO Improve selection logic when status-go provide an error code
|
||||
|
@ -37,31 +39,53 @@
|
|||
:else
|
||||
:t/unknown-status-go-error))
|
||||
|
||||
(defn account-login-badge [photo-path name]
|
||||
[react/view styles/login-badge
|
||||
[react/image {:source {:uri (if (string/blank? photo-path) :avatar photo-path)}
|
||||
:style styles/login-badge-image}]
|
||||
[react/view
|
||||
[react/text {:style styles/login-badge-name
|
||||
:numberOfLines 1}
|
||||
name]]])
|
||||
|
||||
(defview login []
|
||||
(letsubs [{:keys [address photo-path name password error processing]} [:get :accounts/login]]
|
||||
[react/view ast/accounts-container
|
||||
[status-bar {:type :transparent}]
|
||||
[login-toolbar]
|
||||
[react/view st/login-view
|
||||
[react/view st/login-badge-container
|
||||
[account-badge address photo-path name]
|
||||
[react/view {:height 8}]
|
||||
[text-input-with-label {:ref #(reset! password-text-input %)
|
||||
:label (i18n/label :t/password)
|
||||
:auto-capitalize :none
|
||||
:hide-underline? true
|
||||
(letsubs [{:keys [address photo-path name password error processing]} [:get :accounts/login]
|
||||
can-navigate-back? [:can-navigate-back?]
|
||||
password-text-input (atom nil)]
|
||||
[react/keyboard-avoiding-view {:style ast/accounts-view}
|
||||
[status-bar/status-bar]
|
||||
[login-toolbar can-navigate-back?]
|
||||
[components.common/separator]
|
||||
[react/view styles/login-view
|
||||
[react/view styles/login-badge-container
|
||||
[account-login-badge photo-path name]
|
||||
[react/view styles/password-container
|
||||
[text-input/text-input-with-label
|
||||
{:label (i18n/label :t/password)
|
||||
:placeholder (i18n/label :t/password)
|
||||
:ref #(reset! password-text-input %)
|
||||
:auto-focus can-navigate-back? ;;this needed because keyboard overlays testfairy alert
|
||||
:on-submit-editing #(login-account @password-text-input address password)
|
||||
:on-change-text #(do
|
||||
(dispatch [:set-in [:accounts/login :password] %])
|
||||
(dispatch [:set-in [:accounts/login :error] ""]))
|
||||
:on-submit-editing #(login-account password-text-input address password)
|
||||
:auto-focus true
|
||||
(re-frame/dispatch [:set-in [:accounts/login :password] %])
|
||||
(re-frame/dispatch [:set-in [:accounts/login :error] ""]))
|
||||
:secure-text-entry true
|
||||
:error (when (pos? (count error)) (i18n/label (error-key error)))}]]
|
||||
(let [enabled? (pos? (count password))]
|
||||
[react/view {:margin-top 16}
|
||||
[react/touchable-highlight (if enabled? {:on-press #(login-account password-text-input address password)})
|
||||
[react/view st/sign-in-button
|
||||
[react/text {:style (if enabled? st/sign-it-text st/sign-it-disabled-text)} (i18n/label :t/sign-in)]]]])]
|
||||
:error (when (pos? (count error)) (i18n/label (error-key error)))}]]]]
|
||||
[react/view styles/processing-view
|
||||
(when processing
|
||||
[react/view st/processing-view
|
||||
[components/activity-indicator {:animating true}]])]))
|
||||
[components/activity-indicator {:animating true}])
|
||||
(when processing
|
||||
[react/text {:style styles/sign-you-in}
|
||||
(i18n/label :t/sign-you-in)])]
|
||||
(when-not processing
|
||||
[react/view {:style styles/bottom-button-container}
|
||||
(when-not can-navigate-back?
|
||||
[components.common/bottom-button
|
||||
{:label (i18n/label :t/other-accounts)
|
||||
:on-press #(re-frame/dispatch [:navigate-to-clean :accounts])}])
|
||||
[react/view {:style {:flex 1}}]
|
||||
[components.common/bottom-button
|
||||
{:forward? true
|
||||
:label (i18n/label :t/sign-in)
|
||||
:disabled? (not (spec/valid? ::db/password password))
|
||||
:on-press #(login-account @password-text-input address password)}]])]))
|
|
@ -1,10 +1,4 @@
|
|||
(ns status-im.ui.screens.accounts.recover.db
|
||||
(:require [cljs.spec.alpha :as spec]
|
||||
[status-im.constants :as const]
|
||||
status-im.utils.db))
|
||||
|
||||
(defn valid-length? [password]
|
||||
(>= (count password) const/min-password-length))
|
||||
(:require [cljs.spec.alpha :as spec]))
|
||||
|
||||
(spec/def ::passphrase :global/not-empty-string)
|
||||
(spec/def ::password (spec/and :global/not-empty-string valid-length?))
|
||||
|
|
|
@ -1,55 +1,52 @@
|
|||
(ns status-im.ui.screens.accounts.recover.events
|
||||
(:require
|
||||
status-im.ui.screens.accounts.recover.navigation
|
||||
|
||||
[re-frame.core :refer [reg-fx inject-cofx dispatch]]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.native-module.core :as status]
|
||||
[status-im.ui.screens.accounts.events :as accounts-events]
|
||||
[status-im.utils.types :refer [json->clj]]
|
||||
[status-im.utils.identicon :refer [identicon]]
|
||||
[taoensso.timbre :as log]
|
||||
[clojure.string :as str]
|
||||
[status-im.utils.handlers :refer [register-handler-fx]]
|
||||
[status-im.utils.gfycat.core :refer [generate-gfy]]
|
||||
[status-im.utils.types :as types]
|
||||
[status-im.utils.identicon :as identicon]
|
||||
[clojure.string :as string]
|
||||
[status-im.utils.handlers :as handlers]
|
||||
[status-im.utils.gfycat.core :as gfycat]
|
||||
[status-im.utils.signing-phrase.core :as signing-phrase]
|
||||
[status-im.utils.hex :as utils.hex]))
|
||||
|
||||
;;;; FX
|
||||
|
||||
(reg-fx
|
||||
(re-frame/reg-fx
|
||||
::recover-account-fx
|
||||
(fn [[passphrase password]]
|
||||
(status/recover-account
|
||||
(str/trim passphrase)
|
||||
(string/trim passphrase)
|
||||
password
|
||||
#(dispatch [:account-recovered %]))))
|
||||
#(re-frame/dispatch [:account-recovered % password]))))
|
||||
|
||||
;;;; Handlers
|
||||
|
||||
(register-handler-fx
|
||||
(handlers/register-handler-fx
|
||||
:account-recovered
|
||||
[(inject-cofx :get-new-keypair!)]
|
||||
(fn [{:keys [db keypair]} [_ result]]
|
||||
(let [data (json->clj result)
|
||||
[(re-frame/inject-cofx :get-new-keypair!)]
|
||||
(fn [{:keys [db keypair]} [_ result password]]
|
||||
(let [data (types/json->clj result)
|
||||
public-key (:pubkey data)
|
||||
address (-> data :address utils.hex/normalize-hex)
|
||||
phrase (signing-phrase/generate)
|
||||
{:keys [public private]} keypair
|
||||
account {:public-key public-key
|
||||
:address address
|
||||
:name (generate-gfy public-key)
|
||||
:photo-path (identicon public-key)
|
||||
:name (gfycat/generate-gfy public-key)
|
||||
:photo-path (identicon/identicon public-key)
|
||||
:updates-public-key public
|
||||
:updates-private-key private
|
||||
:signed-up? true
|
||||
:signing-phrase phrase}]
|
||||
(log/debug "account-recovered")
|
||||
(when-not (str/blank? public-key)
|
||||
(when-not (string/blank? public-key)
|
||||
(-> db
|
||||
(accounts-events/add-account account)
|
||||
(assoc :dispatch [:navigate-to-clean :accounts]))))))
|
||||
(assoc :dispatch [:login-account address password]))))))
|
||||
|
||||
(register-handler-fx
|
||||
(handlers/register-handler-fx
|
||||
:recover-account
|
||||
(fn [_ [_ passphrase password]]
|
||||
{::recover-account-fx [passphrase password]}))
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
(ns status-im.ui.screens.accounts.recover.styles
|
||||
(:require [status-im.ui.components.styles :as common]
|
||||
[status-im.utils.platform :refer [ios?]]))
|
||||
(:require [status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def screen-container
|
||||
{:flex 1
|
||||
:background-color common/color-white})
|
||||
:background-color colors/white})
|
||||
|
||||
(def passphrase-input-max-height
|
||||
(if ios? 78 72))
|
||||
(def bottom-button-container
|
||||
{:flex-direction :row
|
||||
:margin-horizontal 12
|
||||
:margin-vertical 15})
|
||||
|
|
|
@ -1,63 +1,59 @@
|
|||
(ns status-im.ui.screens.accounts.recover.views
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [re-frame.core :refer [dispatch]]
|
||||
[status-im.ui.components.text-input-with-label.view :refer [text-input-with-label]]
|
||||
[status-im.ui.components.react :refer [view
|
||||
text
|
||||
image
|
||||
keyboard-avoiding-view
|
||||
touchable-highlight]]
|
||||
[status-im.ui.components.sticky-button :refer [sticky-button]]
|
||||
[status-im.ui.components.status-bar.view :refer [status-bar]]
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.ui.components.text-input.view :as text-input]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.components.toolbar.actions :as act]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.accounts.recover.styles :as st]
|
||||
[status-im.ui.screens.accounts.recover.db :as v]
|
||||
[status-im.ui.screens.accounts.recover.styles :as styles]
|
||||
[status-im.ui.screens.accounts.recover.db :as recover.db]
|
||||
[status-im.ui.screens.accounts.db :as db]
|
||||
[cljs.spec.alpha :as spec]
|
||||
[clojure.string :as str]))
|
||||
[status-im.ui.components.common.common :as components.common]))
|
||||
|
||||
(defview passphrase-input [passphrase]
|
||||
(letsubs [error [:get-in [:accounts/recover :passphrase-error]]]
|
||||
[view {:margin-top 10}
|
||||
[text-input-with-label {:label (i18n/label :t/passphrase)
|
||||
:description (i18n/label :t/twelve-words-in-correct-order)
|
||||
[text-input/text-input-with-label
|
||||
{:style {:flex 1}
|
||||
:height 92
|
||||
:label (i18n/label :t/passphrase)
|
||||
:placeholder (i18n/label :t/enter-12-words)
|
||||
:multiline true
|
||||
:auto-expanding true
|
||||
:max-height st/passphrase-input-max-height
|
||||
:default-value passphrase
|
||||
:auto-capitalize :none
|
||||
:on-change-text #(dispatch [:set-in [:accounts/recover :passphrase] %])
|
||||
:error error}]]))
|
||||
:on-change-text #(re-frame/dispatch [:set-in [:accounts/recover :passphrase] %])
|
||||
:error error}]))
|
||||
|
||||
(defview password-input [password]
|
||||
(letsubs [error [:get-in [:accounts/recover :password-error]]]
|
||||
[view {:margin-top 10}
|
||||
[text-input-with-label {:label (i18n/label :t/password)
|
||||
[react/view {:margin-top 10}
|
||||
[text-input/text-input-with-label
|
||||
{:label (i18n/label :t/password)
|
||||
:placeholder (i18n/label :t/enter-password)
|
||||
:default-value password
|
||||
:auto-capitalize :none
|
||||
:on-change-text #(dispatch [:set-in [:accounts/recover :password] %])
|
||||
:auto-focus false
|
||||
:on-change-text #(re-frame/dispatch [:set-in [:accounts/recover :password] %])
|
||||
:secure-text-entry true
|
||||
:error error}]]))
|
||||
|
||||
(defview recover [& [modal?]]
|
||||
(defview recover []
|
||||
(letsubs [{:keys [passphrase password]} [:get :accounts/recover]]
|
||||
(let [valid-form? (and
|
||||
(spec/valid? ::v/passphrase passphrase)
|
||||
(spec/valid? ::v/password password))]
|
||||
[keyboard-avoiding-view {:style st/screen-container}
|
||||
[status-bar]
|
||||
[toolbar/toolbar {:modal? modal?} toolbar/default-nav-back
|
||||
[toolbar/content-title (i18n/label :t/recover-access)]]
|
||||
(spec/valid? ::recover.db/passphrase passphrase)
|
||||
(spec/valid? ::db/password password))]
|
||||
[react/keyboard-avoiding-view {:style styles/screen-container}
|
||||
[status-bar/status-bar]
|
||||
[toolbar/toolbar nil toolbar/default-nav-back
|
||||
[toolbar/content-title (i18n/label :t/sign-in-to-another)]]
|
||||
[components.common/separator]
|
||||
[react/view {:margin 16}
|
||||
[passphrase-input (or passphrase "")]
|
||||
[password-input (or password "")]
|
||||
[view {:flex 1}]
|
||||
(when valid-form?
|
||||
[sticky-button
|
||||
(i18n/label :t/recover-access)
|
||||
#(do
|
||||
(when modal? (dispatch [:navigate-back]))
|
||||
(dispatch [:recover-account passphrase password]))])])))
|
||||
|
||||
(defview recover-modal []
|
||||
[recover true])
|
||||
[password-input (or password "")]]
|
||||
[react/view {:flex 1}]
|
||||
[react/view {:style styles/bottom-button-container}
|
||||
[react/view {:style {:flex 1}}]
|
||||
[components.common/bottom-button
|
||||
{:forward? true
|
||||
:label (i18n/label :t/sign-in)
|
||||
:disabled? (not valid-form?)
|
||||
:on-press #(re-frame/dispatch [:recover-account passphrase password])}]]])))
|
|
@ -1,10 +1,16 @@
|
|||
(ns status-im.ui.screens.accounts.styles
|
||||
(:require-macros [status-im.utils.styles :refer [defnstyle defstyle]])
|
||||
(:require [status-im.ui.components.styles :as common]))
|
||||
(:require [status-im.ui.components.styles :as common]
|
||||
[status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def accounts-view
|
||||
{:flex 1
|
||||
:background-color colors/white})
|
||||
|
||||
(def accounts-container
|
||||
{:flex 1
|
||||
:background-color common/color-blue2})
|
||||
:padding-horizontal 16
|
||||
:background-color colors/gray-lighter})
|
||||
|
||||
(def bottom-actions-container
|
||||
{:margin-bottom 16})
|
||||
|
@ -14,54 +20,40 @@
|
|||
:width 40
|
||||
:border-radius 20})
|
||||
|
||||
(defstyle account-title-conatiner
|
||||
{:justify-content :center
|
||||
:align-items :center
|
||||
:ios {:height 56}
|
||||
:android {:height 55}})
|
||||
|
||||
(defstyle account-title-text
|
||||
{:color :white
|
||||
{:color :black
|
||||
:font-size 17
|
||||
:ios {:letter-spacing -0.2}})
|
||||
|
||||
(defstyle accounts-list-container
|
||||
{:flex 1
|
||||
:margin-horizontal 16
|
||||
:ios {:margin-top 10
|
||||
:margin-bottom 10}
|
||||
:android {:margin-top 16
|
||||
:margin-bottom 16}})
|
||||
|
||||
(def accounts-action-button
|
||||
{:label-style {:color :white}
|
||||
:cyrcle-color "#ffffff33"})
|
||||
|
||||
(def accounts-separator
|
||||
{:background-color "#7482eb"
|
||||
:opacity 1
|
||||
:margin-left 72})
|
||||
|
||||
(def accounts-separator-wrapper
|
||||
{:background-color common/color-blue2})
|
||||
:margin-top 16
|
||||
:margin-bottom 16})
|
||||
|
||||
(defstyle account-view
|
||||
{:background-color :white
|
||||
:justify-content :center
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:padding-horizontal 16
|
||||
:height 64
|
||||
:border-radius 8})
|
||||
|
||||
(def account-badge
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:padding-horizontal 16})
|
||||
|
||||
(def account-badge-text-view
|
||||
{:margin-left 16
|
||||
:margin-right 21
|
||||
:flex-shrink 1})
|
||||
|
||||
(defstyle account-badge-text
|
||||
{:ios {:font-size 17
|
||||
:letter-spacing -0.2}
|
||||
:android {:font-size 16
|
||||
:color common/color-black}})
|
||||
(def account-badge-text
|
||||
{:font-size 17
|
||||
:letter-spacing -0.2
|
||||
:color common/color-black})
|
||||
|
||||
(def account-badge-pub-key-text
|
||||
{:font-size 14
|
||||
:letter-spacing -0.2
|
||||
:color colors/gray
|
||||
:margin-top 4})
|
||||
|
||||
(def bottom-button-container
|
||||
{:margin-top 14
|
||||
:margin-bottom 6})
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
(ns status-im.ui.screens.accounts.subs
|
||||
(:require [re-frame.core :refer [reg-sub subscribe]]))
|
||||
(:require [re-frame.core :refer [reg-sub subscribe]]
|
||||
[clojure.string :as string]
|
||||
[status-im.ui.screens.accounts.db :as db]
|
||||
[cljs.spec.alpha :as spec]))
|
||||
|
||||
(reg-sub :get-current-public-key
|
||||
(fn [db]
|
||||
|
@ -18,3 +21,11 @@
|
|||
:<- [:get-accounts]
|
||||
(fn [[account-id accounts]]
|
||||
(some-> accounts (get account-id))))
|
||||
|
||||
(reg-sub
|
||||
:get-account-creation-next-enabled?
|
||||
(fn [{:accounts/keys [create]}]
|
||||
(let [{:keys [step password password-confirm name]} create]
|
||||
(or (and password (= :enter-password step) (spec/valid? ::db/password password))
|
||||
(and password-confirm (= :confirm-password step) (spec/valid? ::db/password password-confirm))
|
||||
(and name (= :enter-name step) (not (string/blank? name)))))))
|
|
@ -1,56 +1,48 @@
|
|||
(ns status-im.ui.screens.accounts.views
|
||||
(:require-macros [status-im.utils.views :refer [defview]])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ui.screens.accounts.styles :as styles]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]
|
||||
[status-im.ui.components.toolbar.actions :as act]
|
||||
[status-im.ui.components.common.common :as common]
|
||||
[status-im.ui.components.action-button.action-button :refer [action-button]]
|
||||
[status-im.constants :refer [console-chat-id]]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.i18n :as i18n]))
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]))
|
||||
|
||||
|
||||
(defn account-badge [address photo-path name]
|
||||
[react/view styles/account-badge
|
||||
(defn account-view [{:keys [address photo-path name public-key]}]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:open-login address photo-path name])}
|
||||
[react/view styles/account-view
|
||||
[react/image {:source {:uri (if (string/blank? photo-path) :avatar photo-path)}
|
||||
:style styles/photo-image}]
|
||||
[react/view styles/account-badge-text-view
|
||||
[react/text {:style styles/account-badge-text
|
||||
:numberOfLines 1}
|
||||
(or name address)]]])
|
||||
|
||||
(defn account-view [{:keys [address photo-path name] :as account}]
|
||||
[react/view
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:open-login address photo-path name])}
|
||||
[react/view styles/account-view
|
||||
[account-badge address photo-path name]]]])
|
||||
name]
|
||||
[react/text {:style styles/account-badge-pub-key-text
|
||||
:ellipsize-mode :middle
|
||||
:numberOfLines 1}
|
||||
public-key]]
|
||||
[react/view {:flex 1}]
|
||||
[icons/icon :icons/forward {:color (colors/alpha colors/gray-icon 0.4)}]]])
|
||||
|
||||
(defview accounts []
|
||||
[accounts [:get-accounts]]
|
||||
(letsubs [accounts [:get-accounts]]
|
||||
[react/view styles/accounts-view
|
||||
[status-bar/status-bar]
|
||||
[toolbar/toolbar nil nil
|
||||
[toolbar/content-title (i18n/label :t/sign-in-to-status)]]
|
||||
[react/view styles/accounts-container
|
||||
[status-bar/status-bar {:type :transparent}]
|
||||
[react/view styles/account-title-conatiner
|
||||
[react/text {:style styles/account-title-text
|
||||
:font :toolbar-title}
|
||||
(i18n/label :t/sign-in-to-status)]]
|
||||
[react/view styles/accounts-list-container
|
||||
[list/flat-list {:data (vals accounts)
|
||||
:render-fn (fn [account] [account-view account])
|
||||
:separator [react/view {:height 10}]}]]
|
||||
[react/view styles/bottom-actions-container
|
||||
[action-button (merge
|
||||
{:label (i18n/label :t/create-new-account)
|
||||
:icon :icons/add
|
||||
:icon-opts {:color :white}
|
||||
:on-press #(re-frame/dispatch [:create-new-account-handler])}
|
||||
styles/accounts-action-button)]
|
||||
[common/separator styles/accounts-separator styles/accounts-separator-wrapper]
|
||||
[action-button (merge
|
||||
{:label (i18n/label :t/recover-access)
|
||||
:icon :icons/dots-horizontal
|
||||
:icon-opts {:color :white}
|
||||
:on-press #(re-frame/dispatch [:navigate-to :recover])}
|
||||
styles/accounts-action-button)]]])
|
||||
:separator [react/view {:height 12}]}]]
|
||||
[react/view
|
||||
[components.common/button {:on-press #(re-frame/dispatch [:navigate-to :create-account])
|
||||
:label (i18n/label :t/create-new-account)}]
|
||||
[react/view styles/bottom-button-container
|
||||
[components.common/button {:on-press #(re-frame/dispatch [:navigate-to :recover])
|
||||
:label (i18n/label :t/add-existing-account)
|
||||
:background? false}]]]]]))
|
|
@ -43,10 +43,8 @@
|
|||
:on-press #()}]])
|
||||
|
||||
(defview add-new []
|
||||
(letsubs [contacts [:all-added-group-contacts]
|
||||
params [:get :contacts/click-params]]
|
||||
[react/view {:flex 1}
|
||||
[react/view {:flex 1 :background-color :white}
|
||||
[status-bar/status-bar]
|
||||
[toolbar.view/simple-toolbar (i18n/label :t/new)]
|
||||
[components/separator]
|
||||
[options-list]]))
|
||||
[options-list]])
|
|
@ -15,10 +15,8 @@
|
|||
:initialize-browsers
|
||||
[(re-frame/inject-cofx :all-stored-browsers)]
|
||||
(fn [{:keys [db all-stored-browsers]} _]
|
||||
(let [{:accounts/keys [account-creation?]} db]
|
||||
(when-not account-creation?
|
||||
(let [browsers (into {} (map #(vector (:browser-id %) %) all-stored-browsers))]
|
||||
{:db (assoc db :browser/browsers browsers)})))))
|
||||
{:db (assoc db :browser/browsers browsers)})))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:save-browser
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
:group/contact-groups {}
|
||||
:group/selected-contacts #{}
|
||||
:chats {}
|
||||
:current-chat-id constants/console-chat-id
|
||||
:current-chat-id nil
|
||||
:selected-participants #{}
|
||||
:discoveries {}
|
||||
:discover-search-tags #{}
|
||||
|
@ -139,8 +139,7 @@
|
|||
:group/selected-contacts
|
||||
:group/groups-order
|
||||
:accounts/accounts
|
||||
:accounts/account-creation?
|
||||
:accounts/creating-account?
|
||||
:accounts/create
|
||||
:accounts/current-account-id
|
||||
:accounts/recover
|
||||
:accounts/login
|
||||
|
|
|
@ -57,8 +57,7 @@
|
|||
(repeat (- columns extras) {:name ""})))))
|
||||
|
||||
(defview main []
|
||||
(letsubs [all-dapps [:discover/all-dapps]
|
||||
tabs-hidden? [:tabs-hidden?]]
|
||||
(letsubs [all-dapps [:discover/all-dapps]]
|
||||
(let [columns 3]
|
||||
(when (seq all-dapps)
|
||||
[react/view styles/all-dapps-container
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
(defview discover-all-recent []
|
||||
(letsubs [discoveries [:discover/recent-discoveries]
|
||||
tabs-hidden? [:tabs-hidden?]
|
||||
current-account [:get-current-account]
|
||||
contacts [:get-contacts]]
|
||||
[react/view styles/all-recent-container
|
||||
|
@ -16,7 +15,7 @@
|
|||
toolbar/default-nav-back
|
||||
[toolbar/content-title (i18n/label :t/recent)]]
|
||||
(when (seq discoveries)
|
||||
[react/scroll-view (styles/list-container tabs-hidden?)
|
||||
[react/scroll-view (styles/list-container false)
|
||||
[react/view styles/status-list-outer
|
||||
[react/view styles/status-list-inner
|
||||
(let [discoveries (map-indexed vector discoveries)]
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
status-im.ui.screens.wallet.choose-recipient.events
|
||||
status-im.ui.screens.browser.events
|
||||
status-im.ui.screens.offline-messaging-settings.events
|
||||
status-im.ui.screens.usage-data.events
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.native-module.core :as status]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.permissions :as permissions]
|
||||
[status-im.constants :refer [console-chat-id]]
|
||||
[status-im.data-store.core :as data-store]
|
||||
|
@ -159,13 +159,14 @@
|
|||
(re-frame/reg-fx
|
||||
:initialize-geth-fx
|
||||
(fn [config]
|
||||
;;TODO get rid of this, because we don't need this anymore
|
||||
(status/should-move-to-internal-storage?
|
||||
(fn [should-move?]
|
||||
(if should-move?
|
||||
(re-frame/dispatch [:request-permissions
|
||||
[:read-external-storage]
|
||||
#(move-to-internal-storage config)
|
||||
#(re-frame/dispatch [:move-to-internal-failure-message])])
|
||||
#()])
|
||||
(status/start-node config))))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
|
@ -225,7 +226,7 @@
|
|||
{::testfairy-alert nil
|
||||
:dispatch-n [[:initialize-db]
|
||||
[:load-accounts]
|
||||
[:check-console-chat]
|
||||
[:initialize-views]
|
||||
[:listen-to-network-status]
|
||||
[:initialize-crypt]
|
||||
[:initialize-geth]]}))
|
||||
|
@ -234,7 +235,6 @@
|
|||
:initialize-db
|
||||
(fn [{{:keys [status-module-initialized? status-node-started?
|
||||
network-status network]
|
||||
:networks/keys [networks]
|
||||
:or {network (get app-db :network)}} :db} _]
|
||||
{::init-store nil
|
||||
:db (assoc app-db
|
||||
|
@ -247,8 +247,8 @@
|
|||
|
||||
(handlers/register-handler-db
|
||||
:initialize-account-db
|
||||
(fn [{:keys [accounts/accounts contacts/contacts networks/networks
|
||||
network network-status view-id navigation-stack chats
|
||||
(fn [{:keys [accounts/accounts accounts/create contacts/contacts networks/networks
|
||||
network network-status view-id navigation-stack
|
||||
access-scope->commands-responses
|
||||
status-module-initialized? status-node-started?
|
||||
inbox/wnode]
|
||||
|
@ -268,7 +268,7 @@
|
|||
:status-module-initialized? (or platform/ios? js/goog.DEBUG status-module-initialized?)
|
||||
:status-node-started? status-node-started?
|
||||
:accounts/accounts accounts
|
||||
:accounts/creating-account? false
|
||||
:accounts/create create
|
||||
:networks/networks networks
|
||||
:network-status network-status
|
||||
:network network
|
||||
|
@ -291,24 +291,24 @@
|
|||
[:send-account-update-if-needed]
|
||||
[:update-wallet]
|
||||
[:update-transactions]
|
||||
[:get-fcm-token]]
|
||||
[:get-fcm-token]
|
||||
[:update-sign-in-time]]
|
||||
(seq events-after)
|
||||
(into events-after))}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:check-console-chat
|
||||
(fn [{{:accounts/keys [accounts] :as db} :db} [_ open-console?]]
|
||||
(let [view (if (empty? accounts)
|
||||
:chat
|
||||
:accounts)]
|
||||
(merge
|
||||
{:db (assoc db
|
||||
:view-id view
|
||||
:navigation-stack (list view))}
|
||||
(when (or (empty? accounts) open-console?)
|
||||
{:dispatch-n (concat [[:init-console-chat]]
|
||||
(when open-console?
|
||||
[[:navigate-to-chat console-chat-id]]))})))))
|
||||
:initialize-views
|
||||
(fn [{{:accounts/keys [accounts] :as db} :db}]
|
||||
{:db (if (empty? accounts)
|
||||
(assoc db :view-id :intro :navigation-stack (list :intro))
|
||||
(let [{:keys [address photo-path name]} (first (sort-by :last-sign-in > (vals accounts)))]
|
||||
(-> db
|
||||
(assoc :view-id :login
|
||||
:navigation-stack (list :login))
|
||||
(update :accounts/login assoc
|
||||
:address address
|
||||
:photo-path photo-path
|
||||
:name name))))}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:initialize-crypt
|
||||
|
|
|
@ -155,3 +155,51 @@
|
|||
:width 14
|
||||
:height 9
|
||||
:tint-color :white})
|
||||
|
||||
(def no-chats
|
||||
{:flex 1
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:margin-horizontal 34})
|
||||
|
||||
(def no-chats-text
|
||||
{:font-size 14
|
||||
:line-height 21
|
||||
:letter-spacing -0.2
|
||||
:text-align :center
|
||||
:color colors/gray})
|
||||
|
||||
(def welcome-view
|
||||
{:flex 1
|
||||
:padding-horizontal 30})
|
||||
|
||||
(def welcome-image-container
|
||||
{:flex 1
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(def welcome-image
|
||||
{:width 320
|
||||
:height 278})
|
||||
|
||||
(def welcome-text
|
||||
{:line-height 28
|
||||
:font-size 22
|
||||
:font-weight :bold
|
||||
:letter-spacing -0.3
|
||||
:text-align :center
|
||||
:color colors/black})
|
||||
|
||||
(def welcome-text-description
|
||||
{:line-height 21
|
||||
:margin-top 8
|
||||
:margin-bottom 32
|
||||
:font-size 14
|
||||
:letter-spacing -0.2
|
||||
:text-align :center
|
||||
:color colors/gray})
|
||||
|
||||
(def toolbar-logo
|
||||
{:size 42
|
||||
:icon-size 17
|
||||
:shadow? false})
|
|
@ -1,9 +1,7 @@
|
|||
(ns status-im.ui.screens.home.views
|
||||
(:require-macros [status-im.utils.views :as views])
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.native-action-button :refer [native-action-button]]
|
||||
|
@ -12,12 +10,16 @@
|
|||
[status-im.ui.components.sync-state.offline :refer [offline-view]]
|
||||
[status-im.ui.screens.home.views.inner-item :as inner-item]
|
||||
[status-im.ui.screens.home.styles :as styles]
|
||||
[status-im.utils.platform :as platform]))
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.i18n :as i18n]))
|
||||
|
||||
(defn- toolbar []
|
||||
[toolbar/toolbar {:title-centered? true}
|
||||
nil
|
||||
[toolbar/content-title (i18n/label :t/status)]
|
||||
(defn- toolbar [show-welcome?]
|
||||
[toolbar/toolbar nil nil
|
||||
(when-not show-welcome?
|
||||
[toolbar/content-wrapper
|
||||
[components.common/logo styles/toolbar-logo]])
|
||||
[toolbar/actions
|
||||
(when platform/ios?
|
||||
[(toolbar.actions/add #(re-frame/dispatch [:navigate-to :new]))])]])
|
||||
|
@ -38,13 +40,37 @@
|
|||
[react/view
|
||||
[inner-item/home-list-browser-item-inner-view home-item]]]))
|
||||
|
||||
;;do not remove view-id and will-update or will-unmount handlers, this is how it works
|
||||
(views/defview welcome [view-id]
|
||||
(views/letsubs [handler #(re-frame/dispatch [:set-in [:accounts/create :show-welcome?] false])]
|
||||
{:component-will-update handler
|
||||
:component-will-unmount handler}
|
||||
[react/view {:style styles/welcome-view}
|
||||
[react/view {:style styles/welcome-image-container}
|
||||
[react/image {:source (:welcome-image resources/ui)
|
||||
:style styles/welcome-image}]]
|
||||
[react/text {:style styles/welcome-text}
|
||||
(i18n/label :t/welcome-to-status)]
|
||||
[react/view
|
||||
[react/text {:style styles/welcome-text-description}
|
||||
(i18n/label :t/welcome-to-status-description)]]]))
|
||||
|
||||
(views/defview home []
|
||||
(views/letsubs [home-items [:home-items]]
|
||||
(views/letsubs [home-items [:home-items]
|
||||
show-welcome? [:get-in [:accounts/create :show-welcome?]]
|
||||
view-id [:get :view-id]]
|
||||
[react/view styles/container
|
||||
[toolbar]
|
||||
[toolbar show-welcome?]
|
||||
(cond show-welcome?
|
||||
[welcome view-id]
|
||||
(empty? home-items)
|
||||
[react/view styles/no-chats
|
||||
[react/text {:style styles/no-chats-text}
|
||||
(i18n/label :t/no-recent-chats)]]
|
||||
:else
|
||||
[list/flat-list {:data home-items
|
||||
:render-fn (fn [[home-item-id :as home-item]]
|
||||
^{:key home-item-id} [home-list-item home-item])}]
|
||||
^{:key home-item-id} [home-list-item home-item])}])
|
||||
(when platform/android?
|
||||
[home-action-button])
|
||||
[offline-view]]))
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
(ns status-im.ui.screens.intro.styles
|
||||
(:require-macros [status-im.utils.styles :refer [defnstyle defstyle]])
|
||||
(:require [status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def intro-view
|
||||
{:flex 1
|
||||
:padding-horizontal 30
|
||||
:background-color colors/white})
|
||||
|
||||
(def intro-logo-container
|
||||
{:flex 1
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(def intro-logo
|
||||
{:size 111
|
||||
:icon-size 46})
|
||||
|
||||
(defstyle intro-text
|
||||
{:text-align :center
|
||||
:color colors/black
|
||||
:ios {:line-height 28
|
||||
:font-size 22
|
||||
:font-weight :bold
|
||||
:letter-spacing -0.3}
|
||||
:android {:font-size 24
|
||||
:line-height 30}})
|
||||
|
||||
(def intro-text-description
|
||||
{:line-height 21
|
||||
:margin-top 8
|
||||
:margin-bottom 16
|
||||
:font-size 14
|
||||
:letter-spacing -0.2
|
||||
:text-align :center
|
||||
:color colors/gray})
|
||||
|
||||
(def buttons-container
|
||||
{:align-items :center})
|
||||
|
||||
(def bottom-button-container
|
||||
{:margin-bottom 6
|
||||
:margin-top 38})
|
|
@ -0,0 +1,27 @@
|
|||
(ns status-im.ui.screens.intro.views
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.screens.intro.styles :as styles]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]))
|
||||
|
||||
(defview intro []
|
||||
[react/view {:style styles/intro-view}
|
||||
[status-bar/status-bar {:flat? true}]
|
||||
[react/view {:style styles/intro-logo-container}
|
||||
[components.common/logo styles/intro-logo]]
|
||||
[react/text {:style styles/intro-text}
|
||||
(i18n/label :t/intro-text)]
|
||||
[react/view
|
||||
[react/text {:style styles/intro-text-description}
|
||||
(i18n/label :t/intro-text-description)]]
|
||||
[react/view styles/buttons-container
|
||||
[components.common/button {:style {:flex-direction :row}
|
||||
:on-press #(re-frame/dispatch [:navigate-to :create-account])
|
||||
:label (i18n/label :t/create-account)}]
|
||||
[react/view styles/bottom-button-container
|
||||
[components.common/button {:on-press #(re-frame/dispatch [:navigate-to :recover])
|
||||
:label (i18n/label :t/already-have-account)
|
||||
:background? false}]]]])
|
|
@ -21,9 +21,6 @@
|
|||
(update :navigation-stack replace-top-element view-id)
|
||||
(assoc :view-id view-id)))
|
||||
|
||||
(defn- can-navigate-back? [db]
|
||||
(not (get db :accounts/creating-account?)))
|
||||
|
||||
;; public fns
|
||||
|
||||
(defn navigate-to-clean [db view-id]
|
||||
|
@ -89,15 +86,13 @@
|
|||
(>= 1 (count navigation-stack)) db
|
||||
|
||||
:else
|
||||
(if (can-navigate-back? db)
|
||||
(let [[previous-view-id :as navigation-stack'] (pop navigation-stack)
|
||||
first-in-stack (first navigation-stack)]
|
||||
(if (= view-id first-in-stack)
|
||||
(-> db
|
||||
(assoc :view-id previous-view-id)
|
||||
(assoc :navigation-stack navigation-stack'))
|
||||
(assoc db :view-id first-in-stack)))
|
||||
db))))
|
||||
(assoc db :view-id first-in-stack))))))
|
||||
|
||||
(register-handler-db
|
||||
:navigate-to-clean
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
[re-frame.core :refer [dispatch]]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.components.text-input-with-label.view :refer [text-input-with-label]]
|
||||
[status-im.ui.components.text-input.view :as text-input]
|
||||
[status-im.ui.screens.network-settings.views :as network-settings]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.sticky-button :as sticky-button]
|
||||
|
@ -18,7 +18,7 @@
|
|||
(i18n/label :t/add-network)]
|
||||
[network-settings/network-badge]
|
||||
[react/view {:margin-top 8}
|
||||
[text-input-with-label {:label (i18n/label :t/rpc-url)}]]
|
||||
[text-input/text-input-with-label {:label (i18n/label :t/rpc-url)}]]
|
||||
[react/view {:flex 1}]
|
||||
(when (not (str/blank? rpc-url))
|
||||
[sticky-button/sticky-button (i18n/label :t/add-network) #()])]))
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
:padding-top 24})
|
||||
|
||||
(def action
|
||||
{:background-color colors/blue-transparent
|
||||
{:background-color (colors/alpha colors/blue 0.1)
|
||||
:border-radius 50})
|
||||
|
||||
(def action-label
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
:align-items :center
|
||||
:height 42
|
||||
:border-radius components.styles/border-radius
|
||||
:background-color colors/blue-transparent})
|
||||
:background-color (colors/alpha colors/blue 0.1)})
|
||||
|
||||
(def share-contact-code-text-container
|
||||
{:padding-left 16
|
||||
|
|
|
@ -31,13 +31,6 @@
|
|||
(fn [current-account]
|
||||
(:signed-up? current-account)))
|
||||
|
||||
(reg-sub :tabs-hidden?
|
||||
:<- [:get-in [:chat-list-ui-props :edit?]]
|
||||
:<- [:get-in [:contacts/ui-props :edit?]]
|
||||
:<- [:get :view-id]
|
||||
(fn [[chats-edit-mode? contacts-edit-mode? view-id]]
|
||||
(and (= view-id :contact-list) contacts-edit-mode?)))
|
||||
|
||||
(reg-sub :network
|
||||
(fn [db]
|
||||
(:network db)))
|
||||
|
@ -54,3 +47,7 @@
|
|||
(reg-sub :get-screen-params
|
||||
(fn [db [_ view-id]]
|
||||
(get-in db [:navigation/screen-params (or view-id (:view-id db))])))
|
||||
|
||||
(reg-sub :can-navigate-back?
|
||||
(fn [db]
|
||||
(> (count (:navigation-stack db)) 1)))
|
|
@ -0,0 +1,10 @@
|
|||
(ns status-im.ui.screens.usage-data.events
|
||||
(:require [status-im.utils.handlers :as handlers]
|
||||
[status-im.ui.screens.accounts.events :as accounts]))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:help-improve-handler
|
||||
(fn [{db :db} [_ yes?]]
|
||||
(merge (when yes?
|
||||
(accounts/account-update {:db db} {:sharing-usage-data? true}))
|
||||
{:dispatch [:navigate-to-clean :home]})))
|
|
@ -0,0 +1,48 @@
|
|||
(ns status-im.ui.screens.usage-data.styles
|
||||
(:require-macros [status-im.utils.styles :refer [defnstyle defstyle]])
|
||||
(:require [status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def usage-data-view
|
||||
{:flex 1
|
||||
:padding-horizontal 30
|
||||
:background-color colors/white})
|
||||
|
||||
(def logo-container
|
||||
{:flex 1
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(def logo
|
||||
{:size 82
|
||||
:icon-size 34})
|
||||
|
||||
(def usage-data-image
|
||||
{:width 138
|
||||
:height 208
|
||||
:margin-top 10})
|
||||
|
||||
(defstyle help-improve-text
|
||||
{:text-align :center
|
||||
:color colors/black
|
||||
:ios {:line-height 28
|
||||
:font-size 22
|
||||
:font-weight :bold
|
||||
:letter-spacing -0.3}
|
||||
:android {:font-size 24
|
||||
:line-height 30}})
|
||||
|
||||
(def help-improve-text-description
|
||||
{:line-height 21
|
||||
:margin-top 8
|
||||
:margin-bottom 16
|
||||
:font-size 14
|
||||
:letter-spacing -0.2
|
||||
:text-align :center
|
||||
:color colors/gray})
|
||||
|
||||
(def buttons-container
|
||||
{:align-items :center})
|
||||
|
||||
(def bottom-button-container
|
||||
{:margin-bottom 6
|
||||
:margin-top 38})
|
|
@ -0,0 +1,30 @@
|
|||
(ns status-im.ui.screens.usage-data.views
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.screens.usage-data.styles :as styles]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]))
|
||||
|
||||
(defview usage-data []
|
||||
[react/view {:style styles/usage-data-view}
|
||||
[status-bar/status-bar {:flat? true}]
|
||||
[react/view {:style styles/logo-container}
|
||||
[components.common/logo styles/logo]
|
||||
[react/image {:source (:analytics-image resources/ui)
|
||||
:style styles/usage-data-image}]]
|
||||
[react/text {:style styles/help-improve-text}
|
||||
(i18n/label :t/help-improve)]
|
||||
[react/view
|
||||
[react/text {:style styles/help-improve-text-description}
|
||||
(i18n/label :t/help-improve-description)]]
|
||||
[react/view styles/buttons-container
|
||||
[components.common/button {:style {:flex-direction :row}
|
||||
:on-press #(re-frame/dispatch [:help-improve-handler true])
|
||||
:label (i18n/label :t/share-usage-data)}]
|
||||
[react/view styles/bottom-button-container
|
||||
[components.common/button {:on-press #(re-frame/dispatch [:help-improve-handler false])
|
||||
:label (i18n/label :t/dont-want-to-share)
|
||||
:background? false}]]]])
|
|
@ -7,7 +7,7 @@
|
|||
[status-im.ui.screens.main-tabs.views :refer [main-tabs]]
|
||||
|
||||
[status-im.ui.screens.accounts.login.views :refer [login]]
|
||||
[status-im.ui.screens.accounts.recover.views :refer [recover recover-modal]]
|
||||
[status-im.ui.screens.accounts.recover.views :refer [recover]]
|
||||
[status-im.ui.screens.accounts.views :refer [accounts]]
|
||||
|
||||
[status-im.chat.screen :refer [chat]]
|
||||
|
@ -38,7 +38,6 @@
|
|||
[status-im.ui.screens.wallet.transactions.views :as wallet-transactions]
|
||||
[status-im.ui.screens.wallet.send.transaction-sent.views :refer [transaction-sent transaction-sent-modal]]
|
||||
[status-im.ui.screens.wallet.components.views :refer [contact-code recent-recipients recipient-qr-code]]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]
|
||||
[status-im.ui.screens.discover.search-results.views :as discover-search]
|
||||
[status-im.ui.screens.discover.recent-statuses.views :as discover-recent]
|
||||
[status-im.ui.screens.discover.all-dapps.views :as discover-all-dapps]
|
||||
|
@ -51,15 +50,11 @@
|
|||
[status-im.ui.screens.network-settings.parse-json.views :refer [paste-json-text]]
|
||||
[status-im.ui.screens.browser.views :refer [browser]]
|
||||
[status-im.ui.screens.add-new.open-dapp.views :refer [open-dapp dapp-description]]
|
||||
[status-im.ui.screens.intro.views :refer [intro]]
|
||||
[status-im.ui.screens.accounts.create.views :refer [create-account]]
|
||||
[status-im.ui.screens.usage-data.views :refer [usage-data]]
|
||||
[status-im.utils.config :as config]))
|
||||
|
||||
(defn validate-current-view
|
||||
[current-view signed-up?]
|
||||
(if (or (contains? #{:login :chat :recover :accounts} current-view)
|
||||
signed-up?)
|
||||
current-view
|
||||
:chat))
|
||||
|
||||
;;; defines hierarchy of views, when parent screen is opened children screens
|
||||
;;; are pre-rendered, currently it is:
|
||||
;;;
|
||||
|
@ -129,8 +124,10 @@
|
|||
modal-view [:get :modal]]
|
||||
{:component-will-update (fn [] (react/dismiss-keyboard!))}
|
||||
(when view-id
|
||||
(let [current-view (validate-current-view view-id signed-up?)]
|
||||
(let [component (case current-view
|
||||
(let [component (case view-id
|
||||
:intro intro
|
||||
:create-account create-account
|
||||
:usage-data usage-data
|
||||
(:home :wallet :my-profile) main-tabs
|
||||
:browser browser
|
||||
:open-dapp open-dapp
|
||||
|
@ -173,8 +170,8 @@
|
|||
:recipient-qr-code recipient-qr-code
|
||||
:contact-code contact-code
|
||||
:profile-qr-viewer profile.user/qr-viewer
|
||||
(throw (str "Unknown view: " current-view)))
|
||||
main-screen-view (create-main-screen-view current-view)]
|
||||
[react/view [react/text (str "Unknown view: " view-id)]])
|
||||
main-screen-view (create-main-screen-view view-id)]
|
||||
[main-screen-view common-styles/flex
|
||||
(if (and config/compile-views-enabled?
|
||||
signed-up?
|
||||
|
@ -182,7 +179,7 @@
|
|||
:choose-recipient :wallet-transaction-sent :transactions-history
|
||||
:unsigned-transactions :wallet-request-transaction :edit-my-profile
|
||||
:profile-photo-capture :wallet-request-assets}
|
||||
current-view))
|
||||
view-id))
|
||||
[root-view]
|
||||
[component])
|
||||
(when modal-view
|
||||
|
@ -192,13 +189,12 @@
|
|||
:on-request-close #(dispatch [:navigate-back])}
|
||||
(let [component (case modal-view
|
||||
:qr-scanner qr-scanner
|
||||
:recover-modal recover-modal
|
||||
:contact-list-modal contact-list-modal
|
||||
:wallet-transactions-filter wallet-transactions/filter-history
|
||||
:wallet-settings-assets wallet-settings/manage-assets
|
||||
:wallet-send-transaction-modal send-transaction-modal
|
||||
:wallet-transaction-sent-modal transaction-sent-modal
|
||||
:wallet-transaction-fee wallet.send/transaction-fee
|
||||
(throw (str "Unknown modal view: " modal-view)))]
|
||||
[react/view [react/text (str "Unknown modal view: " modal-view)]])]
|
||||
[react/main-screen-modal-view modal-view
|
||||
[component]])]])])))))
|
||||
[component]])]])]))))
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
(ns status-im.ui.screens.wallet.components.animations
|
||||
(:require [status-im.ui.components.animation :as animation]))
|
||||
|
||||
(defn animate-tooltip [bottom-value opacity-value]
|
||||
(fn []
|
||||
(animation/start
|
||||
(animation/parallel
|
||||
[(animation/timing opacity-value {:toValue 1
|
||||
:duration 500})
|
||||
(animation/timing bottom-value {:toValue -40
|
||||
:easing (.bezier (animation/easing) 0.685, 0.000, 0.025, 1.185)
|
||||
:duration 500})]))))
|
|
@ -184,31 +184,4 @@
|
|||
:font-size 15
|
||||
:letter-spacing -0.2})
|
||||
|
||||
(def tooltip-container
|
||||
{:position :absolute
|
||||
:align-items :center
|
||||
:left 0
|
||||
:right 0
|
||||
:top 0})
|
||||
|
||||
(defn tooltip-animated [bottom-value opacity-value]
|
||||
{:position :absolute
|
||||
:align-items :center
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom bottom-value
|
||||
:opacity opacity-value})
|
||||
|
||||
(def tooltip-text-container
|
||||
{:padding-horizontal 16
|
||||
:padding-vertical 9
|
||||
:background-color :white
|
||||
:border-radius 8})
|
||||
|
||||
(def tooltip-text
|
||||
{:color styles/color-red-2
|
||||
:font-size 15})
|
||||
|
||||
(def tooltip-triangle
|
||||
{:width 16
|
||||
:height 8})
|
||||
|
|
|
@ -4,18 +4,15 @@
|
|||
[reagent.core :as reagent]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.animation :as animation]
|
||||
[status-im.ui.components.bottom-buttons.view :as bottom-buttons]
|
||||
[status-im.ui.components.button.view :as button]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.list.styles :as list.styles]
|
||||
[status-im.ui.components.list-selection :as list-selection]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.styles :as components.styles]
|
||||
[status-im.ui.screens.wallet.components :as components]
|
||||
[status-im.ui.screens.wallet.components.animations :as animations]
|
||||
[status-im.ui.screens.wallet.components.styles :as styles]
|
||||
[status-im.ui.screens.wallet.choose-recipient.views :as choose-recipient]
|
||||
[status-im.ui.screens.wallet.views :as wallet]
|
||||
|
@ -23,17 +20,8 @@
|
|||
[status-im.ui.screens.wallet.utils :as wallet.utils]
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
[status-im.utils.ethereum.tokens :as tokens]
|
||||
[status-im.utils.platform :as platform]))
|
||||
|
||||
(views/defview tooltip [label]
|
||||
(views/letsubs [bottom-value (animation/create-value -30)
|
||||
opacity-value (animation/create-value 0)]
|
||||
{:component-did-mount (animations/animate-tooltip bottom-value opacity-value)}
|
||||
[react/view styles/tooltip-container
|
||||
[react/animated-view {:style (styles/tooltip-animated bottom-value opacity-value)}
|
||||
[react/view styles/tooltip-text-container
|
||||
[react/text {:style styles/tooltip-text} label]]
|
||||
[vector-icons/icon :icons/tooltip-triangle {:color :white :style styles/tooltip-triangle}]]]))
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.ui.components.tooltip.views :as tooltip]))
|
||||
|
||||
(defn view-asset [symbol]
|
||||
[react/view
|
||||
|
@ -198,7 +186,7 @@
|
|||
(i18n/label :t/amount)
|
||||
[amount-input m]]
|
||||
(when error
|
||||
[tooltip error])])
|
||||
[tooltip/tooltip error])])
|
||||
|
||||
(defn separator []
|
||||
[react/view styles/separator])
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
[status-im.ui.components.styles :as components.styles]
|
||||
[status-im.ui.components.toolbar.actions :as act]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.components.tooltip.views :as tooltip]
|
||||
[status-im.ui.screens.wallet.components.styles :as wallet.components.styles]
|
||||
[status-im.ui.screens.wallet.components.views :as components]
|
||||
[status-im.ui.screens.wallet.components :as wallet.components]
|
||||
|
@ -51,7 +52,7 @@
|
|||
:on-change-text #(re-frame/dispatch [:wallet.send/set-password %])
|
||||
:style styles/password}]]]
|
||||
(when wrong-password?
|
||||
[components/tooltip (i18n/label :t/wrong-password)])]))
|
||||
[tooltip/tooltip (i18n/label :t/wrong-password)])]))
|
||||
|
||||
;; "Cancel" and "Sign Transaction >" buttons, signing with password
|
||||
(defview signing-buttons [cancel-handler sign-handler in-progress?]
|
||||
|
|
|
@ -216,4 +216,7 @@
|
|||
|
||||
(def filter-container
|
||||
{:flex 1})
|
||||
;:background-color colors/white})
|
||||
|
||||
(def transacions-view
|
||||
{:flex 1
|
||||
:background-color :white})
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
(every? :checked? (:tokens filter-data))))
|
||||
|
||||
(defn- toolbar-view [current-tab filter-data]
|
||||
[toolbar/toolbar {:flat? true}
|
||||
[toolbar/toolbar nil
|
||||
toolbar/default-nav-back
|
||||
[toolbar/content-title (i18n/label :t/transactions)]
|
||||
(case current-tab
|
||||
|
@ -187,7 +187,7 @@
|
|||
(defview transactions []
|
||||
(letsubs [current-tab [:get :view-id]
|
||||
filter-data [:wallet.transactions/filters]]
|
||||
[react/view {:style components.styles/flex}
|
||||
[react/view styles/transacions-view
|
||||
[status-bar/status-bar]
|
||||
[toolbar-view current-tab filter-data]
|
||||
[tabs current-tab]
|
||||
|
|
Loading…
Reference in New Issue