[MVP TTT] Contract support for settings

- settings are stored in a manifest that is pointed at by the contract
- during login the contract is checked to fetch the settings

Signed-off-by: yenda <eric@status.im>
This commit is contained in:
Vitaliy Vlasov 2019-02-22 14:26:40 +02:00 committed by yenda
parent 1dc59cb770
commit 1ca9294af7
No known key found for this signature in database
GPG Key ID: 0095623C0069DCE6
21 changed files with 766 additions and 302 deletions

View File

@ -1,27 +1,27 @@
(ns status-im.accounts.login.core
(:require [re-frame.core :as re-frame]
[status-im.accounts.db :as accounts.db]
[status-im.chaos-mode.core :as chaos-mode]
[status-im.data-store.core :as data-store]
[status-im.fleet.core :as fleet]
[status-im.i18n :as i18n]
[status-im.models.transactions :as transactions]
[status-im.models.wallet :as models.wallet]
[status-im.native-module.core :as status]
[status-im.node.core :as node]
[status-im.protocol.core :as protocol]
[status-im.tribute-to-talk.core :as tribute-to-talk]
[status-im.ui.screens.mobile-network-settings.events :as mobile-network]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.config :as config]
[status-im.fleet.core :as fleet]
[status-im.utils.fx :as fx]
[status-im.react-native.js-dependencies :as rn-dependencies]
[status-im.utils.keychain.core :as keychain]
[status-im.utils.types :as types]
[taoensso.timbre :as log]
[status-im.utils.universal-links.core :as universal-links]
[status-im.utils.security :as security]
[status-im.utils.platform :as platform]
[status-im.protocol.core :as protocol]
[status-im.models.wallet :as models.wallet]
[status-im.utils.handlers :as handlers]
[status-im.models.transactions :as transactions]
[status-im.i18n :as i18n]
[status-im.node.core :as node]
[status-im.ui.screens.mobile-network-settings.events :as mobile-network]
[status-im.chaos-mode.core :as chaos-mode]))
[status-im.utils.keychain.core :as keychain]
[status-im.utils.platform :as platform]
[status-im.utils.security :as security]
[status-im.utils.types :as types]
[status-im.utils.universal-links.core :as universal-links]
[taoensso.timbre :as log]))
(def rpc-endpoint "https://goerli.infura.io/v3/f315575765b14720b32382a61a89341a")
(def contract-address "0xfbf4c8e2B41fAfF8c616a0E49Fb4365a5355Ffaf")
@ -144,6 +144,7 @@
(fn [_]
(when save-password?
{:keychain/save-user-password [address password]}))
(tribute-to-talk/init)
(mobile-network/on-network-status-change)
(protocol/initialize-protocol)
(universal-links/process-stored-event)

View File

@ -8,15 +8,17 @@
[status-im.accounts.update.core :as accounts.update]
[status-im.bootnodes.core :as bootnodes]
[status-im.browser.core :as browser]
[status-im.node.core :as node]
[status-im.browser.permissions :as browser.permissions]
[status-im.chat.commands.core :as commands]
[status-im.chat.commands.input :as commands.input]
[status-im.chat.db :as chat.db]
[status-im.chat.models :as chat]
[status-im.chat.models.input :as chat.input]
[status-im.chat.models.loading :as chat.loading]
[status-im.chat.models.message :as chat.message]
[status-im.contact.core :as contact]
[status-im.contact-code.core :as contact-code]
[status-im.contact-recovery.core :as contact-recovery]
[status-im.contact.core :as contact]
[status-im.extensions.core :as extensions]
[status-im.extensions.registry :as extensions.registry]
[status-im.fleet.core :as fleet]
@ -24,38 +26,36 @@
[status-im.hardwallet.core :as hardwallet]
[status-im.i18n :as i18n]
[status-im.init.core :as init]
[status-im.utils.logging.core :as logging]
[status-im.log-level.core :as log-level]
[status-im.mailserver.core :as mailserver]
[status-im.network.core :as network]
[status-im.node.core :as node]
[status-im.notifications.core :as notifications]
[status-im.pairing.core :as pairing]
[status-im.contact-code.core :as contact-code]
[status-im.privacy-policy.core :as privacy-policy]
[status-im.protocol.core :as protocol]
[status-im.qr-scanner.core :as qr-scanner]
[status-im.search.core :as search]
[status-im.signals.core :as signals]
[status-im.transport.message.core :as transport.message]
[status-im.transport.core :as transport]
[status-im.ui.screens.currency-settings.models :as currency-settings.models]
[status-im.tribute-to-talk.core :as tribute-to-talk]
[status-im.node.core :as node]
[status-im.web3.core :as web3]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.fx :as fx]
[status-im.utils.handlers :as handlers]
[status-im.utils.utils :as utils]
[taoensso.timbre :as log]
[status-im.chat.commands.core :as commands]
[status-im.chat.models.loading :as chat-loading]
[status-im.node.core :as node]
[status-im.stickers.core :as stickers]
[status-im.utils.config :as config]
[status-im.transport.core :as transport]
[status-im.transport.message.core :as transport.message]
[status-im.tribute-to-talk.core :as tribute-to-talk]
[status-im.ui.components.bottom-sheet.core :as bottom-sheet]
[status-im.ui.components.react :as react]
[status-im.ui.screens.add-new.new-chat.db :as new-chat.db]
[status-im.ui.screens.currency-settings.models
:as
currency-settings.models]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.build :as build]
[status-im.chat.db :as chat.db]))
[status-im.utils.config :as config]
[status-im.utils.fx :as fx]
[status-im.utils.handlers :as handlers]
[status-im.utils.logging.core :as logging]
[status-im.utils.utils :as utils]
[status-im.web3.core :as web3]
[taoensso.timbre :as log]))
;; init module
@ -108,7 +108,7 @@
(log/debug "PERF" :init-rest-of-chats (.now js/Date))
(fx/merge cofx
{:db (assoc db :chats/loading? false)}
(chat-loading/initialize-chats {:from 10}))))
(chat.loading/initialize-chats {:from 10}))))
(defn account-change-success
[{:keys [db] :as cofx} [_ address nodes]]
@ -122,7 +122,7 @@
(node/initialize (get-in db [:accounts/login :address])))
(init/initialize-account address)
(mailserver/initialize-ranges)
(chat-loading/initialize-chats {:to 10}))))
(chat.loading/initialize-chats {:to 10}))))
(handlers/register-handler-fx
:init.callback/account-change-success
@ -1656,6 +1656,11 @@
(fn [cofx [_ chat-id envelope-hash]]
(transport.message/set-contact-message-envelope-hash cofx chat-id envelope-hash)))
(handlers/register-handler-fx
:transport.callback/node-info-fetched
(fn [cofx [_ node-info]]
(transport/set-node-info cofx node-info)))
;; contact module
(handlers/register-handler-fx
@ -1686,13 +1691,24 @@
(handlers/register-handler-fx
:contact/qr-code-scanned
[(re-frame/inject-cofx :random-id-generator)]
(fn [cofx [_ _ contact-identity]]
(contact/handle-qr-code cofx contact-identity)))
(fn [{:keys [db] :as cofx} [_ _ contact-identity]]
(let [current-account (:account/account db)
fx {:db (assoc db :contacts/new-identity contact-identity)}
validation-result (new-chat.db/validate-pub-key db contact-identity)]
(if (some? validation-result)
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
:content validation-result
:on-dismiss #(re-frame/dispatch [:navigate-to-clean :home])}}
(fx/merge cofx
fx
(if config/partitioned-topic-enabled?
(contact/add-contacts-filter contact-identity :open-chat)
(chat/start-chat contact-identity {:navigation-reset? true})))))))
(handlers/register-handler-fx
:contact/filters-added
(fn [cofx [_ contact-identity]]
(contact/open-chat cofx contact-identity)))
(chat/start-chat cofx contact-identity {:navigation-reset? true})))
(handlers/register-handler-fx
:contact.ui/start-group-chat-pressed
@ -1703,13 +1719,13 @@
:contact.ui/send-message-pressed
[(re-frame/inject-cofx :random-id-generator)]
(fn [cofx [_ {:keys [public-key]}]]
(contact/open-chat cofx public-key)))
(chat/start-chat cofx public-key {:navigation-reset? true})))
(handlers/register-handler-fx
:contact.ui/contact-code-submitted
[(re-frame/inject-cofx :random-id-generator)]
(fn [cofx _]
(contact/add-new-identity-to-contacts cofx)))
(fn [{{:contacts/keys [new-identity]} :db :as cofx} _]
(chat/start-chat cofx new-identity {:navigation-reset? true})))
;; search module
@ -1858,11 +1874,6 @@
(fn [cofx _]
(stickers/pending-timeout cofx)))
(handlers/register-handler-fx
:transport.callback/node-info-fetched
(fn [cofx [_ node-info]]
(transport/set-node-info cofx node-info)))
;; Tribute to Talk
(handlers/register-handler-fx
:tribute-to-talk.ui/menu-item-pressed
@ -1904,6 +1915,59 @@
(fn [cofx _]
(tribute-to-talk/remove cofx)))
(handlers/register-handler-fx
:tribute-to-talk.callback/check-manifest-success
(fn [cofx [_ identity contenthash]]
(tribute-to-talk/fetch-manifest cofx identity contenthash)))
(handlers/register-handler-fx
:tribute-to-talk.callback/no-manifest-found
(fn [cofx [_ identity]]
(tribute-to-talk/update-settings cofx nil)))
(handlers/register-handler-fx
:tribute-to-talk.callback/fetch-manifest-success
(fn [cofx [_ identity {:keys [tribute-to-talk]}]]
(tribute-to-talk/update-settings cofx tribute-to-talk)))
(handlers/register-handler-fx
:tribute-to-talk.callback/fetch-manifest-failure
(fn [cofx [_ identity contenthash]]
(tribute-to-talk/fetch-manifest cofx identity contenthash)))
(handlers/register-handler-fx
:tribute-to-talk.ui/check-manifest
(fn [{:keys [db] :as cofx} [_ identity]]
(tribute-to-talk/check-manifest cofx identity)))
(handlers/register-handler-fx
:tribute-to-talk.callback/manifest-uploaded
(fn [cofx [_ hash]]
(tribute-to-talk/set-manifest-signing-flow cofx hash)))
(handlers/register-handler-fx
:tribute-to-talk.callback/manifest-upload-failed
(fn [cofx [_ error]]
(tribute-to-talk/on-manifest-upload-failed cofx error)))
(handlers/register-handler-fx
:tribute-to-talk.callback/set-manifest-transaction-completed
(fn [cofx [_ id transaction-hash method]]
(tribute-to-talk/on-set-manifest-transaction-completed cofx
transaction-hash)))
(handlers/register-handler-fx
:tribute-to-talk.callback/set-manifest-transaction-failed
(fn [cofx [_ error]]
(tribute-to-talk/on-set-manifest-transaction-failed cofx
error)))
(handlers/register-handler-fx
:tribute-to-talk/check-set-manifest-transaction-timeout
(fn [cofx _]
(tribute-to-talk/check-set-manifest-transaction cofx)))
;; bottom-sheet events
(handlers/register-handler-fx
:bottom-sheet/show-sheet
(fn [cofx [_ view]]

View File

@ -14,9 +14,9 @@
:success-event-creator
(fn [{:keys [status body]}]
(if (= 200 status)
(on-success {:value body})
(on-success body)
(when on-failure
(on-failure {:value status}))))}
(on-failure status))))}
on-failure
(assoc :failure-event-creator on-failure))})
@ -40,8 +40,8 @@
:success-event-creator
(fn [{:keys [status body]}]
(if (= 200 status)
(on-success {:value (parse-ipfs-add-response body)})
(on-success (parse-ipfs-add-response body))
(when on-failure
(on-failure {:value status}))))}
(on-failure status))))}
on-failure
(assoc :failure-event-creator on-failure))}))

