From 2571e44de0cd2be89f4f55ff1ad6a4e34b790669 Mon Sep 17 00:00:00 2001 From: Gheorghe Pinzaru Date: Mon, 7 Dec 2020 15:10:42 +0300 Subject: [PATCH] Referrals add screen with join public-chat Update strings Check if transaction has receipt on login Notification on accept Add large icon Unify notifications for referral Fix duplicate path for acquisition Fix accept notification and visibility Small fixes Do not show notifications when not rewardable Add home item Show referral on lets go button Fix list item on home Hide messages on accept Signed-off-by: Gheorghe Pinzaru --- src/quo/react_native.cljs | 2 +- src/status_im/acquisition/advertiser.cljs | 22 ++-- src/status_im/acquisition/chat.cljs | 48 ++++++-- src/status_im/acquisition/claim.cljs | 31 +++-- src/status_im/acquisition/core.cljs | 6 +- src/status_im/acquisition/notifications.cljs | 33 ++++++ src/status_im/acquisition/persistance.cljs | 3 +- src/status_im/multiaccounts/login/core.cljs | 25 ++-- src/status_im/notifications/core.cljs | 8 +- src/status_im/notifications/local.cljs | 5 +- src/status_im/subs.cljs | 1 + src/status_im/ui/components/invite/chat.cljs | 54 +++++---- .../ui/components/invite/events.cljs | 31 +++-- src/status_im/ui/components/invite/views.cljs | 6 +- .../ui/screens/chat/toolbar_content.cljs | 49 ++++---- src/status_im/ui/screens/chat/views.cljs | 2 +- src/status_im/ui/screens/home/views.cljs | 10 +- .../ui/screens/referrals/home_item.cljs | 60 ++++++++++ .../ui/screens/referrals/public_chat.cljs | 109 ++++++++++++++++++ .../ui/screens/routing/chat_stack.cljs | 3 + src/status_im/wallet/db_test.cljs | 2 +- translations/en.json | 7 ++ 22 files changed, 406 insertions(+), 111 deletions(-) create mode 100644 src/status_im/acquisition/notifications.cljs create mode 100644 src/status_im/ui/screens/referrals/home_item.cljs create mode 100644 src/status_im/ui/screens/referrals/public_chat.cljs diff --git a/src/quo/react_native.cljs b/src/quo/react_native.cljs index 3733e6fba2..1759e0f0f6 100644 --- a/src/quo/react_native.cljs +++ b/src/quo/react_native.cljs @@ -92,7 +92,7 @@ (defn- wrap-render-fn [f] (fn [data] - (reagent/as-element (f (.-item ^js data) (.-index ^js data) (.-separators ^js data))))) + (reagent/as-element [f (.-item ^js data) (.-index ^js data) (.-separators ^js data)]))) (defn- wrap-key-fn [f] (fn [data index] diff --git a/src/status_im/acquisition/advertiser.cljs b/src/status_im/acquisition/advertiser.cljs index a2c5bd505e..ac6d099d38 100644 --- a/src/status_im/acquisition/advertiser.cljs +++ b/src/status_im/acquisition/advertiser.cljs @@ -4,6 +4,7 @@ [status-im.ethereum.core :as ethereum] [status-im.acquisition.gateway :as gateway] [status-im.acquisition.claim :as claim] + [status-im.acquisition.notifications :as notifications] [status-im.acquisition.persistance :as persistence])) (fx/defn start-acquisition @@ -15,15 +16,20 @@ (fx/defn advertiser-decide {:events [::decision]} [{:keys [db] :as cofx} decision] - (let [referral (get-in db [:acquisition :referrer]) - payload {:chat_key (get-in db [:multiaccount :public-key]) - :address (ethereum/default-address db) - :invite_code referral}] + (let [referral (get-in db [:acquisition :referrer]) + {:keys [rewardable]} (get-in db [:acquisition :metadata]) + payload {:chat_key (get-in db [:multiaccount :public-key]) + :address (ethereum/default-address db) + :invite_code referral}] (fx/merge cofx (if (= decision :accept) - (gateway/handle-acquisition {:message payload - :method "PATCH" - :url [:clicks referral] - :on-success [::claim/success-starter-pack-claim]}) + (fn [cofx] + (fx/merge cofx + (when rewardable + (notifications/accept)) + (gateway/handle-acquisition {:message payload + :method "PATCH" + :url [:clicks referral] + :on-success [::claim/success-starter-pack-claim]}))) {::persistence/set-referrer-state :declined}) (popover/hide-popover)))) diff --git a/src/status_im/acquisition/chat.cljs b/src/status_im/acquisition/chat.cljs index c515b7679d..80e6e99906 100644 --- a/src/status_im/acquisition/chat.cljs +++ b/src/status_im/acquisition/chat.cljs @@ -4,35 +4,63 @@ [status-im.acquisition.claim :as claim] [status-im.ethereum.core :as ethereum] [status-im.acquisition.persistance :as persistence] + [status-im.acquisition.notifications :as notifications] [status-im.acquisition.gateway :as gateway] - [status-im.chat.models :as chat])) + [status-im.chat.models :as chat] + [status-im.navigation :as navigation] + [status-im.ui.components.bottom-sheet.core :as bottom-sheet])) + +(def public-chat "public-chat") (fx/defn start-acquisition [{:keys [db]} {:keys [key id] :as referrer} public] {:db (assoc-in db [:acquisition :chat-referrer (or key id)] referrer) ::persistence/chat-initialized? (fn [state] (when-not (= "initialized" state) - (re-frame/dispatch [::start-chat referrer public])))}) + (if public + (re-frame/dispatch [::start-public-chat referrer public]) + (re-frame/dispatch [::start-chat referrer public]))))}) (fx/defn start-chat {:events [::start-chat]} [cofx {:keys [key id]} public] (fx/merge cofx {::persistence/chat-initalized! true} - (if public - (chat/start-public-chat id nil) - (chat/start-chat key)))) + (chat/start-chat key))) + +(fx/defn start-public-chat + {:events [::start-public-chat]} + [cofx referrer chat-name] + (fx/merge cofx + {::persistence/chat-initalized! true} + (navigation/navigate-to :tabs {:screen :chat-stack + :params {:screen :referral-enclav}}))) + +(fx/defn join-public-chat + [cofx chat-name] + (chat/start-public-chat cofx chat-name nil)) (fx/defn accept-pack {:events [::accept-pack]} [{:keys [db] :as cofx}] - (let [referral (get-in db [:acquisition :referrer]) - payload {:chat_key (get-in db [:multiaccount :public-key]) - :address (ethereum/default-address db) - :invite_code referral}] + (let [referral (get-in db [:acquisition :referrer]) + {:keys [type id rewardable]} (get-in db [:acquisition :metadata]) + payload {:chat_key (get-in db [:multiaccount :public-key]) + :address (ethereum/default-address db) + :invite_code referral}] (fx/merge cofx - {:db (update db :acquisition dissoc :chat-referrer)} + (when rewardable + (notifications/accept)) + (when (= type public-chat) + (join-public-chat id)) (gateway/handle-acquisition {:message payload :method "PATCH" :url [:clicks referral] :on-success [::claim/success-starter-pack-claim]})))) + +(fx/defn decline + {:events [::decline]} + [cofx] + (fx/merge cofx + {::persistence/set-referrer-state :declined} + (bottom-sheet/hide-bottom-sheet))) diff --git a/src/status_im/acquisition/claim.cljs b/src/status_im/acquisition/claim.cljs index f5910d1e91..10e14256e9 100644 --- a/src/status_im/acquisition/claim.cljs +++ b/src/status_im/acquisition/claim.cljs @@ -1,16 +1,17 @@ (ns status-im.acquisition.claim - (:require [status-im.i18n :as i18n] - [status-im.utils.fx :as fx] + (:require [status-im.utils.fx :as fx] [status-im.ethereum.transactions.core :as transaction] - [status-im.notifications.core :as notifications] - [status-im.acquisition.persistance :as persistence])) + [status-im.acquisition.notifications :as notifications] + [status-im.acquisition.persistance :as persistence] + [status-im.ethereum.json-rpc :as json-rpc] + [re-frame.core :as re-frame])) (fx/defn success-tx-received {:events [::success-tx-received]} - [_] - {::persistence/set-referrer-state :claimed - ::notifications/local-notification {:title (i18n/label :t/starter-pack-received) - :message (i18n/label :t/starter-pack-received-description)}}) + [cofx] + (fx/merge cofx + (notifications/claimed) + {::persistence/set-referrer-state :claimed})) (fx/defn add-tx-watcher {:events [::add-tx-watcher]} @@ -23,11 +24,21 @@ (fn [] {:dispatch [::success-tx-received]})}))) +(fx/defn check-transaction-receipt + {:events [::check-transaction-receipt]} + [cofx tx] + (when tx + {::json-rpc/call [{:method "eth_getTransactionReceipt" + :params [tx] + :on-success (fn [receipt] + (if receipt + (re-frame/dispatch [::success-tx-received]) + (re-frame/dispatch [::add-tx-watcher tx])))}]})) + (fx/defn success-starter-pack-claim {:events [::success-starter-pack-claim]} [cofx {:keys [tx]}] (fx/merge cofx {::persistence/set-referrer-state (if tx :accepted :claimed)} (when tx - (add-tx-watcher tx)) - (notifications/request-permission))) + (add-tx-watcher tx)))) diff --git a/src/status_im/acquisition/core.cljs b/src/status_im/acquisition/core.cljs index a9fb8b0d35..5e766d3b6e 100644 --- a/src/status_im/acquisition/core.cljs +++ b/src/status_im/acquisition/core.cljs @@ -5,6 +5,7 @@ [status-im.ethereum.core :as ethereum] [status-im.ethereum.ens :as ens] [status-im.ethereum.contracts :as contracts] + [status-im.acquisition.notifications :as notifications] [status-im.acquisition.chat :as chat] [status-im.acquisition.dapp :as dapp] [status-im.acquisition.claim :as claim] @@ -58,7 +59,8 @@ [{:keys [db] :as cofx} referrer {:keys [type attributed] :as referrer-meta}] (when-not attributed (fx/merge cofx - {:db (assoc-in db [:acquisition :metadata] referrer-meta)} + {:db (assoc-in db [:acquisition :metadata] referrer-meta) + ::notifications/create-channel nil} (cond (= type advertiser-type) (advertiser/start-acquisition referrer-meta) @@ -95,7 +97,7 @@ (fn [_] {::persistence/check-tx-state (fn [tx] (when-not (nil? tx) - (re-frame/dispatch [::claim/add-tx-watcher tx])))}))))) + (re-frame/dispatch [::claim/check-transaction-receipt tx])))}))))) (re-frame/reg-fx ::resolve-contract diff --git a/src/status_im/acquisition/notifications.cljs b/src/status_im/acquisition/notifications.cljs new file mode 100644 index 0000000000..f52eb96ddd --- /dev/null +++ b/src/status_im/acquisition/notifications.cljs @@ -0,0 +1,33 @@ +(ns status-im.acquisition.notifications + (:require [re-frame.core :as re-frame] + [status-im.notifications.android :as pn-android] + [status-im.utils.fx :as fx] + [status-im.i18n :as i18n] + [status-im.notifications.core :as notifications] + [status-im.ui.components.react :as react] + [quo.platform :as platform] + [status-im.ethereum.tokens :as tokens])) + +(def channel-id "status-im-referrals") + +(re-frame/reg-fx + ::create-channel + (fn [] + (when platform/android? + (pn-android/create-channel {:channel-id channel-id + :channel-name "Status referrals push notifications"})))) + +(fx/defn accept + [_] + {::notifications/local-notification + {:title (i18n/label :t/starter-pack-coming) + :message (i18n/label :t/starter-pack-coming-description) + :channel-id channel-id + :icon (:uri (react/resolve-asset-source tokens/snt-icon-source))}}) + +(fx/defn claimed + [_] + {::notifications/local-notification {:title (i18n/label :t/starter-pack-received) + :message (i18n/label :t/starter-pack-received-description) + :channel-id channel-id + :icon (:uri (react/resolve-asset-source tokens/snt-icon-source))}}) diff --git a/src/status_im/acquisition/persistance.cljs b/src/status_im/acquisition/persistance.cljs index e08a14d0dc..ebc1f988dc 100644 --- a/src/status_im/acquisition/persistance.cljs +++ b/src/status_im/acquisition/persistance.cljs @@ -19,7 +19,8 @@ (-> ^js async-storage (.setItem referrer-flow-state-key (get referrer-state decision)) (.then (fn [] - (re-frame/dispatch [:set-in [:acquisition :flow-state] decision]))) + (re-frame/dispatch [:set-in [:acquisition :flow-state] + (get referrer-state decision)]))) (.catch (fn [error] (log/error "[async-storage]" error)))))) diff --git a/src/status_im/multiaccounts/login/core.cljs b/src/status_im/multiaccounts/login/core.cljs index 53fdb66419..ebe8a42581 100644 --- a/src/status_im/multiaccounts/login/core.cljs +++ b/src/status_im/multiaccounts/login/core.cljs @@ -269,10 +269,10 @@ (fx/defn create-only-events [{:keys [db] :as cofx}] - (let [{:keys [multiaccount multiaccounts :multiaccount/accounts]} db - {:keys [creating?]} (:multiaccounts/login db) - first-account? (and creating? - (empty? multiaccounts))] + (let [{:keys [multiaccount :multiaccounts/multiaccounts :multiaccount/accounts]} db + {:keys [creating?]} (:multiaccounts/login db) + first-account? (and creating? + (empty? multiaccounts))] (fx/merge cofx {:db (-> db (dissoc :multiaccounts/login) @@ -284,12 +284,11 @@ ;;later on there is a check that filters have been initialized twice ;;so here we set it at 1 already so that it passes the check once it has ;;been initialized - :filters/initialized 1)) - :dispatch-later [{:ms 2000 :dispatch [::initialize-wallet accounts nil nil (:recovered multiaccount)]}] + :filters/initialized 1) + (assoc-in [:multiaccount :multiaccounts/first-account] first-account?)) + :dispatch-later [{:ms 2000 :dispatch [::initialize-wallet accounts nil nil (:recovered multiaccount)]}] :filters/load-filters [[]]} (finish-keycard-setup) - (when first-account? - (acquisition/create)) (protocol/initialize-protocol {:mailservers [] :mailserver-ranges {} :mailserver-topics {} @@ -448,3 +447,13 @@ (popover/show-popover {:view :secure-with-biometric}) (when-not (= previous-auth-method keychain/auth-method-none) (popover/show-popover {:view :disable-password-saving}))))))) + +(fx/defn welcome-lets-go + {:events [::welcome-lets-go]} + [cofx] + (let [first-account? (get-in cofx [:db :multiaccount :multiaccounts/first-account])] + (fx/merge cofx + (when first-account? + (acquisition/create)) + (navigation/navigate-reset {:index 0 + :routes [{:name :tabs}]})))) diff --git a/src/status_im/notifications/core.cljs b/src/status_im/notifications/core.cljs index 8cad3f6d63..5021081888 100644 --- a/src/status_im/notifications/core.cljs +++ b/src/status_im/notifications/core.cljs @@ -6,6 +6,7 @@ ["@react-native-community/push-notification-ios" :default pn-ios] [status-im.notifications.android :as pn-android] [status-im.native-module.core :as status] + [status-im.notifications.local :as local] [quo.platform :as platform] [status-im.utils.config :as config] [status-im.ethereum.json-rpc :as json-rpc])) @@ -57,9 +58,10 @@ (re-frame/reg-fx ::local-notification - (fn [{:keys [title message]}] - (log/info {:title title - :message message}))) + (fn [props] + (if platform/ios? + (local/local-push-ios props) + (local/local-push-android props)))) (re-frame/reg-fx ::enable diff --git a/src/status_im/notifications/local.cljs b/src/status_im/notifications/local.cljs index 717cf3d70e..640aa6c2f9 100644 --- a/src/status_im/notifications/local.cljs +++ b/src/status_im/notifications/local.cljs @@ -31,8 +31,9 @@ :userInfo (bean/->js (merge user-info {:notificationType "local-notification"}))})) -(defn local-push-android [{:keys [title message icon user-info]}] - (pn-android/present-local-notification (merge {:channelId "status-im-notifications" +(defn local-push-android [{:keys [title message icon user-info channel-id] + :or {channel-id "status-im-notifications"}}] + (pn-android/present-local-notification (merge {:channelId channel-id :title title :message message :showBadge false} diff --git a/src/status_im/subs.cljs b/src/status_im/subs.cljs index 0d89161d1b..1d6af977ea 100644 --- a/src/status_im/subs.cljs +++ b/src/status_im/subs.cljs @@ -216,6 +216,7 @@ (reg-root-key-sub :push-notifications/servers :push-notifications/servers) (reg-root-key-sub :push-notifications/preferences :push-notifications/preferences) +(reg-root-key-sub :acquisition :acquisition) ;;GENERAL ============================================================================================================== (re-frame/reg-sub diff --git a/src/status_im/ui/components/invite/chat.cljs b/src/status_im/ui/components/invite/chat.cljs index 452951e8a9..2e5a02bd02 100644 --- a/src/status_im/ui/components/invite/chat.cljs +++ b/src/status_im/ui/components/invite/chat.cljs @@ -92,31 +92,35 @@ nil))]]) (defn reward-messages [] - (let [pending-invite @(re-frame/subscribe [::invite/pending-chat-invite]) - loading (#{(get gateway/network-statuses :initiated) - (get gateway/network-statuses :in-flight)} - @(re-frame/subscribe [::gateway/network-status])) - messages [{:content [{:type :text - :value "👋"}]} - {:content [{:type :author - :value (i18n/label :t/invite-chat-name)} - {:type :text - :value (i18n/label :t/invite-chat-intro)} - {:type :pack} - {:type :button - :value [quo/button {:type :secondary - :loading loading - :on-press #(re-frame/dispatch [::acquisition/accept-pack])} - (i18n/label :t/invite-chat-accept)]}]} - {:content [{:type :text - :value (i18n/label :t/invite-chat-rule)}]} - {:content [{:type :text - :value [:<> - (i18n/label :t/invite-privacy-policy1) " " - [quo/text {:color :link - :on-press #(re-frame/dispatch [::invite/terms-and-conditions])} - (i18n/label :t/invite-privacy-policy2)]]}]}]] - (when pending-invite + (let [has-invite @(re-frame/subscribe [::invite/has-chat-invite]) + loading (#{(get gateway/network-statuses :initiated) + (get gateway/network-statuses :in-flight)} + @(re-frame/subscribe [::gateway/network-status])) + pending @(re-frame/subscribe [::invite/pending-reward]) + messages [{:content [{:type :text + :value "👋"}]} + {:content [{:type :author + :value (i18n/label :t/invite-chat-name)} + {:type :text + :value (i18n/label :t/invite-chat-intro)} + {:type :pack} + {:type :button + :value [quo/button {:type :secondary + :loading loading + :disabled pending + :on-press #(re-frame/dispatch [::acquisition/accept-pack])} + (if pending + (i18n/label :t/invite-chat-pending) + (i18n/label :t/invite-chat-accept))]}]} + {:content [{:type :text + :value (i18n/label :t/invite-chat-rule)}]} + {:content [{:type :text + :value [:<> + (i18n/label :t/invite-privacy-policy1) " " + [quo/text {:color :link + :on-press #(re-frame/dispatch [::invite/terms-and-conditions])} + (i18n/label :t/invite-privacy-policy2)]]}]}]] + (when has-invite [rn/view {:style (messages-wrapper)} (for [message messages] [render-message message])]))) diff --git a/src/status_im/ui/components/invite/events.cljs b/src/status_im/ui/components/invite/events.cljs index d3a9461573..ad4782993a 100644 --- a/src/status_im/ui/components/invite/events.cljs +++ b/src/status_im/ui/components/invite/events.cljs @@ -46,16 +46,31 @@ :on-success [::share-link]})) (re-frame/reg-sub - ::pending-chat-invite - (fn [db] - (let [chat-id (get db :current-chat-id) - {:keys [flow-state]} (get db :acquisition) - {:keys [attributed] - :as chat-referrer} (get-in db [:acquisition :chat-referrer chat-id])] + ::has-chat-invite + :<- [:chats/current-chat-id] + :<- [:acquisition] + (fn [[chat-id acquisition]] + (let [{:keys [flow-state attributed]} acquisition + chat-referrer (get-in acquisition [:chat-referrer chat-id])] (and chat-referrer (not attributed) - (or (= flow-state (get persistence/referrer-state :accepted)) - (nil? flow-state)))))) + (nil? flow-state))))) + +(re-frame/reg-sub + ::pending-reward + :<- [:acquisition] + (fn [{:keys [flow-state]}] + (= flow-state (get persistence/referrer-state :accepted)))) + +(re-frame/reg-sub + ::has-public-chat-invite + :<- [:acquisition] + (fn [acquisition] + (let [{:keys [metadata flow-state attributed]} acquisition + {:keys [type]} metadata] + (and (= type "public-chat") + (not attributed) + (nil? flow-state))))) (fx/defn go-to-invite {:events [::open-invite]} diff --git a/src/status_im/ui/components/invite/views.cljs b/src/status_im/ui/components/invite/views.cljs index 03654e61d7..cb205a42e3 100644 --- a/src/status_im/ui/components/invite/views.cljs +++ b/src/status_im/ui/components/invite/views.cljs @@ -176,7 +176,11 @@ (defn friend-reward-item [starter-pack-amount description] (let [tokens (transform-tokens starter-pack-amount) - reward-text (cstr/join ", " (map (comp name :symbol first) tokens))] + reward-text (->> tokens + (map (comp :symbol first)) + (filter (comp not nil?)) + (map name) + (cstr/join ", "))] [rn/view {} [rn/view {:style styles/reward-item-title} [quo/text {:weight :medium} diff --git a/src/status_im/ui/screens/chat/toolbar_content.cljs b/src/status_im/ui/screens/chat/toolbar_content.cljs index f8416fe25e..fe6a6d2cfb 100644 --- a/src/status_im/ui/screens/chat/toolbar_content.cljs +++ b/src/status_im/ui/screens/chat/toolbar_content.cljs @@ -3,8 +3,7 @@ [status-im.ui.components.chat-icon.screen :as chat-icon.screen] [status-im.ui.components.react :as react] [status-im.ui.screens.chat.styles.main :as st] - [re-frame.core :as re-frame]) - (:require-macros [status-im.utils.views :refer [defview letsubs]])) + [re-frame.core :as re-frame])) (defn- group-last-activity [{:keys [contacts public?]}] [react/view {:flex-direction :row} @@ -31,27 +30,25 @@ (i18n/label :chat-is-a-contact) (i18n/label :chat-is-not-a-contact))]])) -(defview toolbar-content-view [] - (letsubs [{:keys [group-chat - invitation-admin - color - chat-id - contacts - chat-name - public?]} - [:chats/current-chat]] - [react/view {:style st/toolbar-container} - [react/view {:margin-right 10} - [chat-icon.screen/chat-icon-view-toolbar chat-id group-chat chat-name color]] - [react/view {:style st/chat-name-view} - (if group-chat - [react/text {:style st/chat-name-text - :number-of-lines 1 - :accessibility-label :chat-name-text} - chat-name] - [one-to-one-name chat-id]) - (when-not group-chat - [contact-indicator chat-id]) - (when (and group-chat (not invitation-admin)) - [group-last-activity {:contacts contacts - :public? public?}])]])) +(defn toolbar-content-view [{:keys [group-chat + invitation-admin + color + chat-id + contacts + chat-name + public?]}] + [react/view {:style st/toolbar-container} + [react/view {:margin-right 10} + [chat-icon.screen/chat-icon-view-toolbar chat-id group-chat chat-name color]] + [react/view {:style st/chat-name-view} + (if group-chat + [react/text {:style st/chat-name-text + :number-of-lines 1 + :accessibility-label :chat-name-text} + chat-name] + [one-to-one-name chat-id]) + (when-not group-chat + [contact-indicator chat-id]) + (when (and group-chat (not invitation-admin)) + [group-last-activity {:contacts contacts + :public? public?}])]]) diff --git a/src/status_im/ui/screens/chat/views.cljs b/src/status_im/ui/screens/chat/views.cljs index 2dad881780..10b8ad6c3d 100644 --- a/src/status_im/ui/screens/chat/views.cljs +++ b/src/status_im/ui/screens/chat/views.cljs @@ -37,7 +37,7 @@ (defn topbar [] (let [current-chat @(re-frame/subscribe [:current-chat/metadata])] [topbar/topbar - {:content [toolbar-content/toolbar-content-view] + {:content [toolbar-content/toolbar-content-view current-chat] :navigation {:on-press #(re-frame/dispatch [:navigate-to :home])} :right-accessories [{:icon :main-icons/more :accessibility-label :chat-menu-button diff --git a/src/status_im/ui/screens/home/views.cljs b/src/status_im/ui/screens/home/views.cljs index 7e370ad2fd..271bd7245a 100644 --- a/src/status_im/ui/screens/home/views.cljs +++ b/src/status_im/ui/screens/home/views.cljs @@ -9,6 +9,7 @@ [status-im.ui.components.react :as react] [status-im.ui.screens.home.styles :as styles] [status-im.ui.screens.home.views.inner-item :as inner-item] + [status-im.ui.screens.referrals.home-item :as referral-item] [status-im.ui.components.colors :as colors] [status-im.ui.screens.add-new.new-public-chat.view :as new-public-chat] [quo.core :as quo] @@ -18,6 +19,7 @@ [status-im.utils.debounce :as debounce] [status-im.utils.utils :as utils] [cljs-bean.core :as bean] + [status-im.multiaccounts.login.core :as multiaccounts.login] [status-im.ui.components.invite.views :as invite] [status-im.ui.components.topbar :as topbar] [status-im.ui.components.plus-button :as components.plus-button]) @@ -45,8 +47,7 @@ [react/i18n-text {:style styles/welcome-text-description :key :welcome-to-status-description}]] [react/view {:align-items :center :margin-bottom 50} - [quo/button {:on-press #(re-frame/dispatch [:navigate-reset {:index 0 - :routes [{:name :tabs}]}]) + [quo/button {:on-press #(re-frame/dispatch [::multiaccounts.login/welcome-lets-go]) :accessibility-label :lets-go-button} (i18n/label :t/lets-go)]]]) @@ -152,8 +153,9 @@ :keyboard-should-persist-taps :always :data chats :render-fn render-fn - :header (when (or (seq chats) @search-active? (seq search-filter)) - [search-input-wrapper search-filter chats]) + :header [:<> (when (or (seq chats) @search-active? (seq search-filter)) + [search-input-wrapper search-filter chats]) + [referral-item/list-item]] :empty-component (when (or @search-active? (seq search-filter)) [start-suggestion search-filter]) :footer (if (and (not hide-home-tooltip?) (not @search-active?)) diff --git a/src/status_im/ui/screens/referrals/home_item.cljs b/src/status_im/ui/screens/referrals/home_item.cljs new file mode 100644 index 0000000000..e30838e3f7 --- /dev/null +++ b/src/status_im/ui/screens/referrals/home_item.cljs @@ -0,0 +1,60 @@ +(ns status-im.ui.screens.referrals.home-item + (:require [status-im.acquisition.chat :as acquisition.chat] + [status-im.acquisition.core :as acquisition] + [quo.core :as quo] + [status-im.i18n :as i18n] + [re-frame.core :as re-frame] + [status-im.ui.components.chat-icon.screen :as chat-icon.screen] + [quo.react-native :as rn] + [status-im.ui.components.icons.vector-icons :as icons] + [status-im.utils.core :as utils] + [status-im.ui.components.colors :as colors] + [status-im.ui.components.invite.events :as invite])) + +(defn icon-style [] + {:color colors/black + :width 15 + :height 15 + :container-style {:width 15 + :height 15 + :margin-right 2}}) + +(defn referral-sheet [] + [quo/list-item + {:theme :negative + :title (i18n/label :t/delete-chat) + :accessibility-label :delete-chat-button + :icon :main-icons/delete + :on-press #(re-frame/dispatch [::acquisition.chat/decline])}]) + +(defn list-item [] + (let [{:keys [id]} @(re-frame/subscribe [::acquisition/metadata]) + {:keys [chat-id + chat-name + group-chat + color]} {:chat-name (str "#" id) + :chat-id id + :color "#887af9" + :public? true + :group-chat true}] + (when @(re-frame/subscribe [::invite/has-public-chat-invite]) + [quo/list-item {:icon [chat-icon.screen/chat-icon-view-chat-list + chat-id group-chat chat-name color nil false] + :title [rn/view {:flex-direction :row + :flex 1} + [rn/view {:flex-direction :row + :flex 1 + :padding-right 16 + :align-items :center} + [icons/icon :main-icons/tiny-public (icon-style)] + [quo/text {:weight :medium + :accessibility-label :chat-name-text + :ellipsize-mode :tail + :number-of-lines 1} + (utils/truncate-str chat-name 30)]]] + :title-accessibility-label :chat-name-text + :subtitle (i18n/label :t/invite-public-chat-home) + :on-press #(re-frame/dispatch [:navigate-to :tabs {:screen :chat-stack + :params {:screen :referral-enclav}}]) + :on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet + {:content referral-sheet}])}]))) diff --git a/src/status_im/ui/screens/referrals/public_chat.cljs b/src/status_im/ui/screens/referrals/public_chat.cljs new file mode 100644 index 0000000000..ac747c6eec --- /dev/null +++ b/src/status_im/ui/screens/referrals/public_chat.cljs @@ -0,0 +1,109 @@ +(ns status-im.ui.screens.referrals.public-chat + (:require [status-im.ui.components.topbar :as topbar] + [status-im.ui.screens.chat.toolbar-content :as toolbar-content] + [re-frame.core :as re-frame] + [status-im.acquisition.chat :as chat.acquisition] + [status-im.acquisition.core :as acquisition] + [status-im.ui.components.invite.events :as invite] + [status-im.i18n :as i18n] + [status-im.acquisition.gateway :as gateway] + [quo.react-native :as rn] + [quo.core :as quo] + [quo.design-system.colors :as colors] + [status-im.ui.components.icons.vector-icons :as icons] + [status-im.ui.components.chat-icon.screen :as chat-icon.screen] + [status-im.ui.screens.chat.styles.main :as chat.styles] + [status-im.ui.components.invite.chat :as invite.chat])) + +(defn non-reward [] + (let [loading (#{(get gateway/network-statuses :initiated) + (get gateway/network-statuses :in-flight)} + @(re-frame/subscribe [::gateway/network-status]))] + + [rn/view {:border-radius 16 + :padding-horizontal 12 + :padding-vertical 16 + :justify-content :center + :align-items :center + :border-width 1 + :border-color (colors/get-color :border-01)} + [rn/view + [icons/icon :main-icons/link {:color (colors/get-color :icon-04)}]] + [rn/view {:style {:padding-vertical 10}} + [quo/text {:color :secondary + :align :center} + (i18n/label :t/invite-privacy-policy-public) " " + [quo/text {:color :link + :on-press #(re-frame/dispatch [::invite/terms-and-conditions])} + (i18n/label :t/invite-privacy-policy2)]]] + [rn/view {:padding-horizontal 16 + :padding-vertival 8 + :flex-direction :row} + [quo/button {:loading loading + :on-press #(re-frame/dispatch [::chat.acquisition/accept-pack])} + (i18n/label :t/invite-chat-accept-join)]]])) + +(defn reward-messages [] + (let [loading (#{(get gateway/network-statuses :initiated) + (get gateway/network-statuses :in-flight)} + @(re-frame/subscribe [::gateway/network-status])) + pending @(re-frame/subscribe [::invite/pending-reward]) + messages [{:content [{:type :text + :value "👋"}]} + {:content [{:type :text + :value (i18n/label :t/invite-public-chat-intro)} + {:type :pack} + {:type :button + :value [quo/button {:type :secondary + :loading loading + :disabled pending + :on-press #(re-frame/dispatch [::chat.acquisition/accept-pack])} + (if pending + (i18n/label :t/invite-chat-pending) + (i18n/label :t/invite-chat-accept-join))]}]} + {:content [{:type :text + :value [:<> + (i18n/label :t/invite-privacy-policy-public) " " + [quo/text {:color :link + :on-press #(re-frame/dispatch [::invite/terms-and-conditions])} + (i18n/label :t/invite-privacy-policy2)]]}]}]] + [rn/view {:style (invite.chat/messages-wrapper)} + (for [message messages] + [invite.chat/render-message message])])) + +(defn view [] + (let [{:keys [rewardable id]} @(re-frame/subscribe [::acquisition/metadata]) + {:keys [chat-id + chat-name + group-chat + color] + :as chat-info} {:chat-name (str "#" id) + :color "#887af9" + :public? true + :group-chat true}] + [:<> + [topbar/topbar + {:content [toolbar-content/toolbar-content-view chat-info] + :navigation {:on-press #(re-frame/dispatch [:navigate-to :home])}}] + [rn/scroll-view {:style {:flex 1} + :center-content true + :content-container-style {:padding 16}} + [rn/view {:style {:flex 1 + :justify-content :flex-end + :align-items :center + :padding-vertical 24}} + [rn/view {:style {:padding-vertical 16}} + [chat-icon.screen/chat-intro-icon-view + chat-name chat-id group-chat + {:default-chat-icon (chat.styles/intro-header-icon 120 color) + :default-chat-icon-text chat.styles/intro-header-icon-text + :size 120}]] + [rn/view {:style {:padding-horizontal 32 + :padding-bottom 32}} + [quo/text {:size :x-large + :weight :bold} + chat-name]]] + (if rewardable + [reward-messages] + [non-reward])]])) + diff --git a/src/status_im/ui/screens/routing/chat_stack.cljs b/src/status_im/ui/screens/routing/chat_stack.cljs index 973f4bce8b..9717126c4c 100644 --- a/src/status_im/ui/screens/routing/chat_stack.cljs +++ b/src/status_im/ui/screens/routing/chat_stack.cljs @@ -3,6 +3,7 @@ [status-im.ui.screens.home.views :as home] [status-im.ui.screens.chat.views :as chat] [status-im.ui.screens.group.views :as group] + [status-im.ui.screens.referrals.public-chat :as referrals.public-chat] [status-im.ui.screens.profile.group-chat.views :as profile.group-chat] [status-im.ui.components.tabbar.styles :as tabbar.styles] [status-im.ui.screens.stickers.views :as stickers])) @@ -16,6 +17,8 @@ [{:name :home :style {:padding-bottom tabbar.styles/tabs-diff} :component home/home} + {:name :referral-enclav + :component referrals.public-chat/view} {:name :chat :component chat/chat} {:name :group-chat-profile diff --git a/src/status_im/wallet/db_test.cljs b/src/status_im/wallet/db_test.cljs index 6764e293a9..e195c93e9f 100644 --- a/src/status_im/wallet/db_test.cljs +++ b/src/status_im/wallet/db_test.cljs @@ -23,7 +23,7 @@ (and (= (:error a) (:error b)) (or (and (nil? (:amount a)) (nil? (:amount b))) - (.eq (:amount a) (:amount b))))) + (.eq ^js (:amount a) (:amount b))))) (deftest test-parse-amount (testing "test amount parsing" diff --git a/translations/en.json b/translations/en.json index 43817d3de9..542fb33907 100644 --- a/translations/en.json +++ b/translations/en.json @@ -597,10 +597,15 @@ "invite-reward-friend-description": "Your friend will receive a Starter Pack consisting of some {{reward}} to get started", "invite-privacy-policy1": "By accepting you agree to the referral program", "invite-privacy-policy2": "Terms and Conditions.", + "invite-privacy-policy-public": "You installed Status through a referral link. By joining this chat you attribute your referrer and agree to the", "invite-chat-name": "Friend referral", "invite-chat-starter-pack": "Starter Pack", "invite-chat-intro": "You were referred by a friend to join Status. Here’s some crypto to get you started! Use it to register an ENS name or buy a sticker pack", + "invite-public-chat-home": "Referral invitation", + "invite-public-chat-intro": "Here’s some crypto to get you started! Use it to register an ENS name or buy a sticker pack", "invite-chat-accept": "Accept", + "invite-chat-pending": "Pending", + "invite-chat-accept-join": "Accept and Join", "invite-chat-rule": "Accepting will also reward your friend with a crypto referral bonus", "redeem-now": "Redeem now", "redeem-amount": "{{quantity}} bonuses available", @@ -615,6 +620,8 @@ "dapp-starter-pack-title": "Starter Pack", "dapp-starter-pack-description": "Here’s some crypto to get you started! Use it to get stickers, an ENS name and try dapps", "dapp-starter-pack-accept": "Accept and Open", + "starter-pack-coming": "Starter Pack coming your way", + "starter-pack-coming-description": "Can take a few minutes to hours", "starter-pack-received": "Starter Pack received", "starter-pack-received-description": "Here’s some crypto to get you started! Use it to get stickers, an ENS name and try dapps", "join-group-chat": "Join group",