diff --git a/.gitignore b/.gitignore index a814427814..4e18fe503c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ # .DS_Store .projectile +.cljs_rhino_repl/ +.#* # Xcode # diff --git a/resources/console.js b/resources/console.js index 0395cb9713..6719c2708b 100644 --- a/resources/console.js +++ b/resources/console.js @@ -13,8 +13,10 @@ I18n.translations = { password_placeholder2: 'Please re-enter password to confirm', password_error: 'Password should be not less then 6 symbols.', password_error1: 'Password confirmation doesn\'t match password.', - password_validation_title: 'Password' + password_validation_title: 'Password', + faucet_incorrect_title: 'Incorrect faucet', + faucet_incorrect_description: 'Please, select a one from the list' }, ru: { phone_title: 'Отправить номер телефона', @@ -1594,7 +1596,6 @@ status.command({ handler: jsHandler }); - var phones = [ // TODO this is supposed to be regionalised { number: "89171111111", @@ -1719,6 +1720,111 @@ var phoneConfig = { status.response(phoneConfig); status.command(phoneConfig); +var faucets = [ + { + name: "Ethereum Robsten Faucet", + url: "http://faucet.ropsten.be:3001" + }, + { + name: "Status Testnet Faucet", + url: "http://46.101.129.137:3001", + }, + { + name: "Zerogox Faucet", + url: "https://zerogox.com/ethereum/wei_faucet" + } +]; + +function faucetSuggestions(params) { + var suggestions = faucets.map(function(entry) { + return status.components.touchable( + {onPress: [status.events.SET_VALUE, entry.url]}, + status.components.view( + suggestionContainerStyle, + [status.components.view( + suggestionSubContainerStyle, + [ + status.components.text( + {style: valueStyle}, + entry.name + ), + status.components.text( + {style: descriptionStyle}, + entry.url + ) + ] + )] + ) + ); + }); + + var view = status.components.scrollView( + suggestionsContainerStyle(faucets.length), + suggestions + ); + + return {markup: view}; +} + +status.command({ + name: "faucet", + title: "Faucet", + description: "Get some ETH", + color: "#7099e6", + registeredOnly: true, + params: [{ + name: "url", + type: status.types.TEXT, + suggestions: faucetSuggestions, + placeholder: "Faucet URL" + }], + preview: function (params) { + return status.components.text( + {}, + params.url + ); + }, + validator: function (params, context) { + var f = faucets.map(function (entry) { + return entry.url; + }); + + if (f.indexOf(params.url) == -1) { + var error = status.components.validationMessage( + I18n.t('faucet_incorrect_title'), + I18n.t('faucet_incorrect_description') + ); + + return {errors: [error]}; + } + } +}); + + +function browseSuggestions(params) { + if (params.url && params.url !== "undefined" && params.url != "") { + var url = params.url; + if (!/^[a-zA-Z-_]+:/.test(url)) { + url = 'http://' + url; + } + + return {webViewUrl: url}; + } +} + +status.command({ + name: "browse", + color: "#ffa500", + hidden: true, + fullscreen: true, + suggestionsTrigger: 'on-send', + params: [{ + name: "url", + suggestions: browseSuggestions, + type: status.types.TEXT + }] +}); + // status.command({ // name: "help", @@ -1822,4 +1928,4 @@ status.registerFunction("message-suggestions", function(params, context) { status.registerFunction("message-handler", function(params, context) { return jsHandler({code: params.message}, context); -}); \ No newline at end of file +}); diff --git a/resources/status.js b/resources/status.js index e25ae39025..7c7f9db2be 100644 --- a/resources/status.js +++ b/resources/status.js @@ -26,6 +26,7 @@ Command.prototype.create = function (com) { this.description = com.description; this.handler = com.handler; this["has-handler"] = com.handler != null; + this["registered-only"] = com.registeredOnly; this.validator = com.validator; this.color = com.color; this.icon = com.icon; diff --git a/src/status_im/chat/handlers.cljs b/src/status_im/chat/handlers.cljs index 99b1fb6dc1..0af3fdce69 100644 --- a/src/status_im/chat/handlers.cljs +++ b/src/status_im/chat/handlers.cljs @@ -34,6 +34,7 @@ status-im.chat.handlers.unviewed-messages status-im.chat.handlers.send-message status-im.chat.handlers.receive-message + status-im.chat.handlers.faucet [cljs.core.async :as a] status-im.chat.handlers.webview-bridge status-im.chat.handlers.wallet-chat @@ -584,6 +585,10 @@ (fn [{:keys [current-chat-id] :as db} [_ url]] (assoc-in db [:web-view-url current-chat-id] url))) +(register-handler :set-web-view-extra-js + (fn [{:keys [current-chat-id] :as db} [_ extra-js]] + (assoc-in db [:web-view-extra-js current-chat-id] extra-js))) + (register-handler :set-soft-input-mode (after (fn [{:keys [current-chat-id]} [_ mode chat-id]] diff --git a/src/status_im/chat/handlers/console.cljs b/src/status_im/chat/handlers/console.cljs index 270a4912ac..825082218c 100644 --- a/src/status_im/chat/handlers/console.cljs +++ b/src/status_im/chat/handlers/console.cljs @@ -18,12 +18,16 @@ :confirmation-code (fn [params id] - (dispatch [:sign-up-confirm (params "code") id]))}) + (dispatch [:sign-up-confirm (params "code") id])) + + :faucet + (fn [params id] + (dispatch [:open-faucet (params "url") id]))}) (def commands-names (set (keys console-commands))) (def commands-with-delivery-status - (disj commands-names :password)) + (disj commands-names :password :faucet)) (register-handler :invoke-console-command-handler! (u/side-effect! diff --git a/src/status_im/chat/handlers/faucet.cljs b/src/status_im/chat/handlers/faucet.cljs new file mode 100644 index 0000000000..1c1df0e0b2 --- /dev/null +++ b/src/status_im/chat/handlers/faucet.cljs @@ -0,0 +1,65 @@ +(ns status-im.chat.handlers.faucet + (:require [re-frame.core :refer [dispatch]] + [status-im.utils.handlers :refer [register-handler] :as u] + [status-im.utils.utils :refer [http-get]] + [status-im.utils.random :as random] + [status-im.constants :refer [console-chat-id + text-content-type]] + [status-im.i18n :refer [label]] + [taoensso.timbre :as log] + [goog.string :as gstring] + goog.string.format)) + +(def faucets + [{:name "http://faucet.ropsten.be:3001" + :type :api + :api-url "http://faucet.ropsten.be:3001/donate/0x%s"} + {:name "http://46.101.129.137:3001" + :type :api + :api-url "http://46.101.129.137:3001/donate/0x%s"} + {:name "https://zerogox.com/ethereum/wei_faucet" + :type :prefill + :prefill-js "document.getElementById('edit-ethereum-address').value='%s';"}]) + +(defn faucet-by-name [faucet-name] + (->> faucets + (filter #(= (:name %) faucet-name)) + (first))) + +(defn received-message [content] + (dispatch [:received-message + {:message-id (random/id) + :content content + :content-type text-content-type + :outgoing false + :chat-id console-chat-id + :from console-chat-id + :to "me"}])) + +(defmulti open-faucet (fn [_ _ {:keys [type]}] type)) + +(defmethod open-faucet :api + [faucet-name current-address {:keys [api-url]}] + (let [api-url (gstring/format api-url current-address)] + (http-get api-url + #(received-message (label :t/faucet-success)) + #(received-message (label :t/faucet-error))))) + +(defmethod open-faucet :prefill + [faucet-name current-address {:keys [prefill-js]}] + (let [prefill-js (gstring/format prefill-js current-address) + web-view-js (gstring/format + "document.addEventListener('DOMContentLoaded', function(){ %s };" + prefill-js)] + (dispatch [:set-chat-command :browse]) + (dispatch [:fill-chat-command-content faucet-name]) + (dispatch [:set-web-view-extra-js web-view-js]) + (js/setTimeout #(dispatch [:send-command!]) 500))) + +(register-handler + :open-faucet + (u/side-effect! + (fn [{:keys [accounts current-account-id]} [_ faucet-name _]] + (if-let [faucet (faucet-by-name faucet-name)] + (let [current-address (get-in accounts [current-account-id :address])] + (open-faucet faucet-name current-address faucet)))))) diff --git a/src/status_im/chat/subs.cljs b/src/status_im/chat/subs.cljs index ab4fcff9a6..0a21c757f6 100644 --- a/src/status_im/chat/subs.cljs +++ b/src/status_im/chat/subs.cljs @@ -260,6 +260,11 @@ (let [chat-id (subscribe [:get-current-chat-id])] (reaction (get-in @db [:web-view-url @chat-id]))))) +(register-sub :web-view-extra-js + (fn [db] + (let [chat-id (subscribe [:get-current-chat-id])] + (reaction (get-in @db [:web-view-extra-js @chat-id]))))) + (register-sub :animate? (fn [db] (let [chat-id (subscribe [:get-current-chat-id])] diff --git a/src/status_im/chat/views/response.cljs b/src/status_im/chat/views/response.cljs index 8e1c054457..8b8ab45710 100644 --- a/src/status_im/chat/views/response.cljs +++ b/src/status_im/chat/views/response.cljs @@ -129,7 +129,8 @@ [text (label :t/web-view-error)]])) (defview suggestions-web-view [] - [url [:web-view-url]] + [url [:web-view-url] + extra-js [:web-view-extra-js]] (when url [webview-bridge {:ref #(dispatch [:set-webview-bridge %]) @@ -137,7 +138,7 @@ :source {:uri url} :render-error web-view-error :java-script-enabled true - :injected-java-script js-res/webview-js + :injected-java-script (str js-res/webview-js extra-js) :bounces false :on-navigation-state-change on-navigation-change}])) diff --git a/src/status_im/chat/views/suggestions.cljs b/src/status_im/chat/views/suggestions.cljs index 3a652167a6..528c566b4b 100644 --- a/src/status_im/chat/views/suggestions.cljs +++ b/src/status_im/chat/views/suggestions.cljs @@ -1,5 +1,6 @@ (ns status-im.chat.views.suggestions - (:require-macros [status-im.utils.views :refer [defview]]) + (:require-macros [status-im.utils.views :refer [defview]] + [clojure.string :as str]) (:require [re-frame.core :refer [subscribe dispatch]] [status-im.components.react :refer [view scroll-view @@ -77,7 +78,7 @@ ^{:key [chat-id message-id]} [request-item request])) [title (label :t/suggestions-commands)] - (for [suggestion suggestions] + (for [suggestion (remove #(nil? (:title (second %))) suggestions)] ^{:key (first suggestion)} [suggestion-list-item suggestion])]]) diff --git a/src/status_im/commands/handlers/jail.cljs b/src/status_im/commands/handlers/jail.cljs index 38e86b4f98..ee533bb21b 100644 --- a/src/status_im/commands/handlers/jail.cljs +++ b/src/status_im/commands/handlers/jail.cljs @@ -16,7 +16,7 @@ (let [hiccup (generate-hiccup markup)] (assoc-in db [:rendered-commands chat-id message-id] hiccup))) -(defn command-hadler! +(defn command-handler! [_ [chat-id {:keys [staged-command] :as parameters} {:keys [result error]}]] @@ -46,7 +46,7 @@ (let [{:keys [markup webViewUrl]} (:returned result) hiccup (generate-hiccup markup)] (-> db - (assoc-in [:suggestions chat-id] (generate-hiccup markup)) + (assoc-in [:suggestions chat-id] hiccup) (assoc-in [:web-view-url chat-id] webViewUrl) (assoc-in [:has-suggestions? chat-id] (or hiccup webViewUrl))))) @@ -83,7 +83,7 @@ (reg-handler :command-handler! (after (print-error-message! "Error on command handling")) - (u/side-effect! command-hadler!)) + (u/side-effect! command-handler!)) (reg-handler :suggestions-handler [(after #(dispatch [:animate-show-response])) @@ -103,4 +103,4 @@ (reg-handler :set-local-storage (fn [{:keys [current-chat-id] :as db} [{:keys [data] :as event}]] (log/debug "Got event: " event) - (assoc-in db [:local-storage current-chat-id] data))) \ No newline at end of file + (assoc-in db [:local-storage current-chat-id] data))) diff --git a/src/status_im/commands/handlers/loading.cljs b/src/status_im/commands/handlers/loading.cljs index 271e33d2be..da4c62afa1 100644 --- a/src/status_im/commands/handlers/loading.cljs +++ b/src/status_im/commands/handlers/loading.cljs @@ -10,7 +10,8 @@ [status-im.constants :refer [console-chat-id wallet-chat-id]] [taoensso.timbre :as log] [status-im.utils.homoglyph :as h] - [status-im.utils.js-resources :as js-res])) + [status-im.utils.js-resources :as js-res] + [clojure.string :as str])) (def commands-js "commands.js") @@ -79,8 +80,11 @@ (map (fn [[k v]] [k (assoc v :type as)])) (into {}))) -(defn filter-forbidden-names [id commands] +(defn filter-forbidden-names [account id commands] (->> commands + (remove (fn [[_ {:keys [registered-only]}]] + (and (not (:address account)) + registered-only))) (remove (fn [[n]] (and (not (= console-chat-id id)) @@ -89,8 +93,9 @@ (defn add-commands [db [id _ {:keys [commands responses autorun]}]] - (let [commands' (filter-forbidden-names id commands) - responses' (filter-forbidden-names id responses)] + (let [account @(subscribe [:get-current-account]) + commands' (filter-forbidden-names account id commands) + responses' (filter-forbidden-names account id responses)] (-> db (assoc-in [id :commands] (mark-as :command commands')) (assoc-in [id :responses] (mark-as :response responses')) diff --git a/src/status_im/translations/en.cljs b/src/status_im/translations/en.cljs index 5e46abcd8b..e9c7688308 100644 --- a/src/status_im/translations/en.cljs +++ b/src/status_im/translations/en.cljs @@ -31,6 +31,8 @@ :no-messages "No messages" :suggestions-requests "Requests" :suggestions-commands "Commands" + :faucet-success "Faucet request has been received" + :faucet-error "Faucet request error" ;sync :sync-in-progress "Syncing..." @@ -162,6 +164,7 @@ :command-text-browse "Browsing webpage: {{webpage}}" :command-text-send "Transaction: {{amount}} ETH" :command-text-help "Help" + :command-text-faucet "Faucet: {{url}}" ;new-group :group-chat-name "Chat name"