View File

@ -1,35 +1,77 @@
(ns status-im.tribute-to-talk.core
(:refer-clojure :exclude [remove])
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.accounts.update.core :as accounts.update]
[status-im.contact.db :as contact.db]
[status-im.ipfs.core :as ipfs]
[status-im.tribute-to-talk.db :as tribute-to-talk.db]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.fx :as fx]))
[status-im.utils.contenthash :as contenthash]
[status-im.utils.ethereum.contracts :as contracts]
[status-im.utils.ethereum.core :as ethereum]
[status-im.utils.fx :as fx]
[taoensso.timbre :as log]))
(fx/defn update-settings
[{:keys [db] :as cofx} {:keys [snt-amount message update] :as new-settings}]
(let [account-settings (get-in db [:account/account :settings])
chain-keyword (-> (get-in db [:account/account :networks (:network db)])
ethereum/network->chain-keyword)
tribute-to-talk-settings (cond-> (merge (tribute-to-talk.db/get-settings db)
new-settings)
new-settings
(assoc :seen? true)
(not new-settings)
(dissoc :snt-amount :manifest)
(and (contains? new-settings :update)
(nil? update))
(dissoc :update))]
(accounts.update/update-settings
cofx
(-> account-settings
(assoc-in [:tribute-to-talk chain-keyword]
tribute-to-talk-settings))
{})))
(fx/defn mark-ttt-as-seen
[{:keys [db] :as cofx}]
(let [settings (get-in db [:account/account :settings])
{:keys [seen?]} (:tribute-to-talk settings)]
(when-not seen?
(fx/merge cofx
{:db (assoc db :tribute-to-talk/seen? true)}
(accounts.update/update-settings
(assoc-in settings [:tribute-to-talk :seen?] true) {})))))
(when-not (:seen (tribute-to-talk.db/get-settings db))
(update-settings cofx {:seen? true})))
(fx/defn open-settings
[{:keys [db] :as cofx}]
(let [snt-amount (get-in db [:account/account :settings :tribute-to-talk :snt-amount])]
(let [settings (tribute-to-talk.db/get-settings db)
updated-settings (:update settings)]
(fx/merge cofx
mark-ttt-as-seen
(navigation/navigate-to-cofx :tribute-to-talk
(if snt-amount
{:step :edit
:editing? true}
{:step :intro})))))
(navigation/navigate-to-cofx
:tribute-to-talk
(cond
updated-settings
(merge {:step :finish}
updated-settings
(when updated-settings
{:state :pending}))
(:snt-amount settings)
(merge {:step :edit
:editing? true}
(update settings :snt-amount tribute-to-talk.db/from-wei))
:else
{:step :intro})))))
(fx/defn set-step
[{:keys [db]} step]
{:db (assoc-in db [:navigation/screen-params :tribute-to-talk :step] step)})
(fx/defn set-step-finish
[{:keys [db] :as cofx}]
(fx/merge cofx
{:db (assoc-in db [:navigation/screen-params :tribute-to-talk :state] :signing)}
(set-step :finish)))
(fx/defn open-learn-more
[cofx]
(set-step cofx :learn-more))
@ -53,6 +95,24 @@
:finish
(set-step cofx :personalized-message))))
(fx/defn upload-manifest
[cofx]
(let [{:keys [message snt-amount]}
(get-in cofx [:db :navigation/screen-params :tribute-to-talk])
manifest {:tribute-to-talk
{:message message
:snt-amount (tribute-to-talk.db/to-wei snt-amount)}}]
(ipfs/add cofx
{:value (js/JSON.stringify
(clj->js manifest))
:on-success
(fn [response]
[:tribute-to-talk.callback/manifest-uploaded
(:hash response)])
:on-failure
(fn [error]
[:tribute-to-talk.callback/manifest-upload-failed error])})))
(fx/defn step-forward
[cofx]
(let [{:keys [step editing?]}
@ -65,14 +125,9 @@
(set-step cofx :personalized-message)
:personalized-message
(let [account-settings (get-in cofx [:db :account/account :settings])]
(fx/merge cofx
(set-step (if editing?
:edit
:finish))
(accounts.update/update-settings
account-settings
{})))
(fx/merge cofx
(set-step-finish)
(upload-manifest))
:finish
(navigation/navigate-back cofx))))
@ -81,7 +136,7 @@
[snt-amount numpad-symbol]
;; TODO: Put some logic in place so that incorrect numbers can not
;; be entered
(let [snt-amount (or snt-amount "0")]
(let [snt-amount (or (str snt-amount) "0")]
(if (= numpad-symbol :remove)
(let [len (count snt-amount)
s (subs snt-amount 0 (dec len))]
@ -105,25 +160,140 @@
(fx/defn update-snt-amount
[{:keys [db]} numpad-symbol]
{:db (update-in db [:account/account :settings :tribute-to-talk :snt-amount]
{:db (update-in db
[:navigation/screen-params :tribute-to-talk :snt-amount]
#(get-new-snt-amount % numpad-symbol))})
(fx/defn update-message
[{:keys [db]} message]
{:db (assoc-in db [:account/account :settings :tribute-to-talk :message]
{:db (assoc-in db
[:navigation/screen-params :tribute-to-talk :message]
message)})
(fx/defn start-editing
[{:keys [db]}]
{:db (assoc-in db [:navigation/screen-params :tribute-to-talk]
{:step :set-snt-amount
:editing? true})})
{:db (assoc-in db
[:navigation/screen-params :tribute-to-talk :step]
:set-snt-amount)})
(fx/defn fetch-manifest
[{:keys [db] :as cofx} identity contenthash]
(contenthash/cat cofx
{:contenthash contenthash
:on-failure
(fn [error]
(re-frame/dispatch
(if (= 503 error)
[:tribute-to-talk.callback/fetch-manifest-failure
identity contenthash]
[:tribute-to-talk.callback/no-manifest-found identity])))
:on-success
(fn [manifest-json]
(let [manifest (js->clj (js/JSON.parse manifest-json)
:keywordize-keys true)]
(re-frame/dispatch
[:tribute-to-talk.callback/fetch-manifest-success
identity manifest])))}))
(fx/defn check-manifest
[{:keys [db] :as cofx} identity]
(or (contracts/call cofx
{:contract :status/tribute-to-talk
:method :get-manifest
:params [(contact.db/public-key->address identity)]
:return-params ["bytes"]
:callback
#(re-frame/dispatch
(if-let [contenthash (first %)]
[:tribute-to-talk.callback/check-manifest-success
identity
contenthash]
[:tribute-to-talk.callback/no-manifest-found identity]))})
;; `contracts/call` returns nil if there is no contract for the current network
;; update settings if checking own manifest or do nothing otherwise
(when-let [me? (= identity
(get-in cofx [:db :account/account :public-key]))]
(update-settings cofx nil))))
(fx/defn check-own-manifest
[cofx]
(check-manifest cofx (get-in cofx [:db :account/account :public-key])))
(fx/defn set-manifest-signing-flow
[{:keys [db] :as cofx} hash]
(let [contenthash (when hash
(contenthash/encode {:hash hash
:namespace :ipfs}))]
(or (contracts/call cofx
{:contract :status/tribute-to-talk
:method :set-manifest
:params [contenthash]
:on-result [:tribute-to-talk.callback/set-manifest-transaction-completed]
:on-error [:tribute-to-talk.callback/set-manifest-transaction-failed]})
{:db (assoc-in db [:navigation/screen-params :tribute-to-talk :state] :transaction-failed)})))
(defn remove
[{:keys [db] :as cofx}]
(let [account-settings (get-in db [:account/account :settings])]
(fx/merge cofx
{:db (assoc-in db [:navigation/screen-params :tribute-to-talk]
{:step :finish
:state :disabled})}
(set-manifest-signing-flow nil)))
(fx/defn check-set-manifest-transaction
[{:keys [db] :as cofx}]
(let [transaction (get-in (tribute-to-talk.db/get-settings db) [:update :transaction])]
(when transaction
(let [confirmed? (pos? (js/parseInt
(get-in cofx [:db :wallet :transactions
transaction :confirmations]
0)))
;;TODO support failed transactions
failed? false]
(cond
failed?
(fx/merge cofx
{:db (assoc-in db [:navigation/screen-params :tribute-to-talk :state] :transaction-failed)}
(update-settings {:update nil}))
confirmed?
(fx/merge cofx
{:db (assoc-in db [:navigation/screen-params :tribute-to-talk :state] :completed)}
check-own-manifest
(update-settings {:update nil}))
(not confirmed?)
{:dispatch-later [{:ms 10000
:dispatch [:tribute-to-talk/check-set-manifest-transaction-timeout]}]})))))
(fx/defn on-set-manifest-transaction-completed
[{:keys [db] :as cofx} transaction-hash]
(let [{:keys [snt-amount message]} (get-in db [:navigation/screen-params
:tribute-to-talk])]
(fx/merge cofx
{:db (assoc-in db [:navigation/screen-params :tribute-to-talk]
{:step :finish})}
(accounts.update/update-settings
(assoc account-settings :tribute-to-talk {:seen? true}) {}))))
{:db (assoc-in db [:navigation/screen-params :tribute-to-talk :state] :pending)}
(navigation/navigate-to-clean :wallet-transaction-sent-modal {})
(update-settings {:update {:transaction transaction-hash
:snt-amount snt-amount
:message message}})
check-set-manifest-transaction)))
(fx/defn on-set-manifest-transaction-failed
[{:keys [db] :as cofx} error]
(log/error :set-manifest-transaction-failed error)
{:db (assoc-in db
[:navigation/screen-params :tribute-to-talk :state]
:transaction-failed)})
(fx/defn on-manifest-upload-failed
[{:keys [db] :as cofx} error]
(log/error :upload-manifest-failed error)
{:db (assoc-in db
[:navigation/screen-params :tribute-to-talk :state]
:transaction-failed)})
(fx/defn init
[cofx]
(fx/merge cofx
check-own-manifest
check-set-manifest-transaction))

View File

@ -0,0 +1,25 @@
(ns status-im.tribute-to-talk.db
(:require [status-im.js-dependencies :as dependencies]
[status-im.utils.ethereum.core :as ethereum]))
(def utils dependencies/web3-utils)
(defn to-wei
[s]
(when s
(.toWei utils s)))
(defn from-wei
[s]
(when s
(.fromWei utils s)))
(defn get-settings
[db]
(let [chain-keyword (-> (get-in db [:account/account :networks (:network db)])
ethereum/network->chain-keyword)]
(get-in db [:account/account :settings :tribute-to-talk chain-keyword])))
(defn enabled?
[db]
(:snt-amount (get-settings db)))

View File

@ -1,12 +1,13 @@
(ns status-im.tribute-to-talk.subs
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.tribute-to-talk.db :as tribute-to-talk]
[status-im.utils.money :as money]))
(re-frame/reg-sub
:tribute-to-talk/settings
(fn [db]
(get-in db [:account/account :settings :tribute-to-talk])))
(tribute-to-talk/get-settings db)))
(re-frame/reg-sub
:tribute-to-talk/screen-params
@ -19,22 +20,35 @@
:<- [:tribute-to-talk/screen-params]
:<- [:prices]
:<- [:wallet/currency]
(fn [[{:keys [snt-amount message]}
{:keys [step editing?] :or {step :intro}}
prices currency]]
(fn [[{:keys [seen? snt-amount message update]}
{:keys [step editing? state error]
:or {step :intro}
screen-snt-amount :snt-amount
screen-message :message} prices currency]]
(let [fiat-value (if snt-amount
(money/fiat-amount-value snt-amount
:SNT
(-> currency :code keyword)
prices)
"0")
disabled? (and (= step :set-snt-amount)
(or (string/blank? snt-amount)
(= "0" snt-amount)
(string/ends-with? snt-amount ".")))]
{:snt-amount snt-amount
:disabled? disabled?
:message message
:step step
:editing? editing?
:fiat-value (str "~" fiat-value " " (:code currency))})))
(money/fiat-amount-value
snt-amount
:SNT
(-> currency :code keyword)
prices)
"0")]
(cond-> {:seen? seen?
:snt-amount (tribute-to-talk/from-wei snt-amount)
:message message
:disabled? (nil? snt-amount)
:error error
:step step
:state (or state (if snt-amount :completed :disabled))
:editing? editing?
:fiat-value (str "~" fiat-value " " (:code currency))}
(= step :set-snt-amount)
(assoc :snt-amount (str screen-snt-amount)
:disable-button?
(boolean (and (= step :set-snt-amount)
(or (string/blank? screen-snt-amount)
(#{"0" "0.0" "0.00"} screen-snt-amount)
(string/ends-with? screen-snt-amount ".")))))
(= step :personalized-message)
(assoc :message screen-message)))))

