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",