From 54c3030971c005c774883b721c422fc534b06456 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 25 Mar 2022 12:09:47 +0100 Subject: [PATCH] https://github.com/status-im/status-go/compare/640793fe85d9a9eef9eb3712cda1c5a1ceea401a...0048aaebcc7859a6f0dd7cdf0266fe029f3066fcn [#13173] move stickers business logic to status-go Signed-off-by: andrey --- .env | 1 + .env.e2e | 1 + .env.jenkins | 1 + src/status_im/browser/core.cljs | 15 - src/status_im/chat/models/input.cljs | 22 +- src/status_im/constants.cljs | 6 +- src/status_im/data_store/settings.cljs | 2 - src/status_im/db.cljs | 1 - src/status_im/ethereum/json_rpc.cljs | 11 +- src/status_im/multiaccounts/login/core.cljs | 2 - src/status_im/stickers/core.cljs | 279 ++++++------------ src/status_im/stickers/core_test.cljs | 7 - src/status_im/subs.cljs | 40 +-- src/status_im/transport/core.cljs | 4 +- src/status_im/ui/screens/browser/views.cljs | 4 +- .../ui/screens/chat/message/message.cljs | 6 +- .../ui/screens/chat/stickers/views.cljs | 26 +- src/status_im/ui/screens/status/views.cljs | 11 +- src/status_im/ui/screens/stickers/views.cljs | 93 +++--- src/status_im/utils/config.cljs | 1 + src/status_im/utils/contenthash.cljs | 48 --- src/status_im/utils/contenthash_test.cljs | 26 -- src/status_im/utils/money.cljs | 4 + status-go-version.json | 6 +- 24 files changed, 207 insertions(+), 410 deletions(-) delete mode 100644 src/status_im/stickers/core_test.cljs delete mode 100644 src/status_im/utils/contenthash.cljs delete mode 100644 src/status_im/utils/contenthash_test.cljs diff --git a/.env b/.env index 7ee60c452c..c22d68ab60 100644 --- a/.env +++ b/.env @@ -34,3 +34,4 @@ COLLECTIBLES_ENABLED=1 COMMANDS_ENABLED=1 TWO_MINUTES_SYNCING=1 SWAP_ENABLED=1 +STICKERS_TEST_ENABLED=1 diff --git a/.env.e2e b/.env.e2e index aa5940d26e..1a6e9d044c 100644 --- a/.env.e2e +++ b/.env.e2e @@ -34,3 +34,4 @@ COMMUNITIES_MANAGEMENT_ENABLED=1 METRICS_ENABLED=0 DELETE_MESSAGE_ENABLED=1 TWO_MINUTES_SYNCING=1 +STICKERS_TEST_ENABLED=1 \ No newline at end of file diff --git a/.env.jenkins b/.env.jenkins index 20ef28303c..917c2af4c8 100644 --- a/.env.jenkins +++ b/.env.jenkins @@ -37,3 +37,4 @@ METRICS_ENABLED=0 DELETE_MESSAGE_ENABLED=1 TWO_MINUTES_SYNCING=1 ENABLE_QUO_PREVIEW=1 +STICKERS_TEST_ENABLED=1 \ No newline at end of file diff --git a/src/status_im/browser/core.cljs b/src/status_im/browser/core.cljs index 52f15f3427..bad51e17e4 100644 --- a/src/status_im/browser/core.cljs +++ b/src/status_im/browser/core.cljs @@ -10,7 +10,6 @@ [status-im.native-module.core :as status] [status-im.ui.components.list-selection :as list-selection] [status-im.navigation :as navigation] - [status-im.utils.contenthash :as contenthash] [status-im.utils.fx :as fx] [status-im.utils.http :as http] [status-im.utils.platform :as platform] @@ -182,20 +181,6 @@ :history new-history :history-index new-index)))))) -(defmulti storage-gateway :namespace) - -(defmethod storage-gateway :ipns - [{:keys [hash]}] - (str "https://" hash)) - -(defmethod storage-gateway :ipfs - [{:keys [hash]}] - (contenthash/ipfs-url hash)) - -(defmethod storage-gateway :swarm - [{:keys [hash]}] - (str "https://gateway.ethswarm.org/bzz/" hash)) - (fx/defn resolve-ens-multihash-success {:events [:browser.callback/resolve-ens-multihash-success]} [{:keys [db] :as cofx} url] diff --git a/src/status_im/chat/models/input.cljs b/src/status_im/chat/models/input.cljs index 0f0b50bda8..023dc47445 100644 --- a/src/status_im/chat/models/input.cljs +++ b/src/status_im/chat/models/input.cljs @@ -14,8 +14,7 @@ [status-im.utils.fx :as fx] ["emojilib" :as emojis] [status-im.chat.models.mentions :as mentions] - [status-im.utils.utils :as utils] - [status-im.multiaccounts.update.core :as multiaccounts.update])) + [status-im.utils.utils :as utils])) (defn text->emoji "Replaces emojis in a specified `text`" @@ -230,12 +229,12 @@ :text (i18n/label :t/update-to-listen-audio {"locale" "en"})}))) (fx/defn send-sticker-message - [cofx {:keys [hash pack]} current-chat-id] - (when-not (string/blank? hash) + [cofx {:keys [hash packID]} current-chat-id] + (when-not (or (string/blank? hash) (string/blank? packID)) (chat.message/send-message cofx {:chat-id current-chat-id :content-type constants/content-type-sticker :sticker {:hash hash - :pack pack} + :pack (int packID)} :text (i18n/label :t/update-to-see-sticker {"locale" "en"})}))) (fx/defn send-edited-message [{:keys [db] :as cofx} text {:keys [message-id]}] @@ -265,13 +264,16 @@ (fx/defn chat-send-sticker {:events [:chat/send-sticker]} - [{{:keys [current-chat-id multiaccount]} :db :as cofx} {:keys [hash] :as sticker}] + [{{:keys [current-chat-id] :as db} :db :as cofx} {:keys [hash packID] :as sticker}] (fx/merge cofx - (multiaccounts.update/multiaccount-update - :stickers/recent-stickers - (conj (remove #(= hash %) (:stickers/recent-stickers multiaccount)) hash) - {}) + {:db (update db + :stickers/recent-stickers + (fn [recent] + (conj (remove #(= hash (:hash %)) recent) sticker))) + ::json-rpc/call [{:method "stickers_addRecent" + :params [(int packID) hash] + :on-success #()}]} (send-sticker-message sticker current-chat-id))) (fx/defn chat-send-audio diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index 675560c85a..c4f3bfb97d 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -171,4 +171,8 @@ (def ^:const visibility-status-inactive 4) (def ^:const wallet-connect-version-1 1) -(def ^:const wallet-connect-version-2 2) \ No newline at end of file +(def ^:const wallet-connect-version-2 2) + +(def ^:const sticker-pack-status-installed 1) +(def ^:const sticker-pack-status-pending 2) +(def ^:const sticker-pack-status-owned 3) \ No newline at end of file diff --git a/src/status_im/data_store/settings.cljs b/src/status_im/data_store/settings.cljs index e6d9c5bf3d..1996ca030d 100644 --- a/src/status_im/data_store/settings.cljs +++ b/src/status_im/data_store/settings.cljs @@ -46,8 +46,6 @@ config/default-network)) (update :wallet/visible-tokens rpc->visible-tokens) (update :pinned-mailservers rpc->pinned-mailservers) - (update :stickers/packs-installed rpc->stickers-packs) - (update :stickers/packs-pending set) (update :link-previews-enabled-sites set) (update :custom-bootnodes rpc->custom-bootnodes) (update :custom-bootnodes-enabled? rpc->custom-bootnodes) diff --git a/src/status_im/db.cljs b/src/status_im/db.cljs index 9b9d4958d8..b65af572f9 100644 --- a/src/status_im/db.cljs +++ b/src/status_im/db.cljs @@ -33,7 +33,6 @@ :dimensions/window (dimensions/window) :registry {} :visibility-status-updates {} - :stickers/packs-owned #{} :stickers/packs-pending #{} :keycard {:nfc-enabled? false :pin {:original [] diff --git a/src/status_im/ethereum/json_rpc.cljs b/src/status_im/ethereum/json_rpc.cljs index 44e968a52b..611a7f728e 100644 --- a/src/status_im/ethereum/json_rpc.cljs +++ b/src/status_im/ethereum/json_rpc.cljs @@ -242,7 +242,16 @@ "mailservers_getChatRequestRanges" {} "mailservers_deleteChatRequestRange" {} "appmetrics_saveAppMetrics" {} - "appmetrics_getAppMetrics" {}}) + "appmetrics_getAppMetrics" {} + "stickers_market" {} + "stickers_installed" {} + "stickers_install" {} + "stickers_addRecent" {} + "stickers_recent" {} + "stickers_buyPrepareTx" {} + "stickers_processPending" {} + "stickers_addPending" {} + "stickers_pending" {}}) (defn on-error-retry [call-method {:keys [method number-of-retries delay on-error] :as arg}] diff --git a/src/status_im/multiaccounts/login/core.cljs b/src/status_im/multiaccounts/login/core.cljs index f1ce3f2d49..a78f9250f2 100644 --- a/src/status_im/multiaccounts/login/core.cljs +++ b/src/status_im/multiaccounts/login/core.cljs @@ -18,7 +18,6 @@ [status-im.popover.core :as popover] [status-im.communities.core :as communities] [status-im.transport.core :as transport] - [status-im.stickers.core :as stickers] [status-im.mobile-sync-settings.core :as mobile-network] [status-im.utils.fx :as fx] [status-im.utils.keychain.core :as keychain] @@ -445,7 +444,6 @@ (initialize-transactions-management-enabled) (check-network-version network-id) (contact/initialize-contacts) - (stickers/init-stickers-packs) (initialize-browser) (mobile-network/on-network-status-change) (get-group-chat-invitations) diff --git a/src/status_im/stickers/core.cljs b/src/status_im/stickers/core.cljs index 1713c11490..02d9cb25d3 100644 --- a/src/status_im/stickers/core.cljs +++ b/src/status_im/stickers/core.cljs @@ -1,24 +1,13 @@ (ns status-im.stickers.core - (:require [cljs.reader :as edn] - [clojure.set :as clojure.set] - [clojure.string :as string] + (:require [clojure.string :as string] [re-frame.core :as re-frame] - [status-im.ethereum.abi-spec :as abi-spec] - [status-im.ethereum.contracts :as contracts] [status-im.ethereum.core :as ethereum] [status-im.ethereum.json-rpc :as json-rpc] [status-im.navigation :as navigation] - [status-im.multiaccounts.update.core :as multiaccounts.update] - [status-im.signing.core :as signing] - [status-im.utils.contenthash :as contenthash] [status-im.utils.fx :as fx] - [status-im.utils.utils :as utils])) - -(defn pack-data-callback - [id] - (fn [[_ _ _ _ price contenthash]] - (when-let [url (contenthash/url contenthash)] - (re-frame/dispatch [:stickers/load-pack url id price])))) + [status-im.utils.utils :as utils] + [status-im.utils.config :as config] + [status-im.constants :as constants])) (re-frame/reg-fx :stickers/set-pending-timeout-fx @@ -26,193 +15,109 @@ (utils/set-timeout #(re-frame/dispatch [:stickers/pending-timeout]) 10000))) -(defn eth-call-pack-data - [contract id] - (json-rpc/eth-call - {:contract contract - ;; Returns vector of pack data parameters by pack id: - ;; [category owner mintable timestamp price contenthash] - :method "getPackData(uint256)" - :params [id] - :outputs ["bytes4[]" "address" "bool" "uint256" "uint256" "bytes"] - :on-success (pack-data-callback id)})) - -(re-frame/reg-fx - :stickers/pack-data-fx - (fn [[contract id]] - (eth-call-pack-data contract id))) - -(re-frame/reg-fx - :stickers/load-packs-fx - (fn [[contract]] - (json-rpc/eth-call - {:contract contract - ;; Returns number of packs registered in the contract - :method "packCount()" - :outputs ["uint256"] - :on-success - (fn [[count]] - (dotimes [id count] - (eth-call-pack-data contract id)))}))) - -(re-frame/reg-fx - :stickers/owned-packs-fx - (fn [[contract address]] - (json-rpc/eth-call - {:contract contract - ;; Returns vector of owned tokens ids in the contract by address - :method "balanceOf(address)" - :params [address] - :outputs ["uint256"] - :number-of-retries 3 - :on-success - (fn [[count]] - (dotimes [id count] - (json-rpc/eth-call - {:contract contract - ;; Returns pack id in the contract by token id - :method "tokenOfOwnerByIndex(address,uint256)" - :params [address id] - :outputs ["uint256"] - :number-of-retries 3 - :on-success - (fn [[token-id]] - (json-rpc/eth-call - {:contract contract - ;; Returns pack id in the contract by token id - :method "tokenPackId(uint256)" - :params [token-id] - :outputs ["uint256"] - :number-of-retries 3 - :on-success - (fn [[pack-id]] - (re-frame/dispatch [:stickers/pack-owned pack-id]))}))})))}))) - -(fx/defn init-stickers-packs - [{:keys [db] :as cofx}] - (let [sticker-packs (get-in db [:multiaccount :stickers/packs-installed]) - pending-packs (get-in db [:multiaccount :stickers/packs-pending] #{})] - (cond-> {:db (assoc db - :stickers/packs-installed sticker-packs - :stickers/packs sticker-packs - :stickers/packs-pending pending-packs)} - (not-empty pending-packs) - (assoc :stickers/set-pending-timeout-fx nil)))) - (fx/defn install-stickers-pack {:events [:stickers/install-pack]} - [{{:keys [multiaccount] :as db} :db :as cofx} id] - (let [pack (get-in db [:stickers/packs id])] - (fx/merge - cofx - {:db (-> db - (assoc-in [:stickers/packs-installed id] pack))} - ;;(assoc :stickers/selected-pack id))} TODO it doesn't scroll to selected pack on Android - (multiaccounts.update/multiaccount-update - :stickers/packs-installed - (assoc (:stickers/packs-installed multiaccount) id pack) - {})))) - -(defn valid-sticker? [sticker] - (contains? sticker :hash)) - -(fx/defn load-sticker-pack-success - {:events [:stickers/load-sticker-pack-success]} - [{:keys [db] :as cofx} edn-string id price] - (let [{:keys [stickers] :as pack} (assoc (get (edn/read-string edn-string) 'meta) - :id id :price price)] - (fx/merge cofx - {:db (cond-> db - (and (seq stickers) - (every? valid-sticker? stickers)) - (assoc-in [:stickers/packs id] pack))}))) - -(fx/defn open-sticker-pack - {:events [:stickers/open-sticker-pack]} - [{{:stickers/keys [packs packs-installed] :networks/keys [current-network] :as db} :db :as cofx} id] - (when (and id (string/starts-with? current-network "mainnet")) - (let [pack (or (get packs-installed id) - (get packs id)) - contract-address (contracts/get-address db :status/stickers) - pack-contract (contracts/get-address db :status/sticker-pack) - address (ethereum/default-address db)] - (fx/merge cofx - (navigation/open-modal :stickers-pack {:id id}) - #(when (and contract-address (not pack)) - {:stickers/pack-data-fx [contract-address id] - :stickers/owned-packs-fx [pack-contract address]}))))) - -(fx/defn load-pack - {:events [:stickers/load-pack]} - [_ url id price] - {:http-get {:url url - :on-success - (fn [o] - (re-frame/dispatch [:stickers/load-sticker-pack-success o id price]))}}) + [{db :db :as cofx} id] + (fx/merge + cofx + {:db (assoc-in db [:stickers/packs id :status] constants/sticker-pack-status-installed) + ::json-rpc/call [{:method "stickers_install" + :params [(ethereum/chain-id db) id] + :on-success #()}]})) (fx/defn load-packs {:events [:stickers/load-packs]} [{:keys [db]}] - (let [contract (contracts/get-address db :status/stickers) - pack-contract (contracts/get-address db :status/sticker-pack) - address (ethereum/default-address db)] - (when contract - {:stickers/owned-packs-fx [pack-contract address] - :stickers/load-packs-fx [contract]}))) + {::json-rpc/call [{:method "stickers_market" + :params [(ethereum/chain-id db)] + :on-success #(re-frame/dispatch [:stickers/stickers-market-success %])} + {:method "stickers_installed" + :params [] + :on-success #(re-frame/dispatch [:stickers/stickers-installed-success %])} + {:method "stickers_pending" + :params [] + :on-success #(re-frame/dispatch [:stickers/stickers-pending-success %])} + {:method "stickers_recent" + :params [] + :on-success #(re-frame/dispatch [:stickers/stickers-recent-success %])}]}) -(fx/defn approve-pack +(fx/defn buy-pack {:events [:stickers/buy-pack]} - [{db :db :as cofx} pack-id price] - (let [address (ethereum/default-address db) - sticker-market-contract (contracts/get-address db :status/sticker-market) - snt-contract (contracts/get-address db :status/snt)] - (signing/eth-transaction-call - cofx - {:contract snt-contract - :method "approveAndCall(address,uint256,bytes)" - :params [sticker-market-contract - price - (abi-spec/encode "buyToken(uint256,address,uint256)" [pack-id address price])] - :on-result [:stickers/pending-pack pack-id]}))) + [{db :db} pack-id] + {::json-rpc/call [{:method "stickers_buyPrepareTx" + :params [(ethereum/chain-id db) (ethereum/default-address db) (int pack-id)] + :on-success #(re-frame/dispatch [:signing.ui/sign + {:tx-obj % + :on-result [:stickers/pending-pack pack-id]}])}]}) (fx/defn pending-pack {:events [:stickers/pending-pack]} - [{{:keys [multiaccount] :as db} :db :as cofx} id] - (let [contract (contracts/get-address db :status/sticker-pack) - address (ethereum/default-address db) - pending (get multiaccount :stickers/packs-pending #{})] - (when contract - (fx/merge cofx - {:db (update db :stickers/packs-pending conj id) - :stickers/owned-packs-fx [contract address]} - (multiaccounts.update/multiaccount-update - :stickers/packs-pending - (conj pending id) - {}) - #(when (zero? (count (:stickers/packs-pending db))) - {:stickers/set-pending-timeout-fx nil}))))) + [{db :db} id] + {:db (-> db + (assoc-in [:stickers/packs id :status] constants/sticker-pack-status-pending) + (update :stickers/packs-pending conj id)) + :stickers/set-pending-timeout-fx nil + ::json-rpc/call [{:method "stickers_addPending" + :params [(ethereum/chain-id db) (int id)] + :on-success #()}]}) (fx/defn pending-timeout {:events [:stickers/pending-timeout]} - [{{:stickers/keys [packs-pending packs-owned] :as db} :db :as cofx}] - (let [packs-diff (clojure.set/difference packs-pending packs-owned) - contract (contracts/get-address db :status/sticker-pack) - address (ethereum/default-address db)] - (when contract - (fx/merge cofx - (merge {:db (assoc db :stickers/packs-pending packs-diff)} - (when-not (zero? (count packs-diff)) - {:stickers/owned-packs-fx [contract address] - :stickers/set-pending-timeout-fx nil})) - (multiaccounts.update/multiaccount-update - :stickers/packs-pending - packs-diff - {}))))) + [{{:stickers/keys [packs-pending] :as db} :db}] + (when (seq packs-pending) + {::json-rpc/call [{:method "stickers_processPending" + :params [(ethereum/chain-id db)] + :on-success #(re-frame/dispatch [:stickers/stickers-process-pending-success %])}]})) -(fx/defn pack-owned - {:events [:stickers/pack-owned]} - [{db :db} id] - {:db (update db :stickers/packs-owned conj id)}) +(fx/defn stickers-process-pending-success + {:events [:stickers/stickers-process-pending-success]} + [{{:stickers/keys [packs-pending packs] :as db} :db} purchased] + (let [purchased-ids (map :id (vals purchased)) + packs-pending (apply disj packs-pending purchased-ids) + packs (reduce (fn [packs id] + (assoc-in packs [id :status] constants/sticker-pack-status-owned)) + packs + purchased-ids)] + (merge + {:db (-> db + (assoc :stickers/packs packs) + (assoc :stickers/packs-pending packs-pending))} + (when (seq packs-pending) + {:stickers/set-pending-timeout-fx nil})))) + +(fx/defn stickers-market-success + {:events [:stickers/stickers-market-success]} + [{:keys [db]} packs] + (let [packs (reduce (fn [acc pack] (assoc acc (:id pack) pack)) {} packs)] + {:db (update db :stickers/packs merge packs)})) + +(fx/defn stickers-installed-success + {:events [:stickers/stickers-installed-success]} + [{:keys [db]} packs] + (let [packs (reduce (fn [acc [_ pack]] (assoc acc (:id pack) pack)) {} packs)] + {:db (update db :stickers/packs merge packs)})) + +(fx/defn stickers-pending-success + {:events [:stickers/stickers-pending-success]} + [{:keys [db]} packs] + (let [packs (reduce (fn [acc [_ pack]] (assoc acc (:id pack) pack)) {} packs)] + (merge + {:db (-> db + (assoc :stickers/packs-pending (into #{} (keys packs))) + (update :stickers/packs merge packs))} + (when (seq packs) + {:stickers/set-pending-timeout-fx nil})))) + +(fx/defn stickers-recent-success + {:events [:stickers/stickers-recent-success]} + [{:keys [db]} packs] + {:db (assoc db :stickers/recent-stickers packs)}) + +(fx/defn open-sticker-pack + {:events [:stickers/open-sticker-pack]} + [{{:networks/keys [current-network]} :db :as cofx} id] + (when (and id (or config/stickers-test-enabled? (string/starts-with? current-network "mainnet"))) + (navigation/open-modal cofx :stickers-pack {:id id}))) (fx/defn select-pack {:events [:stickers/select-pack]} diff --git a/src/status_im/stickers/core_test.cljs b/src/status_im/stickers/core_test.cljs deleted file mode 100644 index 7e04bd957e..0000000000 --- a/src/status_im/stickers/core_test.cljs +++ /dev/null @@ -1,7 +0,0 @@ -(ns status-im.stickers.core-test - (:require [cljs.test :refer-macros [deftest is]] - [status-im.stickers.core :as stickers])) - -(deftest valid-sticker? - (is (true? (stickers/valid-sticker? {:hash ""}))) - (is (false? (stickers/valid-sticker? {})))) diff --git a/src/status_im/subs.cljs b/src/status_im/subs.cljs index 202f1cc110..7e93ea9a96 100644 --- a/src/status_im/subs.cljs +++ b/src/status_im/subs.cljs @@ -136,9 +136,7 @@ ;;stickers (reg-root-key-sub :stickers/selected-pack :stickers/selected-pack) (reg-root-key-sub :stickers/packs :stickers/packs) -(reg-root-key-sub :stickers/installed-packs :stickers/packs-installed) -(reg-root-key-sub :stickers/packs-owned :stickers/packs-owned) -(reg-root-key-sub :stickers/packs-pending :stickers/packs-pending) +(reg-root-key-sub :stickers/recent-stickers :stickers/recent-stickers) ;;mailserver (reg-root-key-sub :mailserver/current-id :mailserver/current-id) @@ -1336,7 +1334,7 @@ (fn [[{:keys [processing]} sending-image mainnet? one-to-one-chat? {:keys [public?]} reply edit]] (let [sending-image (seq sending-image)] {:send (not processing) - :stickers (and mainnet? + :stickers (and (or config/stickers-test-enabled? mainnet?) (not sending-image) (not reply)) :image (and (not reply) @@ -1515,23 +1513,20 @@ ;;STICKERS ============================================================================================================= (re-frame/reg-sub - :stickers/installed-packs-vals - :<- [:stickers/installed-packs] + :stickers/installed-packs + :<- [:stickers/packs] (fn [packs] - (vals packs))) + (filter #(= (:status %) constants/sticker-pack-status-installed) (vals packs)))) (re-frame/reg-sub :stickers/all-packs :<- [:stickers/packs] - :<- [:stickers/installed-packs] - :<- [:stickers/packs-owned] - :<- [:stickers/packs-pending] - (fn [[packs installed owned pending]] - (map (fn [{:keys [id] :as pack}] - (cond-> pack - (get installed id) (assoc :installed true) - (get owned id) (assoc :owned true) - (get pending id) (assoc :pending true))) + (fn [packs] + (map (fn [{:keys [status] :as pack}] + (-> pack + (assoc :installed (= status constants/sticker-pack-status-installed)) + (assoc :pending (= status constants/sticker-pack-status-pending)) + (assoc :owned (= status constants/sticker-pack-status-owned)))) (vals packs)))) (re-frame/reg-sub @@ -1541,19 +1536,6 @@ (fn [[{:keys [id]} packs]] (first (filter #(= (:id %) id) packs)))) -(defn find-pack-id-for-hash [sticker-uri packs] - (some (fn [{:keys [stickers id]}] - (when (some #(= sticker-uri (:hash %)) stickers) - id)) - packs)) - -(re-frame/reg-sub - :stickers/recent - :<- [:multiaccount] - :<- [:stickers/installed-packs-vals] - (fn [[{:keys [:stickers/recent-stickers]} packs]] - (map (fn [hash] {:hash hash :pack (find-pack-id-for-hash hash packs)}) recent-stickers))) - ;;HOME ============================================================================================================== (def memo-home-items (atom nil)) diff --git a/src/status_im/transport/core.cljs b/src/status_im/transport/core.cljs index 6ee0cf304e..2c6bb15da0 100644 --- a/src/status_im/transport/core.cljs +++ b/src/status_im/transport/core.cljs @@ -8,7 +8,8 @@ [status-im.utils.handlers :as handlers] status-im.transport.shh [taoensso.timbre :as log] - [status-im.utils.universal-links.core :as universal-links])) + [status-im.utils.universal-links.core :as universal-links] + [status-im.stickers.core :as stickers])) (fx/defn set-node-info {:events [:transport.callback/node-info-fetched]} @@ -65,4 +66,5 @@ (add-mailservers mailservers))} (fetch-node-info-fx) (pairing/init) + (stickers/load-packs) (universal-links/process-stored-event))) diff --git a/src/status_im/ui/screens/browser/views.cljs b/src/status_im/ui/screens/browser/views.cljs index d9e7896e2d..486ade4f36 100644 --- a/src/status_im/ui/screens/browser/views.cljs +++ b/src/status_im/ui/screens/browser/views.cljs @@ -18,7 +18,6 @@ [status-im.utils.debounce :as debounce] [status-im.utils.http :as http] [status-im.utils.js-resources :as js-res] - [status-im.utils.contenthash :as contenthash] [status-im.ui.components.permissions :as components.permissions] [quo.core :as quo] [status-im.ui.screens.wallet.components.views :as components] @@ -58,8 +57,7 @@ (reagent/as-element [react/view styles/web-view-error [react/image {:style {:width 140 :height 140 :margin-bottom 16} - :source {:uri (contenthash/url - "e3010170122001bbe2f5bfba0305a3bdc2047fddc47ee595a591bdee61de6040ffc2456624e1")}}] + :source {:uri "https://bafybeiabxprplp52amc2hpocar753rd64wk2len55zq54yca77bekzre4e.ipfs.cf-ipfs.com"}}] [react/i18n-text {:style styles/web-view-error-text :key :web-view-error}] [react/text {:style styles/web-view-error-text} (str desc)]])) diff --git a/src/status_im/ui/screens/chat/message/message.cljs b/src/status_im/ui/screens/chat/message/message.cljs index 7107ecc218..dfa78ff68c 100644 --- a/src/status_im/ui/screens/chat/message/message.cljs +++ b/src/status_im/ui/screens/chat/message/message.cljs @@ -14,7 +14,6 @@ [status-im.ui.screens.chat.message.gap :as message.gap] [status-im.ui.screens.chat.styles.message.message :as style] [status-im.ui.screens.chat.utils :as chat.utils] - [status-im.utils.contenthash :as contenthash] [status-im.utils.security :as security] [status-im.ui.screens.chat.message.reactions :as reactions] [status-im.ui.screens.chat.image.preview.views :as preview] @@ -558,7 +557,7 @@ :accessibility-label :sticker-message :on-press (fn [_] (when pack - (re-frame/dispatch [:stickers/open-sticker-pack pack])) + (re-frame/dispatch [:stickers/open-sticker-pack (str pack)])) (react/dismiss-keyboard!)) :delay-long-press 100 :on-long-press (fn [] @@ -568,8 +567,7 @@ (re-frame/dispatch [:chat.ui/show-profile from])) :label (i18n/label :t/view-details)}])))}) [react/fast-image {:style {:margin 10 :width 140 :height 140} - ;;TODO (perf) move to event - :source {:uri (contenthash/url (-> content :sticker :hash))}}]] + :source {:uri (str (-> content :sticker :url) "&download=true")}}]] reaction-picker])) (defmethod ->message constants/content-type-image diff --git a/src/status_im/ui/screens/chat/stickers/views.cljs b/src/status_im/ui/screens/chat/stickers/views.cljs index d46828b268..c522525f89 100644 --- a/src/status_im/ui/screens/chat/stickers/views.cljs +++ b/src/status_im/ui/screens/chat/stickers/views.cljs @@ -2,14 +2,12 @@ (:require-macros [status-im.utils.views :refer [defview letsubs]]) (:require [re-frame.core :as re-frame] [reagent.core :as reagent] - [status-im.stickers.core :as stickers] [status-im.ui.components.react :as react] [status-im.ui.components.icons.icons :as icons] [quo.design-system.colors :as colors] [status-im.i18n.i18n :as i18n] [quo.core :as quo] [status-im.ui.screens.chat.stickers.styles :as styles] - [status-im.utils.contenthash :as contenthash] [status-im.utils.debounce :as debounce])) (def icon-size 28) @@ -26,25 +24,23 @@ :height 64}] [react/text {:style {:margin-vertical 8 :font-size 17}} (i18n/label :t/you-dont-have-stickers)] [quo/button {:type :secondary - :on-press #(do - (re-frame/dispatch [:stickers/load-packs]) - (re-frame/dispatch [:navigate-to :stickers]))} + :on-press #(re-frame/dispatch [:navigate-to :stickers])} (i18n/label :t/get-stickers)]]) (defn- stickers-panel [stickers window-width] [react/view {:width window-width :flex 1} [react/scroll-view [react/view {:style styles/stickers-panel} - (for [{:keys [hash] :as sticker} stickers] - ^{:key (str hash)} + (for [{:keys [url] :as sticker} stickers] + ^{:key (str url)} [react/touchable-highlight {:style {:height 75 :width 75 :margin 5} :on-press #(debounce/dispatch-and-chill [:chat/send-sticker sticker] 1000)} [react/fast-image {:style {:width "100%" :height "100%"} :accessibility-label :sticker-icon - :source {:uri (contenthash/url (str "0x" hash))}}]])]]]) + :source {:uri (str url "&download=true")}}]])]]]) (defview recent-stickers-panel [window-width] - (letsubs [stickers [:stickers/recent]] + (letsubs [stickers [:stickers/recent-stickers]] (if (seq stickers) [stickers-panel stickers window-width] [react/view {:style {:flex 1 @@ -98,7 +94,7 @@ [recent-stickers-panel width] (for [{:keys [stickers id]} installed-packs] ^{:key (str "sticker" id)} - [stickers-panel (map #(assoc % :pack id) (filter stickers/valid-sticker? stickers)) width])])) + [stickers-panel (map #(assoc % :pack id) stickers) width])])) (defn pack-icon [{:keys [id on-press background-color] :or {on-press #(re-frame/dispatch [:stickers/select-pack id])}} @@ -118,7 +114,7 @@ (defview stickers-view [] (letsubs [selected-pack [:stickers/selected-pack] - installed-packs [:stickers/installed-packs-vals]] + installed-packs [:stickers/installed-packs]] [react/view {:style {:background-color colors/white :flex 1}} (cond @@ -126,9 +122,7 @@ (not (seq installed-packs)) [no-stickers-yet-panel] :else [stickers-paging-panel installed-packs selected-pack]) [react/view {:style {:flex-direction :row :padding-horizontal 4}} - [pack-icon {:on-press #(do - (re-frame/dispatch [:stickers/load-packs]) - (re-frame/dispatch [:navigate-to :stickers])) + [pack-icon {:on-press #(re-frame/dispatch [:navigate-to :stickers]) :selected? false :background-color colors/blue} [icons/icon :main-icons/add {:width 20 :height 20 :color colors/white-persist}]] [react/view {:width 2}] @@ -140,9 +134,9 @@ :width 44 :height 44}]] (for [{:keys [id thumbnail]} installed-packs] - ^{:key id} + ^{:key (str "pack-icon" id)} [pack-icon {:id id :background-color colors/white} [react/fast-image {:style {:width icon-size :height icon-size :border-radius (/ icon-size 2)} - :source {:uri (contenthash/url thumbnail)}}]])] + :source {:uri (str thumbnail "&download=true")}}]])] [scroll-indicator]]]]])) diff --git a/src/status_im/ui/screens/status/views.cljs b/src/status_im/ui/screens/status/views.cljs index 0787c50e5c..498f2e5555 100644 --- a/src/status_im/ui/screens/status/views.cljs +++ b/src/status_im/ui/screens/status/views.cljs @@ -15,7 +15,6 @@ [status-im.ui.screens.chat.image.preview.views :as preview] [status-im.ui.screens.chat.photos :as photos] [status-im.ui.components.tabs :as tabs] - [status-im.utils.contenthash :as contenthash] [status-im.ui.screens.chat.message.reactions :as reactions] [status-im.chat.models.reactions :as models.reactions] [status-im.ui.screens.chat.components.reply :as components.reply] @@ -175,8 +174,6 @@ [tabs/tab-title state :timeline (i18n/label :t/timeline) (= tab :timeline)] [tabs/tab-title state :status (i18n/label :t/my-status) (= tab :status)]])) -(def image-hash "e3010170122080c27fe972a95dbb4b0ead029d2c73d18610e849fac197e91068a918755e21b2") - (defn timeline [] (let [messages @(re-frame/subscribe [:chats/timeline-messages-stream]) loading-messages? @(re-frame/subscribe [:chats/loading-messages? constants/timeline-chat-id]) @@ -191,10 +188,10 @@ (if no-messages? [react/view {:padding-horizontal 32 :margin-top 64} - [react/image {:style {:width 140 - :height 140 - :align-self :center} - :source {:uri (contenthash/url image-hash)}}] + [react/fast-image {:style {:width 140 + :height 140 + :align-self :center} + :source {:uri "https://bafybeieayj76s4vjlw5uwdvnakosy46rqyioqsp2ygl6sedivemhkxrbwi.ipfs.cf-ipfs.com"}}] [react/view (styles/descr-container) [react/text {:style {:color colors/gray :line-height 22}} diff --git a/src/status_im/ui/screens/stickers/views.cljs b/src/status_im/ui/screens/stickers/views.cljs index d4d9156478..fd70c385a8 100644 --- a/src/status_im/ui/screens/stickers/views.cljs +++ b/src/status_im/ui/screens/stickers/views.cljs @@ -5,54 +5,56 @@ [status-im.ui.components.icons.icons :as icons] [status-im.ui.components.react :as react] [status-im.ui.screens.stickers.styles :as styles] - [status-im.utils.contenthash :as contenthash] - [status-im.utils.money :as money]) + [status-im.utils.money :as money] + [status-im.utils.handlers :refer [ :eth price)))])]]))))) -(defview price-badge [price id owned? pending] - (letsubs [chain [:ethereum/chain-keyword] - balance [:balance-default]] - (let [snt (money/to-number (if (= :mainnet chain) (:SNT balance) (:STT balance))) - not-enough-snt? (> price snt) - no-snt? (or (nil? snt) (zero? snt))] - [react/touchable-highlight {:on-press #(cond pending nil - (or owned? (zero? price)) - (re-frame/dispatch [:stickers/install-pack id]) - (or no-snt? not-enough-snt?) nil - :else (re-frame/dispatch [:stickers/buy-pack id price]))} - [react/view (styles/price-badge (and (not (or owned? (zero? price))) (or no-snt? not-enough-snt?))) - (when (and (not (zero? price)) (not owned?)) - [icons/tiny-icon :tiny-icons/tiny-snt {:color colors/white-persist :container-style {:margin-right 6}}]) - (if pending - [react/activity-indicator {:animating true - :color colors/white-persist}] - [react/text {:style {:color colors/white-persist} - :accessibility-label :sticker-pack-price} - (cond owned? (i18n/label :t/install) - (zero? price) (i18n/label :t/free) - :else (str (money/wei-> :eth price)))])]]))) - -(defn pack-badge [{:keys [name author price thumbnail preview id installed owned pending]}] +(defn pack-badge [{:keys [name author thumbnail preview id] :as pack}] [react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :stickers-pack {:id id}])} [react/view {:margin-bottom 27} - [react/fast-image {:style {:height 200 :border-radius 20} :source {:uri (contenthash/url preview)}}] + [react/fast-image {:style {:height 200 :border-radius 20} :source {:uri (cache preview)}}] [react/view {:height 64 :align-items :center :flex-direction :row} - [thumbnail-icon (contenthash/url thumbnail) 40] + [thumbnail-icon thumbnail 40] [react/view {:padding-horizontal 16 :flex 1} [react/text {:accessibility-label :sticker-pack-name} name] - [react/text {:style {:color colors/gray :margin-top 6} + [react/text {:style {:color colors/gray :margin-top 6} :accessibility-label :sticker-pack-author} author]] - (if installed - [installed-icon] - [price-badge price id owned pending])]]]) + [price-badge pack]]]]) (defview packs [] (letsubs [packs [:stickers/all-packs]] @@ -70,28 +72,25 @@ (def sticker-icon-size 60) (defview pack-main [] - (letsubs [{:keys [id name author price thumbnail - stickers installed owned pending] - :as pack} + (letsubs [{:keys [name author thumbnail stickers] + :as pack} [:stickers/get-current-pack]] [react/keyboard-avoiding-view {:flex 1} (if pack [react/view {:flex 1} [react/view {:height 74 :align-items :center :flex-direction :row :padding-horizontal 16} - [thumbnail-icon (contenthash/url thumbnail) 64] + [thumbnail-icon thumbnail 64] [react/view {:padding-horizontal 16 :flex 1} [react/text {:style {:typography :header}} name] [react/text {:style {:color colors/gray :margin-top 6}} author]] - (if installed - [installed-icon] - [price-badge price id owned pending])] + [price-badge pack]] [react/view {:style {:padding-top 8 :flex 1}} [react/scroll-view {:keyboard-should-persist-taps :handled :style {:flex 1}} [react/view {:flex-direction :row :flex-wrap :wrap} - (for [{:keys [hash]} stickers] - ^{:key hash} - [react/fast-image {:style (styles/sticker-image sticker-icon-size) - :source {:uri (contenthash/url hash)}}])]]]] + (for [{:keys [url]} stickers] + ^{:key url} + [react/fast-image {:style (styles/sticker-image sticker-icon-size) + :source {:uri (cache url)}}])]]]] [react/view {:flex 1 :align-items :center :justify-content :center} [react/activity-indicator {:animating true}]])])) diff --git a/src/status_im/utils/config.cljs b/src/status_im/utils/config.cljs index 0a74ebad05..af3f4ec7e5 100644 --- a/src/status_im/utils/config.cljs +++ b/src/status_im/utils/config.cljs @@ -54,6 +54,7 @@ (def test-stateofus? (enabled? (get-config :TEST_STATEOFUS "0"))) (def two-minutes-syncing? (enabled? (get-config :TWO_MINUTES_SYNCING "0"))) (def swap-enabled? (enabled? (get-config :SWAP_ENABLED "0"))) +(def stickers-test-enabled? (enabled? (get-config :STICKERS_TEST_ENABLED "0"))) ;; CONFIG VALUES (def log-level diff --git a/src/status_im/utils/contenthash.cljs b/src/status_im/utils/contenthash.cljs deleted file mode 100644 index c6eca048be..0000000000 --- a/src/status_im/utils/contenthash.cljs +++ /dev/null @@ -1,48 +0,0 @@ -(ns status-im.utils.contenthash - "TODO: currently we only support encoding/decoding ipfs contenthash - implementing swarm and other protocols will come later" - (:refer-clojure :exclude [cat]) - (:require ["hi-base32" :as hi-base32] - [alphabase.hex :as hex] - [clojure.string :as string] - [status-im.ethereum.core :as ethereum])) - -(defn decode - "TODO properly decode the CID - extract the content-type using varint ns" - [hex] - (when (and hex (not= hex "0x")) - (cond - (and (string/starts-with? hex "0xe40101")) - ;; content type can be 2 or 4 bytes - ;; we expect 1b20 (hash algorithm keccak256 and hash length 64) - ;; before the hash so we split the contenthash there - (when-let [hash (second (string/split hex "1b20"))] - {:namespace :swarm - :hash hash}) - (and (= 78 (count hex)) - (string/starts-with? hex "0xe3010170")) - {:namespace :ipfs - :hash (str "b" (-> hex - (subs 6) - hex/decode - ((fn [v] (.encode ^js hi-base32 v))) - (string/replace #"=" "") - string/lower-case))} - (and (string/starts-with? hex "0xe50101700")) - {:namespace :ipns - :hash (-> hex - (subs 14) - ((fn [v] (str "0x" v))) - (ethereum/hex-to-utf8))}))) - -(defn ipfs-url [hash] - (str "https://" hash ".ipfs.cf-ipfs.com")) - -(defn url-fn [hex] - (let [{:keys [namespace hash]} (decode (ethereum/normalized-hex hex))] - (case namespace - :ipfs (ipfs-url hash) - ""))) - -(def url (memoize url-fn)) diff --git a/src/status_im/utils/contenthash_test.cljs b/src/status_im/utils/contenthash_test.cljs deleted file mode 100644 index 3bf8dcdc66..0000000000 --- a/src/status_im/utils/contenthash_test.cljs +++ /dev/null @@ -1,26 +0,0 @@ -(ns status-im.utils.contenthash-test - (:require [cljs.test :refer-macros [deftest is testing]] - [status-im.utils.contenthash :as contenthash])) - -;; we reuse the exemple from EIP-1577 but omit content type: dag-pb (0x70) -;; in the contenthash as we do not support it yet - -(deftest contenthash-decode - (testing "decoding a valid ipfs hash" - (is (= (contenthash/decode "0xe3010170122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f") - {:namespace :ipfs - :hash "bafybeibj6lixxzqtsb45ysdjnupvqkufgdvzqbnvmhw2kf7cfkesy7r7d4"}))) - (testing "decoding a valid ipns hash" - (is (= (contenthash/decode "0xe5010170000f6170702e756e69737761702e6f7267") - {:namespace :ipns - :hash "app.uniswap.org"}))) - (testing "decoding a valid swarm hash" - (is (= (contenthash/decode "0xe40101fa011b20d1de9994b4d039f6548d191eb26786769f580809256b4685ef316805265ea162") - {:namespace :swarm - :hash "d1de9994b4d039f6548d191eb26786769f580809256b4685ef316805265ea162"}))) - (testing "decoding an invalid ipfs hash" - (is (nil? (contenthash/decode "0xe301122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e2")))) - (testing "decoding random garbage" - (is (nil? (contenthash/decode "0xabcdef1234567890")))) - (testing "decoding nil" - (is (nil? (contenthash/decode nil))))) \ No newline at end of file diff --git a/src/status_im/utils/money.cljs b/src/status_im/utils/money.cljs index 9d9f489aed..eab8163604 100644 --- a/src/status_im/utils/money.cljs +++ b/src/status_im/utils/money.cljs @@ -41,6 +41,10 @@ [bn1 bn2] (.greaterThan ^js bn1 bn2)) +(defn equal-to + [bn1 bn2] + (.eq ^js bn1 bn2)) + (defn sub [bn1 bn2] (.sub ^js bn1 bn2)) diff --git a/status-go-version.json b/status-go-version.json index fe9808017a..f2578c3ed0 100644 --- a/status-go-version.json +++ b/status-go-version.json @@ -3,7 +3,7 @@ "_comment": "Instead use: scripts/update-status-go.sh ", "owner": "status-im", "repo": "status-go", - "version": "v0.98.5", - "commit-sha1": "640793fe85d9a9eef9eb3712cda1c5a1ceea401a", - "src-sha256": "1k1iw69yw23k29y0b1yvnggjqlmfnwavk4mq1sf2h3wrlb8x47kd" + "version": "v0.98.6", + "commit-sha1": "0048aaebcc7859a6f0dd7cdf0266fe029f3066fc", + "src-sha256": "1px3ddfbpnlqyzkbp8v4bb8dh5f69cx4lwif8vspw60rr4gpppys" }