View File

@ -1,15 +1,15 @@
(ns status-im.ui.components.contact.contact
(:require-macros [status-im.utils.views :as views])
(:require [status-im.i18n :as i18n]
[status-im.utils.platform :as platform]
[status-im.ui.components.react :as react]
[status-im.ui.components.icons.vector-icons :as vector-icons]
(:require [clojure.string :as string]
[status-im.i18n :as i18n]
[status-im.ui.components.chat-icon.screen :as chat-icon]
[status-im.ui.components.contact.styles :as styles]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.list-selection :as list-selection]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.react :as react]
[status-im.utils.gfycat.core :as gfycat]
[clojure.string :as string]))
[status-im.utils.platform :as platform])
(:require-macros [status-im.utils.views :as views]))
(defn desktop-extended-options [options]
[react/view {}

View File

@ -1,8 +1,5 @@
(ns status-im.ui.components.contact.styles
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
(:require [status-im.ui.components.styles :as common]
[status-im.utils.platform]
[status-im.ui.components.colors :as colors]))
(:require [status-im.ui.components.colors :as colors]))
(def contact-container-to-refactor
{:flex-direction :row

View File

@ -18,9 +18,8 @@
[section-list {:sections [{:title \"\" :key :unik :render-fn render :data {:title \"\" :subtitle \"\"}}]}]
"
(:require-macros [status-im.utils.views :as views])
(:require [reagent.core :as reagent]
[clojure.string :as string]
(:require [clojure.string :as string]
[reagent.core :as reagent]
[status-im.i18n :as i18n]
[status-im.ui.components.animation :as animation]
[status-im.ui.components.checkbox.view :as checkbox]
@ -28,8 +27,9 @@
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.list.styles :as styles]
[status-im.ui.components.react :as react]
[status-im.utils.platform :as platform]
[status-im.ui.screens.home.animations.responder :as responder]))
[status-im.ui.screens.home.animations.responder :as responder]
[status-im.utils.platform :as platform])
(:require-macros [status-im.utils.views :as views]))
(def flat-list-class (react/get-class "FlatList"))
(def section-list-class (react/get-class "SectionList"))
@ -68,7 +68,7 @@
(defn item-primary
([s] (item-primary nil s))
([{:keys [style] :as props} s]
[react/text (merge {:style styles/primary-text}
[react/text (merge {:style (merge styles/primary-text style)}
(dissoc props :style))
s]))
@ -80,8 +80,13 @@
s]))
(defn item-secondary
[secondary]
[react/text {:style styles/secondary-text :ellipsize-mode :middle :number-of-lines 1} secondary])
([s] (item-secondary nil s))
([{:keys [style]} s]
[react/text
{:style (merge styles/secondary-text style)
:ellipsize-mode :middle
:number-of-lines 1}
s]))
(defn item-content
[& children]
@ -108,14 +113,14 @@
(defn big-list-item
[{:keys [style text text-color subtext value action-fn active? destructive? hide-chevron?
accessory-value text-color new?
accessory-value text-color new? activity-indicator
accessibility-label icon icon-color image-source icon-content]
:or {icon-color colors/blue
text-color colors/black
value ""
active? true
style {}}}]
{:pre [(or icon image-source)
{:pre [(or icon image-source activity-indicator)
(and action-fn text)
(or (nil? accessibility-label) (keyword? accessibility-label))]}
[react/touchable-highlight
@ -124,11 +129,16 @@
:accessibility-label accessibility-label
:disabled (not active?)}
[react/view (styles/settings-item subtext)
(if icon
(cond
icon
[react/view (styles/settings-item-icon icon-color subtext)
[vector-icons/icon icon {:color icon-color}]]
image-source
[react/image {:source {:uri image-source}
:style styles/big-item-image}])
:style styles/big-item-image}]
activity-indicator
[react/view (styles/settings-item-icon icon-color subtext)
[react/activity-indicator activity-indicator]])
(if subtext
[react/view {:style styles/settings-item-text-container}
[react/view {:style styles/settings-item-main-text-container}
@ -247,8 +257,8 @@
{:sections (clj->js (map wrap-per-section-render-fn sections))
:renderSectionHeader (wrap-render-section-header-fn render-section-header-fn)})])
(defn render-action [{:keys [label accessibility-label icon action disabled?]}
{:keys [action-style action-label-style icon-opts]}]
(defn render-action [{:keys [label subtext accessibility-label icon action disabled?]}
{:keys [action-style action-label-style action-subtext-style icon-opts]}]
[react/touchable-highlight {:on-press action}
[react/view {:accessibility-label accessibility-label}
[item
@ -259,10 +269,21 @@
:icon-opts (merge {:color :white}
icon-opts
(when disabled? {:color colors/gray}))}]
[item-primary-only {:style (merge styles/action-label
action-label-style
(if-not subtext
[item-primary-only {:style (merge styles/action-label
(action-label-style false)
(when disabled? styles/action-label-disabled))}
label]
[item-content
[item-primary {:style (merge styles/action-label
(action-label-style true)
(when disabled? styles/action-label-disabled))}
label]
[item-secondary {:style (merge styles/action-label
action-subtext-style
(when disabled? styles/action-label-disabled))}
label]
subtext]])
item-icon-forward]]])
(defn action-list [actions {:keys [container-style action-separator-style] :as styles}]

View File

@ -1,14 +1,10 @@
(ns status-im.ui.components.qr-code-viewer.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [reagent.core :as reagent]
[re-frame.core :as re-frame]
[status-im.react-native.js-dependencies :as rn-dependencies]
[status-im.ui.components.button.view :as button]
[status-im.ui.components.list-selection :as list-selection]
[status-im.ui.components.qr-code-viewer.styles :as styles]
[status-im.ui.screens.profile.tribute-to-talk.views :as tr-to-talk]
[status-im.ui.components.react :as react]
[status-im.i18n :as i18n]))
[status-im.ui.screens.profile.tribute-to-talk.views :as tr-to-talk])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
(defn qr-code [props]
(reagent/create-element
@ -17,12 +13,12 @@
(defview qr-code-viewer-component [{:keys [style hint-style footer-style footer-button value hint legend]}]
(letsubs [{:keys [width]} [:dimensions/window]
{:keys [snt-amount]} [:tribute-to-talk/settings]]
{:keys [disabled?]} [:tribute-to-talk/ui]]
[react/scroll-view {:content-container-style {:align-items :center
:margin-top 16
:justify-content :center}
:style (merge {:flex 1} style)}
(when snt-amount
(when-not disabled?
[react/view {:style {:margin-horizontal 16}}
[tr-to-talk/enabled-note]])
(when width

View File

@ -50,6 +50,7 @@
:fleet-settings {:type :main}
:log-level-settings {:type :main}
:stickers-pack-modal {:type :main}
:tribute-learn-more {:type :main}
:show-extension-modal {:type :main}
:wallet {:type :wallet-tab}
:wallet-stack {:type :wallet-tab}

View File

@ -31,11 +31,20 @@
{:background-color (colors/alpha colors/blue 0.1)
:border-radius 50})
(def action-label
{:color colors/blue})
(defn action-label [with-subtext?]
(cond-> {:color colors/blue}
with-subtext?
(assoc :font-size 15
:line-height 22
:font-weight "500")))
(def action-subtext
{:line-height 22
:font-size 15
:color colors/gray})
(def action-separator
{:height 1
{:height 0
:background-color colors/gray-light
:margin-left 50})
@ -46,7 +55,7 @@
{:background-color (colors/alpha colors/red 0.1)
:border-radius 50})
(def block-action-label
(defn block-action-label [with-subtext?]
{:color colors/red})
(def block-action-icon-opts

View File

@ -90,6 +90,7 @@
{:container-style styles/action-container
:action-style styles/action
:action-label-style styles/action-label
:action-subtext-style styles/action-subtext
:action-separator-style styles/action-separator
:icon-opts styles/action-icon-opts}]
[react/view {:style {:height 16}}]

View File

@ -224,19 +224,35 @@
{:background-color colors/blue-light
:padding-horizontal 12
:padding-top 8
:width 222
:margin-top 4
:border-radius 8})
(def pay-to-chat-container
{:justify-content :center
{:justify-content :flex-start
:align-items :center
:flex-direction :row
:height 44})
(def pay-to-chat-text
{:typography :main-medium
:color colors/blue})
(defn payment-status-icon [pending?]
{:width 24
:height 24
:border-radius 12
:justify-content :center
:align-items :center
:background-color (if pending?
(colors/alpha colors/black 0.1)
colors/green)})
(def payment-status-text
{:font-size 15
:color colors/gray
:margin-left 6
:line-height 22})
(def edit-container
{:justify-content :space-between
:flex-grow 1})

View File

@ -3,6 +3,7 @@
[re-frame.core :as re-frame]
[status-im.i18n :as i18n]
[status-im.react-native.resources :as resources]
[status-im.tribute-to-talk.core :as tribute-to-talk]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.common.common :as components.common]
[status-im.ui.components.icons.vector-icons :as icons]
@ -19,8 +20,7 @@
(defn steps-numbers [editing?]
{:intro 1
:set-snt-amount (if editing? 1 2)
:personalized-message (if editing? 2 3)
:finish 3})
:personalized-message (if editing? 2 3)})
(def step-forward-label
{:intro :t/get-started
@ -58,10 +58,10 @@
(defn snt-amount-label
[snt-amount fiat-value]
[react/view {:style styles/snt-amount-container}
[react/text {:style styles/snt-amount-label
:number-of-lines 1
:ellipsize-mode :middle}
[react/text {:style styles/snt-amount} (or snt-amount "0")]
[react/nested-text {:style styles/snt-amount-label
:number-of-lines 1
:ellipsize-mode :middle}
[{:style styles/snt-amount} (or snt-amount "0")]
" SNT"]
[snt-asset-value fiat-value]])
@ -112,10 +112,9 @@
[react/scroll-view
{:content-container-style styles/personalized-message-container}
[react/view {:style styles/personalized-message-title}
[react/text {:style {:text-align :center}}
[react/nested-text {:style {:text-align :center}}
(i18n/label :t/personalized-message)
[react/text {:style styles/description-label}
(str " (" (i18n/label :t/optional) ")")]]]
[{:style styles/description-label} (str " (" (i18n/label :t/optional) ")")]]]
[react/text-input
(cond-> {:style (assoc styles/personalized-message-input :height 144
:align-self :stretch)
@ -129,19 +128,46 @@
(i18n/label :t/tribute-to-talk-you-can-leave-a-message)]])
(defn finish
[snt-amount]
[snt-amount state]
[react/view {:style styles/intro-container}
[react/view {:style {:flex 1
:min-height 32}}]
[react/view {:style {:justify-content :center
:align-items :center}}
[react/view {:style (styles/finish-circle (if snt-amount
colors/green-transparent-10
colors/gray-lighter) 80)}
[react/view {:style (styles/finish-circle
(case state
:completed
colors/green-transparent-10
:disabled
colors/gray-lighter
:pending
colors/gray-lighter
:signing
colors/gray-lighter
:transaction-failed
colors/red-transparent-10)
80)}
[react/view {:style styles/finish-circle-with-shadow}
[icons/icon :main-icons/check {:color (if snt-amount
colors/green
colors/gray)}]]]]
(if (#{:signing :pending} state)
[react/activity-indicator {:animating true
:size :large
:color colors/gray}]
[icons/icon (case state
:completed :main-icons/check
:disabled :main-icons/cancel
:transaction-failed :main-icons/warning)
{:width 48 :height 48
:color (case state
:completed
colors/green
:disabled
colors/gray
:pending
colors/gray
:signing
colors/gray
:transaction-failed
colors/red)}])]]]
[react/view {:style {:flex 1
:min-height 32}}]
@ -149,17 +175,35 @@
:align-items :center
:margin-bottom 32}}
[react/text {:style styles/finish-label}
(i18n/label (if snt-amount
(i18n/label (case state
:completed
:t/you-are-all-set
:t/tribute-to-talk-disabled))]
(if snt-amount
[react/text {:style (assoc styles/description-label :margin-top 16)}
:disabled
:t/tribute-to-talk-disabled
:pending
:t/tribute-to-talk-pending
:signing
:t/tribute-to-talk-signing
:transaction-failed
:t/transaction-failed))]
(case state
:completed
[react/nested-text {:style (assoc styles/description-label :margin-top 16)}
(i18n/label :t/tribute-to-talk-finish-desc)
[react/text {:style {:text-align :center}}
snt-amount]
[{:style {:color colors/black
:font-weight "600"}} snt-amount]
" SNT"]
:disabled
[react/text {:style (assoc styles/description-label :margin-top 16)}
(i18n/label :t/tribute-to-talk-disabled-note)])]])
(i18n/label :t/tribute-to-talk-disabled-note)]
:pending
[react/text {:style (assoc styles/description-label :margin-top 16)}
(i18n/label :t/tribute-to-talk-pending-note)]
:signing
nil
:transaction-failed
[react/text {:style (assoc styles/description-label :margin-top 16)}
(i18n/label :t/tribute-to-talk-transaction-failed-note)])]])
(defn enabled-note
[]
@ -185,10 +229,10 @@
[react/view {:style {:margin-left 16 :justify-content :flex-start}}
[react/view {:style {:justify-content :center
:align-items :center}}
[react/text {:style styles/current-snt-amount}
[react/nested-text {:style styles/current-snt-amount}
snt-amount
[react/text {:style (assoc styles/current-snt-amount
:color colors/gray)} " SNT"]]]
[{:style (assoc styles/current-snt-amount :color colors/gray)}
" SNT"]]]
[snt-asset-value fiat-value]]]
[react/view {:flex 1}]
[react/text {:on-press #(re-frame/dispatch
@ -221,8 +265,9 @@
:min-height 24}]
[enabled-note]])
(defn chat-sample []
[react/view {:style (assoc styles/learn-more-section :margin-top 24)}
(defn pay-to-chat-message [{:keys [snt-amount fiat-amount fiat-currency
personalized-message style public-key tribute-status]}]
[react/view {:style style}
[react/view {:style {:flex-direction :row
:align-items :center}}
[react/view {:style {:background-color colors/white
@ -232,50 +277,79 @@
:font-size 13
:margin-left 4}}
(i18n/label :t/tribute-to-talk)]]
(when-not (string/blank? personalized-message)
[react/view {:style styles/chat-sample-bubble}
[react/text (i18n/label :t/tribute-to-talk-sample-text)]])
[react/view {:style styles/chat-sample-bubble}
[react/text (i18n/label :t/tribute-to-talk-sample-text)]]
[react/view {:style (assoc styles/chat-sample-bubble :width 141)}
;;TODO replace hardcoded values
[react/text {:style {:font-size 22}} "1000"
[react/text {:style {:font-size 22 :color colors/gray}} " SNT"]]
[react/text {:style {:font-size 12}}
"~3.48"
[react/text {:style {:font-size 12 :color colors/gray}} " USD"]]
[react/nested-text {:style {:font-size 22}}
(str snt-amount)
[{:style {:font-size 22 :color colors/gray}} " SNT"]]
[react/nested-text
{:style {:font-size 12}}
(str "~" fiat-amount)
[{:style {:font-size 12 :color colors/gray}} (str " " fiat-currency)]]
[react/view {:style styles/pay-to-chat-container}
[react/text {:style styles/pay-to-chat-text}
(i18n/label :t/pay-to-chat)]]]])
(if (or (nil? public-key) (= tribute-status :required))
[react/text (cond-> {:style styles/pay-to-chat-text}
public-key
(assoc :on-press #(re-frame/dispatch [:tribute-to-talk.ui/on-pay-to-chat-pressed
public-key])))
(i18n/label :t/pay-to-chat)]
[react/view {:style {:flex-direction :row}}
[react/view {:style (styles/payment-status-icon (= tribute-status :pending))}
[icons/icon (if (= tribute-status :pending) :tiny-icons/tiny-pending :tiny-icons/tiny-check)
{:color (if (= tribute-status :pending) colors/black colors/white)}]]
[react/text {:style styles/payment-status-text}
nil]])]]])
(defn learn-more []
[react/scroll-view {:content-container-style styles/learn-more-container}
[react/image {:source (:tribute-to-talk resources/ui)
:style styles/learn-more-image}]
[react/text {:style styles/learn-more-title-text}
(i18n/label :t/tribute-to-talk)]
[react/view {:style styles/learn-more-text-container-1}
[react/text {:style styles/learn-more-text}
(i18n/label :t/tribute-to-talk-learn-more-1)]]
[separator]
[chat-sample]
[react/view {:style styles/learn-more-text-container-2}
[react/text {:style styles/learn-more-text}
(i18n/label :t/tribute-to-talk-learn-more-2)]]
[react/view {:style (assoc styles/learn-more-section
:flex-direction :row
:align-item :flex-stretch
:padding-horizontal 16
:padding-vertical 12)}
[react/view {:style (styles/icon-view colors/blue-light)}
[icons/icon :main-icons/add-contact {:color colors/blue}]]
[react/view {:style {:margin-left 16 :justify-content :center}}
[react/text {:style (assoc styles/learn-more-text :color colors/blue)}
(i18n/label :t/add-to-contacts)]]]
[react/view {:style styles/learn-more-text-container-2}
[react/text {:style styles/learn-more-text}
(i18n/label :t/tribute-to-talk-learn-more-3)]]])
(defn learn-more [owner?]
[react/view {:flex 1}
(when-not owner?
[toolbar/toolbar nil toolbar/default-nav-close
[react/view
[react/text {:style styles/tribute-to-talk}
(i18n/label :t/tribute-to-talk)]
[react/text {:style styles/step-n}
(i18n/label :t/learn-more)]]])
[react/scroll-view {:content-container-style styles/learn-more-container}
[react/image {:source (:tribute-to-talk resources/ui)
:style styles/learn-more-image}]
[react/text {:style styles/learn-more-title-text}
(i18n/label :t/tribute-to-talk)]
[react/view {:style styles/learn-more-text-container-1}
[react/text {:style styles/learn-more-text}
(i18n/label (if owner? :t/tribute-to-talk-learn-more-1
:t/tribute-to-talk-paywall-learn-more-1))]]
[separator]
[pay-to-chat-message {:snt-amount 1000
:fiat-amount 3.48
:fiat-currency (i18n/label :t/usd-currency)
:personalized-message (i18n/label :t/tribute-to-talk-sample-text)
:style (assoc styles/learn-more-section :margin-top 24)}]
[react/view {:style styles/learn-more-text-container-2}
[react/text {:style styles/learn-more-text}
(i18n/label (if owner? :t/tribute-to-talk-learn-more-2
:t/tribute-to-talk-paywall-learn-more-2))]]
[react/view {:style (assoc styles/learn-more-section
:flex-direction :row
:align-item :flex-stretch
:padding-horizontal 16
:padding-vertical 12)}
[react/view {:style (styles/icon-view colors/blue-light)}
[icons/icon :main-icons/add-contact {:color colors/blue}]]
[react/view {:style {:margin-left 16 :justify-content :center}}
[react/text {:style (assoc styles/learn-more-text :color colors/blue)}
(i18n/label (if owner? :t/add-to-contacts :t/share-profile))]]]
[react/view {:style styles/learn-more-text-container-2}
[react/text {:style styles/learn-more-text}
(i18n/label (if owner? :t/tribute-to-talk-learn-more-3
:t/tribute-to-talk-paywall-learn-more-3))]]]])
(defview tribute-to-talk []
(letsubs [current-account [:account/account]
{:keys [step snt-amount editing? message fiat-value disabled?]}
{:keys [step snt-amount editing? message
fiat-value disable-button? state]}
[:tribute-to-talk/ui]]
[react/keyboard-avoiding-view {:style styles/container}
[react/safe-area-view {:style {:flex 1}}
@ -292,7 +366,12 @@
(when-not (#{:edit :learn-more} step)
[react/text {:style styles/step-n}
(if (= step :finish)
(i18n/label (if snt-amount :t/completed :t/disabled))
(i18n/label (case state
:completed :t/completed
:pending :t/pending
:signing :t/signing
:transaction-failed :t/transaction-failed
:disabled :t/disabled))
(i18n/label :t/step-i-of-n {:step ((steps-numbers editing?) step)
:number (if editing? 2 3)}))])
(when (= step :learn-more)
@ -303,15 +382,15 @@
:intro [intro]
:set-snt-amount [set-snt-amount snt-amount]
:edit [edit snt-amount message fiat-value]
:learn-more [learn-more]
:learn-more [learn-more step]
:personalized-message [personalized-message message]
:finish [finish snt-amount])
:finish [finish snt-amount state])
(when-not (#{:learn-more :edit} step)
[react/view {:style styles/bottom-toolbar}
[components.common/button {:button-style styles/intro-button
:disabled? disabled?
:label-style (when disabled? {:color colors/gray})
:disabled? disable-button?
:label-style (when disable-button? {:color colors/gray})
:on-press #(re-frame/dispatch
[:tribute-to-talk.ui/step-forward-pressed])
:label (i18n/label (step-forward-label step))}]])]]))

