From d0f81a549cb522b2fc56f7ab1a786734b381842d Mon Sep 17 00:00:00 2001 From: Siddarth Kumar Date: Wed, 1 Feb 2023 12:34:08 +0530 Subject: [PATCH] add share tab for profile inside Shell --- ios/Podfile.lock | 8 +- src/quo2/components/qr_code/qr.cljs | 32 ++++ src/status_im/events.cljs | 1 + src/status_im/ui/screens/popover/views.cljs | 6 +- src/status_im2/common/home/view.cljs | 4 +- src/status_im2/contexts/share/events.cljs | 24 +++ src/status_im2/contexts/share/style.cljs | 122 +++++++++++++++ src/status_im2/contexts/share/view.cljs | 162 ++++++++++++++++++++ translations/en.json | 6 +- 9 files changed, 358 insertions(+), 7 deletions(-) create mode 100644 src/quo2/components/qr_code/qr.cljs create mode 100644 src/status_im2/contexts/share/events.cljs create mode 100644 src/status_im2/contexts/share/style.cljs create mode 100644 src/status_im2/contexts/share/view.cljs diff --git a/ios/Podfile.lock b/ios/Podfile.lock index a87a212177bd..50eed96e8285 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -210,7 +210,7 @@ PODS: - React - react-native-blob-util (0.13.18): - React-Core - - react-native-blur (4.3.0): + - react-native-blur (4.3.2): - React-Core - react-native-camera-kit (8.0.4): - React @@ -645,7 +645,7 @@ SPEC CHECKSUMS: FBLazyVector: 352a8ca9bbc8e2f097d680747a8c97ecef12d469 FBReactNativeSpec: 7dfb84f624136a45727c813ed21d130cd3e61beb Folly: b73c3869541e86821df3c387eb0af5f65addfab4 - glog: 6934faae5afbec23475648c8aeb6047ce973af65 + glog: 997518ea2aa2d8cd5df9797b641b758d52ecf2bc HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352 Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8 libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef @@ -663,7 +663,7 @@ SPEC CHECKSUMS: React-jsinspector: fdbc08866b34ae8e1b788ea1cbd9f9d1ca2aa3d6 react-native-background-timer: 1f7d560647b40e6a60b01c452ba29c54bf581fc4 react-native-blob-util: 600972b1782380a5a7d5db61a3817ea32349dae9 - react-native-blur: 50c9feabacbc5f49b61337ebc32192c6be7ec3c3 + react-native-blur: 4db8c7556566df4e8714c1af5762a4ebc99175d5 react-native-camera-kit: 498a6d111a904834e0824e9073cfadef7303235f react-native-cameraroll: 88f4e62d9ecd0e1f253abe4f685474f2ea14bfa2 react-native-config: c98128a72bc2c3a1ca72caec0b021f0fa944aa29 @@ -716,6 +716,6 @@ SPEC CHECKSUMS: TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 Yoga: 0276e9f20976c8568e107cfc1163a8629051adc0 -PODFILE CHECKSUM: dd4d6510a5580d20adac6c8a8dad97a0bc7d6508 +PODFILE CHECKSUM: a8a81808e948d1103fdd28ef7fe16d5f045fef62 COCOAPODS: 1.12.0 diff --git a/src/quo2/components/qr_code/qr.cljs b/src/quo2/components/qr_code/qr.cljs new file mode 100644 index 000000000000..31537837b253 --- /dev/null +++ b/src/quo2/components/qr_code/qr.cljs @@ -0,0 +1,32 @@ +(ns quo2.components.qr-code.qr + (:require [react-native.core :as rn])) + +(defn user-profile-qr-code + [{:keys [key-uid public-key port qr-size]}] + (let [profile-qr-url (str "https://join.status.im/u/" public-key) + base-64-qr-url (js/btoa profile-qr-url) + profile-image-type "large" + error-correction-level 4 + superimpose-profile? true + media-server-url (str "https://localhost:" + port + "/GenerateQRCode?level=" + error-correction-level + "&url=" + base-64-qr-url + "&keyUid=" + key-uid + "&allowProfileImage=" + superimpose-profile? + "&size=" + qr-size + "&imageName=" + profile-image-type)] + [rn/view + {:style {:flex-direction :row + :justify-content :center}} + [rn/image + {:source {:uri media-server-url} + :style {:width qr-size + :height qr-size + :border-radius 12}}]])) diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index 5b6bbb46b185..91d0e7e36d33 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -56,6 +56,7 @@ status-im.wallet.custom-tokens.core status-im2.contexts.activity-center.events status-im2.contexts.activity-center.notification.contact-requests.events + status-im2.contexts.share.events status-im2.contexts.shell.events status-im2.contexts.onboarding.events status-im.chat.models.gaps diff --git a/src/status_im/ui/screens/popover/views.cljs b/src/status_im/ui/screens/popover/views.cljs index e021f7929e3e..c63113886992 100644 --- a/src/status_im/ui/screens/popover/views.cljs +++ b/src/status_im/ui/screens/popover/views.cljs @@ -19,7 +19,8 @@ [status-im.ui.screens.wallet.request.views :as request] [status-im.ui.screens.wallet.signing-phrase.views :as signing-phrase] [status-im.utils.platform :as platform] - [status-im2.contexts.activity-center.view :as activity-center])) + [status-im2.contexts.activity-center.view :as activity-center] + [status-im2.contexts.share.view :as share])) (defn hide-panel-anim [bottom-anim-value alpha-value window-height] @@ -188,6 +189,9 @@ (= :activity-center view) [activity-center/view request-close] + (= :profile-share view) + [share/view] + :else [view])]]]])))}))) diff --git a/src/status_im2/common/home/view.cljs b/src/status_im2/common/home/view.cljs index 037635f14508..e3d3012a30ad 100644 --- a/src/status_im2/common/home/view.cljs +++ b/src/status_im2/common/home/view.cljs @@ -95,7 +95,9 @@ (assoc button-common-props :accessibility-label :open-scanner-button) :i/scan] [quo/button - (assoc button-common-props :accessibility-label :show-qr-button) + (merge button-common-props + {:accessibility-label :show-qr-button + :on-press #(rf/dispatch [:share/open])}) :i/qr-code] [rn/view [unread-indicator] diff --git a/src/status_im2/contexts/share/events.cljs b/src/status_im2/contexts/share/events.cljs new file mode 100644 index 000000000000..0d897ceca101 --- /dev/null +++ b/src/status_im2/contexts/share/events.cljs @@ -0,0 +1,24 @@ +(ns status-im2.contexts.share.events + (:require [utils.re-frame :as rf] + [status-im2.common.toasts.events :as toasts] + [quo2.foundations.colors :as colors])) + +(rf/defn open-profile-share-view + {:events [:share/open]} + [{:keys [db]}] + {:dispatch [:show-popover + {:view :profile-share + :style {:margin 0} + :disable-touchable-overlay? true + :blur-view? true + :blur-view-props {:blur-amount 20 + :blur-type :dark}}]}) + +(rf/defn show-successfully-copied-toast + {:events [:share/show-successfully-copied-toast]} + [cofx toast-label] + (toasts/upsert cofx + {:icon :correct + :icon-color colors/success-50 + :override-theme :dark + :text toast-label})) diff --git a/src/status_im2/contexts/share/style.cljs b/src/status_im2/contexts/share/style.cljs new file mode 100644 index 000000000000..714d469ad5d1 --- /dev/null +++ b/src/status_im2/contexts/share/style.cljs @@ -0,0 +1,122 @@ +(ns status-im2.contexts.share.style + (:require [quo2.foundations.colors :as colors])) + +(def screen-padding 20) +(def qr-container-radius 16) +(def emoji-hash-container-radius 16) + +(def header-button + {:margin-bottom 12 + :margin-left screen-padding}) + +(def header-heading + {:padding-horizontal screen-padding + :padding-vertical 12 + :color colors/white}) + +(defn screen-container + [window-width top bottom] + {:flex 1 + :width window-width + :padding-top (if (pos? top) (+ top 12) 12) + :padding-bottom bottom}) + +(def tabs + {:padding-left screen-padding}) + +(defn qr-code-container + [window-width] + {:padding 12 + :border-radius qr-container-radius + :margin-top 12 + :margin-bottom 4 + :margin-horizontal (* window-width 0.053) + :background-color colors/white-opa-5 + :flex-direction :column + :justify-content :center + :align-items :center}) + + +(defn emoji-hash-container + [window-width] + {:border-radius emoji-hash-container-radius + :margin-top 12 + :padding-vertical :1% + :margin-horizontal (* window-width 0.053) + :background-color colors/white-opa-5 + :flex-direction :row + :justify-content :space-between + :align-items :center}) + +(def profile-address-column + {:flex-direction :column}) + +(def profile-address-label + {:align-self :flex-start + :color colors/white-opa-40 + :padding-top 10}) + +(def copyable-text-container-style + {:background-color :transparent}) + +(defn profile-address-content + [max-width] + {:color colors/white + :align-self :flex-start + :padding-top 2 + :font-weight :500 + :font-size 16 + :max-width max-width}) + +(def address-share-button-container + {:padding 8 + :position :absolute + :background-color colors/white-opa-5 + :border-radius 10 + :right 14 + :top 10}) + +(defn profile-address-container + [qr-size] + {:flex-direction :row + :justify-content :space-between + :margin-top 6 + :width qr-size}) + +(def emoji-hash-label + {:color colors/white-opa-40 + :padding-left 12 + :margin-top 8}) + +(def share-button-container + {:flex-direction :column + :justify-content :center + :align-items :center + :padding-left 12}) + +(defn set-custom-width + [section-width] + {:width section-width}) + +(defn emoji-hash-content + [max-width] + {:color colors/white + :align-self :flex-start + :padding-top 4 + :padding-bottom 8 + :padding-left 12 + :font-weight :500 + :font-size 14 + :max-width max-width}) + +(def emoji-share-button-container + {:padding 8 + :position :absolute + :background-color colors/white-opa-5 + :border-radius 10 + :right 14 + :top 2}) + +(def tabs-container + {:padding-horizontal screen-padding + :margin-vertical 8}) diff --git a/src/status_im2/contexts/share/view.cljs b/src/status_im2/contexts/share/view.cljs new file mode 100644 index 000000000000..2eec5a8eb1b0 --- /dev/null +++ b/src/status_im2/contexts/share/view.cljs @@ -0,0 +1,162 @@ +(ns status-im2.contexts.share.view + (:require [utils.i18n :as i18n] + [quo2.core :as quo] + [react-native.core :as rn] + [react-native.safe-area :as safe-area] + [status-im2.contexts.share.style :as style] + [utils.re-frame :as rf] + [reagent.core :as reagent] + [quo2.foundations.colors :as colors] + [quo2.components.qr-code.qr :as qr] + ;;TODO(siddarthkay) : move these components over to status-im2 ns first + [status-im.ui.components.list-selection :as list-selection] + [status-im.ui.components.react :as react] + [clojure.string :as string])) + +(def ^:const profile-tab-id 0) +(def ^:const wallet-tab-id 1) + +(defn copy-text-and-show-toast + [{:keys [text-to-copy post-copy-message]}] + (react/copy-to-clipboard text-to-copy) + (js/setTimeout + #(rf/dispatch [:share/show-successfully-copied-toast post-copy-message]) + 250)) + +(defn header + [] + [rn/view + [quo/button + {:icon true + :type :blur-bg + :size 32 + :accessibility-label :close-activity-center + :override-theme :dark + :style style/header-button + :on-press #(rf/dispatch [:hide-popover])} + :i/close] + [quo/text + {:size :heading-1 + :weight :semi-bold + :style style/header-heading} + (i18n/label :t/share)]]) + +(defn profile-tab + [window-width] + (let [multiaccount (rf/sub [:multiaccount]) + emoji-hash (string/join "" (get multiaccount :emoji-hash)) + qr-size (- window-width 64) + current-pk (get multiaccount :public-key) + profile-qr-url (str "https://join.status.im/u/" current-pk) + port (rf/sub [:mediaserver/port]) + key-uid (get multiaccount :key-uid)] + [:<> + [rn/view {:style (style/qr-code-container window-width)} + [qr/user-profile-qr-code + {:window-width window-width + :key-uid key-uid + :qr-size (- window-width 64) + :public-key current-pk + :port port}] + [rn/view {:style (style/profile-address-container qr-size)} + [rn/view {:style style/profile-address-column} + [quo/text + {:size :paragraph-2 + :weight :medium + :style style/profile-address-label} + (i18n/label :t/link-to-profile)] + [rn/touchable-highlight + {:active-opacity 1 + :underlay-color colors/neutral-80-opa-1-blur + :background-color :transparent + :on-press #(copy-text-and-show-toast + {:text-to-copy profile-qr-url + :post-copy-message (i18n/label :t/link-to-profile-copied)}) + :on-long-press #(copy-text-and-show-toast + {:text-to-copy profile-qr-url + :post-copy-message (i18n/label :t/link-to-profile-copied)})} + [rn/text + {:style (style/profile-address-content (* window-width 0.7)) + :ellipsize-mode :middle + :number-of-lines 1} + profile-qr-url]]] + [rn/view {:style style/share-button-container} + [quo/button + {:icon true + :type :blur-bg + :size 32 + :accessibility-label :link-to-profile + :override-theme :dark + :on-press (fn [] + (js/setTimeout + #(list-selection/open-share {:message profile-qr-url}) + 250))} + :i/share]]]] + + [rn/view {:style (style/emoji-hash-container window-width)} + [rn/view {:style style/profile-address-container} + [rn/view {:style style/profile-address-column} + [quo/text + {:size :paragraph-2 + :weight :medium + :style style/emoji-hash-label} + (i18n/label :t/emoji-hash)] + [rn/touchable-highlight + {:active-opacity 1 + :underlay-color colors/neutral-80-opa-1-blur + :background-color :transparent + :on-press #(copy-text-and-show-toast + {:text-to-copy emoji-hash + :post-copy-message (i18n/label :t/emoji-hash-copied)}) + :on-long-press #(copy-text-and-show-toast + {:text-to-copy emoji-hash + :post-copy-message (i18n/label :t/emoji-hash-copied)})} + [rn/text {:style (style/emoji-hash-content (* window-width 0.76))} emoji-hash]]]] + [rn/view {:style style/share-button-container} + [quo/button + {:icon true + :type :blur-bg + :size 32 + :accessibility-label :link-to-profile + :override-theme :dark + :style {:margin-right 12} + :on-press #(copy-text-and-show-toast + {:text-to-copy emoji-hash + :post-copy-message (i18n/label :t/emoji-hash-copied)}) + :on-long-press #(copy-text-and-show-toast + {:text-to-copy emoji-hash + :post-copy-message (i18n/label :t/emoji-hash-copied)})} + :i/copy]]]])) + +(defn wallet-tab + [] + [:<> + [rn/text {:style {:color colors/white :text-align :center}} "not implemented"]]) + +(defn view + [] + (let [selected-tab (reagent/atom profile-tab-id)] + [safe-area/consumer + (fn [{:keys [top bottom]}] + (let [window-width (rf/sub [:dimensions/window-width])] + [rn/view {:style (style/screen-container window-width top bottom)} + [header] + [rn/view {:style style/tabs-container} + [quo/segmented-control + {:size 28 + :scrollable? true + :blur? true + :override-theme :dark + :style style/tabs + :fade-end-percentage 0.79 + :scroll-on-press? true + :fade-end? true + :on-change #(reset! selected-tab %) + :default-active @selected-tab + :data [{:id profile-tab-id + :label (i18n/label :t/profile)} + {:id wallet-tab-id + :label (i18n/label :t/wallet)}]}]] + (if (= @selected-tab profile-tab-id) + [profile-tab window-width] + [wallet-tab])]))])) diff --git a/translations/en.json b/translations/en.json index 6d4b47a4f77a..905f146b419d 100644 --- a/translations/en.json +++ b/translations/en.json @@ -2054,5 +2054,9 @@ "error-syncing-connection-failed": "Oops! Connection failed. Try again", "camera-permission-denied": "Permission denied", "enable-biometrics": "Enable biometrics", - "use-biometrics": "Use biometrics to fill in your password" + "use-biometrics": "Use biometrics to fill in your password", + "link-to-profile": "Link to profile", + "emoji-hash": "Emoji Hash", + "emoji-hash-copied":"Emojihash copied to clipboard", + "link-to-profile-copied":"Link to Profile copied to clipboard" }