View File

@ -1,33 +1,30 @@
(ns status-im.ui.screens.profile.user.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [re-frame.core :as re-frame]
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.ui.components.list.views :as list.views]
[status-im.i18n :as i18n]
[status-im.ui.components.action-button.styles :as action-button.styles]
[status-im.ui.components.button.view :as button]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.common.styles :as common.styles]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.common.common :as components.common]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.ui.components.list-selection :as list-selection]
[status-im.ui.components.list.views :as list.views]
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
[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 toolbar.actions]
[status-im.ui.components.toolbar.styles :as toolbar.styles]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.screens.profile.components.styles
:as
profile.components.styles]
[status-im.ui.screens.profile.components.views :as profile.components]
[status-im.ui.screens.profile.components.styles :as profile.components.styles]
[status-im.ui.screens.profile.user.styles :as styles]
[status-im.utils.build :as build]
[status-im.utils.config :as config]
[status-im.utils.platform :as platform]
[status-im.utils.utils :as utils]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.ui.components.common.common :as components.common]
[status-im.utils.identicon :as identicon]
[clojure.string :as string]
[status-im.utils.universal-links.core :as universal-links]))
[status-im.utils.platform :as platform]
[status-im.utils.universal-links.core :as universal-links]
[status-im.utils.utils :as utils])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
(defn my-profile-toolbar []
[toolbar/toolbar
@ -277,18 +274,36 @@
:accessory-value active-contacts-count
:action-fn #(re-frame/dispatch [:navigate-to :contacts-list])}])
(defn tribute-to-talk-item [snt-amount seen?]
(defn tribute-to-talk-item [state snt-amount seen?]
[list.views/big-list-item
(cond-> {:text (i18n/label :t/tribute-to-talk)
:icon :main-icons/tribute-to-talk
:accessibility-label :notifications-button
:new? (not seen?)
:action-fn #(re-frame/dispatch
[:tribute-to-talk.ui/menu-item-pressed])}
snt-amount
(assoc :accessory-value (str snt-amount " SNT"))
(not (and seen? snt-amount))
(assoc :subtext (i18n/label :t/tribute-to-talk-desc)))])
(and (not (and seen?
snt-amount
(#{:signing :pending :transaction-failed} state))))
(assoc :subtext (i18n/label :t/tribute-to-talk-desc))
(#{:signing :pending} state)
(assoc :activity-indicator {:animating true
:color colors/blue}
:subtext (case state
:pending (i18n/label :t/pending-confirmation)
:signing (i18n/label :t/waiting-to-sign)))
(= state :transaction-failed)
(assoc :icon :main-icons/warning
:icon-color colors/red
:subtext (i18n/label :t/transaction-failed))
(not (#{:signing :pending :transaction-failed} state))
(assoc :icon :main-icons/tribute-to-talk)
(and (= state :completed)
(not-empty snt-amount))
(assoc :accessory-value (str snt-amount " SNT")))])
(defview extensions-settings []
(letsubs [{:keys [label view on-close]} [:get-screen-params :my-profile-ext-settings]]
@ -308,7 +323,8 @@
scroll (reagent/atom nil)
active-contacts-count [:contacts/active-count]
{tribute-to-talk-seen? :seen?
snt-amount :snt-amount} [:tribute-to-talk/settings]]
snt-amount :snt-amount
tribute-to-talk-state :state} [:tribute-to-talk/ui]]
(let [shown-account (merge current-account changed-account)
;; We scroll on the component once rendered. setTimeout is necessary,
;; likely to allow the animation to finish.
@ -342,7 +358,10 @@
[share-profile-item (dissoc current-account :mnemonic)]
[contacts-list-item active-contacts-count]
(when config/tr-to-talk-enabled?
[tribute-to-talk-item snt-amount tribute-to-talk-seen?])
[tribute-to-talk-item
tribute-to-talk-state
snt-amount
tribute-to-talk-seen?])
[my-profile-settings current-account shown-account currency (nil? login-data) extensions]
(when (nil? login-data)
[advanced shown-account on-show-advanced])]]])))

View File

@ -19,6 +19,7 @@
:chat-modal
:show-extension-modal
:stickers-pack-modal
:tribute-learn-more
:wallet-sign-message-modal
:selection-modal-screen
:wallet-settings-assets

View File

@ -1,63 +1,82 @@
(ns status-im.ui.screens.routing.screens
(:require
[status-im.ui.screens.accounts.login.views :as login]
[status-im.ui.screens.accounts.recover.views :as recover]
[status-im.ui.screens.accounts.views :as accounts]
[status-im.ui.screens.progress.views :as progress]
[status-im.ui.screens.chat.views :as chat]
[status-im.ui.screens.add-new.views :as add-new]
[status-im.ui.screens.add-new.new-chat.views :as new-chat]
[status-im.ui.screens.add-new.new-public-chat.view :as new-public-chat]
[status-im.ui.screens.qr-scanner.views :as qr-scanner]
[status-im.ui.screens.group.views :as group]
[status-im.ui.screens.profile.user.views :as profile.user]
[status-im.ui.screens.profile.contact.views :as profile.contact]
[status-im.ui.screens.profile.group-chat.views :as profile.group-chat]
[status-im.ui.screens.profile.photo-capture.views :as photo-capture]
[status-im.extensions.capacities.camera.views :as extensions.camera.views]
[status-im.ui.screens.wallet.main.views :as wallet.main]
[status-im.ui.screens.wallet.collectibles.views :as collectibles]
[status-im.ui.screens.wallet.send.views :as send]
[status-im.ui.screens.wallet.sign-message.views :as sign-message]
[status-im.ui.screens.wallet.request.views :as request]
[status-im.ui.screens.wallet.components.views :as wallet.components]
[status-im.ui.screens.wallet.onboarding.views :as wallet.onboarding]
[status-im.ui.screens.wallet.transaction-fee.views :as wallet.transaction-fee]
[status-im.ui.screens.wallet.settings.views :as wallet-settings]
[status-im.ui.screens.wallet.transactions.views :as wallet-transactions]
[status-im.ui.screens.wallet.transaction-sent.views :as transaction-sent]
[status-im.ui.screens.contacts-list.views :as contacts-list]
[status-im.ui.screens.network-settings.views :as network-settings]
[status-im.ui.screens.network-settings.network-details.views :as network-details]
[status-im.ui.screens.network-settings.edit-network.views :as edit-network]
[status-im.ui.screens.extensions.views :as screens.extensions]
[status-im.ui.screens.log-level-settings.views :as log-level-settings]
[status-im.ui.screens.fleet-settings.views :as fleet-settings]
[status-im.ui.screens.offline-messaging-settings.views :as offline-messaging-settings]
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.views :as edit-mailserver]
[status-im.ui.screens.extensions.add.views :as extensions.add]
[status-im.ui.screens.bootnodes-settings.views :as bootnodes-settings]
[status-im.ui.screens.pairing.views :as pairing]
[status-im.ui.screens.bootnodes-settings.edit-bootnode.views :as edit-bootnode]
[status-im.ui.screens.currency-settings.views :as currency-settings]
[status-im.ui.screens.hardwallet.settings.views :as hardwallet.settings]
[status-im.ui.screens.help-center.views :as help-center]
[status-im.ui.screens.browser.views :as browser]
[status-im.ui.screens.browser.open-dapp.views :as open-dapp]
[status-im.ui.screens.intro.views :as intro]
[status-im.ui.screens.accounts.create.views :as accounts.create]
[status-im.ui.screens.hardwallet.authentication-method.views :as hardwallet.authentication]
[status-im.ui.screens.hardwallet.connect.views :as hardwallet.connect]
[status-im.ui.screens.hardwallet.pin.views :as hardwallet.pin]
[status-im.ui.screens.hardwallet.setup.views :as hardwallet.setup]
[status-im.ui.screens.hardwallet.success.views :as hardwallet.success]
[status-im.ui.screens.profile.seed.views :as profile.seed]
[status-im.ui.screens.profile.tribute-to-talk.views :as tr-to-talk]
[status-im.ui.screens.about-app.views :as about-app]
[status-im.ui.screens.stickers.views :as stickers]
[status-im.ui.screens.dapps-permissions.views :as dapps-permissions]
[status-im.ui.screens.mobile-network-settings.view :as mobile-network-settings]
[status-im.ui.screens.home.views :as home]))
(:require [status-im.extensions.capacities.camera.views
:as
extensions.camera.views]
[status-im.ui.screens.about-app.views :as about-app]
[status-im.ui.screens.accounts.create.views :as accounts.create]
[status-im.ui.screens.accounts.login.views :as login]
[status-im.ui.screens.accounts.recover.views :as recover]
[status-im.ui.screens.accounts.views :as accounts]
[status-im.ui.screens.add-new.new-chat.views :as new-chat]
[status-im.ui.screens.add-new.new-public-chat.view :as new-public-chat]
[status-im.ui.screens.add-new.views :as add-new]
[status-im.ui.screens.bootnodes-settings.edit-bootnode.views
:as
edit-bootnode]
[status-im.ui.screens.bootnodes-settings.views :as bootnodes-settings]
[status-im.ui.screens.browser.open-dapp.views :as open-dapp]
[status-im.ui.screens.browser.views :as browser]
[status-im.ui.screens.chat.views :as chat]
[status-im.ui.screens.contacts-list.views :as contacts-list]
[status-im.ui.screens.currency-settings.views :as currency-settings]
[status-im.ui.screens.dapps-permissions.views :as dapps-permissions]
[status-im.ui.screens.extensions.add.views :as extensions.add]
[status-im.ui.screens.extensions.views :as screens.extensions]
[status-im.ui.screens.fleet-settings.views :as fleet-settings]
[status-im.ui.screens.group.views :as group]
[status-im.ui.screens.hardwallet.authentication-method.views
:as
hardwallet.authentication]
[status-im.ui.screens.hardwallet.connect.views :as hardwallet.connect]
[status-im.ui.screens.hardwallet.pin.views :as hardwallet.pin]
[status-im.ui.screens.hardwallet.settings.views :as hardwallet.settings]
[status-im.ui.screens.hardwallet.setup.views :as hardwallet.setup]
[status-im.ui.screens.hardwallet.success.views :as hardwallet.success]
[status-im.ui.screens.help-center.views :as help-center]
[status-im.ui.screens.home.views :as home]
[status-im.ui.screens.intro.views :as intro]
[status-im.ui.screens.log-level-settings.views :as log-level-settings]
[status-im.ui.screens.mobile-network-settings.view
:as
mobile-network-settings]
[status-im.ui.screens.network-settings.edit-network.views
:as
edit-network]
[status-im.ui.screens.network-settings.network-details.views
:as
network-details]
[status-im.ui.screens.network-settings.views :as network-settings]
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.views
:as
edit-mailserver]
[status-im.ui.screens.offline-messaging-settings.views
:as
offline-messaging-settings]
[status-im.ui.screens.pairing.views :as pairing]
[status-im.ui.screens.profile.contact.views :as profile.contact]
[status-im.ui.screens.profile.group-chat.views :as profile.group-chat]
[status-im.ui.screens.profile.photo-capture.views :as photo-capture]
[status-im.ui.screens.profile.seed.views :as profile.seed]
[status-im.ui.screens.profile.tribute-to-talk.views :as tr-to-talk]
[status-im.ui.screens.profile.user.views :as profile.user]
[status-im.ui.screens.progress.views :as progress]
[status-im.ui.screens.qr-scanner.views :as qr-scanner]
[status-im.ui.screens.stickers.views :as stickers]
[status-im.ui.screens.wallet.collectibles.views :as collectibles]
[status-im.ui.screens.wallet.components.views :as wallet.components]
[status-im.ui.screens.wallet.main.views :as wallet.main]
[status-im.ui.screens.wallet.onboarding.views :as wallet.onboarding]
[status-im.ui.screens.wallet.request.views :as request]
[status-im.ui.screens.wallet.send.views :as send]
[status-im.ui.screens.wallet.settings.views :as wallet-settings]
[status-im.ui.screens.wallet.sign-message.views :as sign-message]
[status-im.ui.screens.wallet.transaction-fee.views
:as
wallet.transaction-fee]
[status-im.ui.screens.wallet.transaction-sent.views
:as
transaction-sent]
[status-im.ui.screens.wallet.transactions.views :as wallet-transactions]))
(def all-screens
{:login login/login
@ -89,6 +108,7 @@
:stickers stickers/packs
:stickers-pack stickers/pack
:stickers-pack-modal [:modal stickers/pack-modal]
:tribute-learn-more [:modal tr-to-talk/learn-more]
:chat-modal [:modal chat/chat-modal]
:show-extension-modal [:modal extensions.add/show-extension-modal]
:wallet-send-transaction-modal [:modal send/send-transaction-modal]

View File

@ -7,7 +7,16 @@
[status-im.utils.money :as money]))
(def contracts
{:status/tribute-to-talk
{:status/snt
{:address
{:mainnet "0x744d70fdbe2ba4cf95131626614a1763df805b9e"
:testnet "0xc55cf4b03948d7ebc8b9e8bad92643703811d162"
:rinkeby nil}
:methods
{:erc20/transfer
{:signature "transfer(address,uint256)"
:write? true}}}
:status/tribute-to-talk
{:address
{:mainnet nil
:testnet "0x3da3fc53e24707f36c5b4433b442e896c4955f0e"
@ -40,7 +49,8 @@
callback)))
(fx/defn call
[{:keys [db] :as cofx} {:keys [contract method params callback on-result on-error details]}]
[{:keys [db] :as cofx}
{:keys [contract method params callback on-result on-error details]}]
(let [chain-keyword (-> (get-in db [:account/account :networks (:network db)])
ethereum/network->chain-keyword)
contract-address (get-in contracts [contract :address chain-keyword])]

View File

@ -225,7 +225,7 @@ class OkGotItButton(BaseButton):
def __init__(self, driver):
super(OkGotItButton, self).__init__(driver)
self.locator = self.Locator.text_selector('Ok, got it')
self.locator = self.Locator.text_selector('OK, got it')
class DebugModeToggle(BaseButton):

View File

@ -480,7 +480,7 @@
"dapp": "ÐApp",
"mainnet-text": "Youre on the Mainnet. Real ETH will be sent",
"receive": "Receive",
"ok-got-it": "Ok, got it",
"ok-got-it": "OK, got it",
"ok": "OK",
"main-currency": "Main currency",
"ens-names": "ENS names",
@ -918,23 +918,43 @@
"tribute-to-talk-set-snt-amount": "Set the amount of SNT required for new people to start a chat",
"personalized-message": "Personalized message",
"optional": "optional",
"pending-confirmation": "Pending confirmation...",
"waiting-to-sign": "Waiting to sign transaction...",
"tribute-to-talk-message-placeholder": "Hi there, I ask you to pay tribute to start a chat with me. If you know me in real life, you know how to find me...",
"tribute-to-talk-you-can-leave-a-message": "You can leave a message for people to see when they want to start a chat with you.",
"tribute-to-talk-sign-and-set-tribute": "Sign and set tribute",
"tribute-to-talk-finish-desc": "From now on, you will only receive chats from contacts, and people who paid ",
"tribute-to-talk-you-require-snt": "You require SNT for new people to start a chat.",
"tribute-to-talk-signing": "Waiting to sign transaction",
"tribute-to-talk-pending": "Tribute pending confirmation",
"tribute-to-talk-pending-note": "Tribute transaction is pending confirmation on the network. You can check its status in transaction history",
"tribute-to-talk-transaction-failed-note": "Transaction has failed and your Tribute to Talk settings have not been changed",
"tribute-to-talk-removing-note": "Removing Tribute to Talk will allow new people to start a chat without sending SNT. Requires a transaction to be made.",
"tribute-to-talk-enabled": "You have Tribute to Talk enabled.",
"tribute-to-talk-add-friends": "Add friends as a contact to allow chats without tribute payment.",
"signing": "Signing",
"learn-more": "Learn more",
"loading": "Loading...",
"tribute-to-talk-learn-more-1": "Your time and attention are your most valuable assets. Tribute to Talk lets you set an amount of SNT required for new people to start a chat with you.",
"tribute-to-talk-learn-more-2": "Anyone who is not in your contact list will be asked to pay, and you can respond once they have.",
"tribute-to-talk-learn-more-3": "You can always send the money back, but to ensure that friends can reach you freely, add them as a contact first.",
"tribute-to-talk-sample-text": "Hi Im Carmen. Message me to have your fortune told 🔮",
"tribute-to-talk-disabled": "Tribute to Talk disabled",
"tribute-to-talk-disabled-note": "From now on, new people can start a chat with you without sending SNT.",
"tribute-state-required": "Requires {{snt-amount}} SNT tribute",
"tribute-state-pending": "Tribute pending",
"tribute-state-paid": "Tribute paid",
"tribute-required-by-account": "{{account-name}} requires SNT to start a chat.",
"tribute-to-talk-are-you-friends": "Are you friends?",
"tribute-to-talk-ask-to-be-added": "Ask to be added as a contact",
"tribute-to-talk-paywall-learn-more-1": "Our time and attention are our most valuable assets. Tribute to Talk lets you contact new people in exchange for an SNT payment.",
"tribute-to-talk-paywall-learn-more-2": "To start a chat with someone who has a tribute set, simply pay the required SNT and you will be added as a contact.",
"tribute-to-talk-paywall-learn-more-3": "If you know them, you can share your profile outside of Status to be added for free.",
"tribute-to-talk-contact-received-your-tribute": " received your tribute. You are now contacts and can securely chat with each other.",
"pay-to-chat": "Pay to chat",
"share-chat": "Share chat",
"share-link": "Share link",
"share-profile": "Share profile",
"share-profile-link": "Share profile link",
"add-contact": "Add contact",
"blocked-users": "Blocked users",