From 03f813c957e9e1395ac9bff205f871a8b4ec5475 Mon Sep 17 00:00:00 2001 From: Ibrahem Khalil Date: Thu, 25 Apr 2024 13:49:17 +0200 Subject: [PATCH] Implement context action share community QR code (#19700) --- .../gradient/gradient_cover/view.cljs | 4 +- .../actions/community_options/view.cljs | 11 ++- .../actions/share_community/style.cljs | 64 +++++++++++++ .../actions/share_community/view.cljs | 90 +++++++++++++++++++ src/status_im/navigation/screens.cljs | 5 ++ 5 files changed, 168 insertions(+), 6 deletions(-) create mode 100644 src/status_im/contexts/communities/actions/share_community/style.cljs create mode 100644 src/status_im/contexts/communities/actions/share_community/view.cljs diff --git a/src/quo/components/gradient/gradient_cover/view.cljs b/src/quo/components/gradient/gradient_cover/view.cljs index 2d610b31f88..0a601c942ee 100644 --- a/src/quo/components/gradient/gradient_cover/view.cljs +++ b/src/quo/components/gradient/gradient_cover/view.cljs @@ -5,13 +5,13 @@ [react-native.linear-gradient :as linear-gradient])) (defn view - [{:keys [customization-color opacity container-style height] + [{:keys [customization-color opacity container-style height bottom-color-override] :or {customization-color :blue}}] ;; `when` added for safety, `linear-gradient` will break if `nil` is passed, the `:or` ;; destructuring won't work because it's only applied when the `:customization-color` key is ;; non-existent. While deleting an account the key exists and has a `nil` value. (let [color-top (colors/resolve-color customization-color 50 20) - color-bottom (colors/resolve-color customization-color 50 0)] + color-bottom (or bottom-color-override (colors/resolve-color customization-color 50 0))] (when (and color-top color-bottom) [linear-gradient/linear-gradient {:accessibility-label :gradient-cover diff --git a/src/status_im/contexts/communities/actions/community_options/view.cljs b/src/status_im/contexts/communities/actions/community_options/view.cljs index fbf9fbf9032..de674ff81ae 100644 --- a/src/status_im/contexts/communities/actions/community_options/view.cljs +++ b/src/status_im/contexts/communities/actions/community_options/view.cljs @@ -99,10 +99,13 @@ (defn show-qr [id] - {:icon :i/qr-code - :accessibility-label :show-qr - :on-press #(js/alert (str "implement action" id)) - :label (i18n/label :t/show-qr)}) + (let [on-success #(rf/dispatch [:open-modal :screen/share-community + {:community-id id + :url %}])] + {:icon :i/qr-code + :accessibility-label :show-qr + :on-press #(rf/dispatch [:communities/get-community-share-data id on-success]) + :label (i18n/label :t/show-qr)})) (defn share-community [id] diff --git a/src/status_im/contexts/communities/actions/share_community/style.cljs b/src/status_im/contexts/communities/actions/share_community/style.cljs new file mode 100644 index 00000000000..14b73be5024 --- /dev/null +++ b/src/status_im/contexts/communities/actions/share_community/style.cljs @@ -0,0 +1,64 @@ +(ns status-im.contexts.communities.actions.share-community.style + (:require [quo.foundations.colors :as colors])) + +(def horizontal-padding 20) +(def vertical-padding 12) +(def gradient-cover-padding 20) +(def qr-code-padding 12) + +(def header-container + {:padding-horizontal horizontal-padding + :padding-vertical vertical-padding}) + +(def scan-notice + {:color colors/white-70-blur + :margin-top 16 + :margin-left :auto + :margin-right :auto}) + +(defn community-name + [thumbnail] + {:margin-left (when thumbnail 8)}) + +(def qr-code-wrapper + {:padding-horizontal horizontal-padding + :margin-top 8}) + +(defn qr-code-size + [total-width] + (- total-width (* gradient-cover-padding 2) (* qr-code-padding 2))) + +(defn gradient-cover-size + [total-width] + (- total-width (* gradient-cover-padding 2))) + +(defn gradient-cover-wrapper + [width] + {:width (gradient-cover-size width) + :border-radius 16 + :margin-left 20 + :height "100%"}) + +(def share-button-container {:justify-self :flex-end}) + +(def qr-top-wrapper + {:margin 12 + :margin-bottom 0 + :flex-direction :row + :align-items :center + :justify-content :space-between}) + +(def community-avatar-dimension 32) + +(def community-avatar + {:border-radius community-avatar-dimension + :width community-avatar-dimension + :height community-avatar-dimension}) + +(def qr-code-view + {:padding-vertical vertical-padding + :align-items :center}) + +(def text-wrapper + {:flex-direction :row + :align-items :center}) diff --git a/src/status_im/contexts/communities/actions/share_community/view.cljs b/src/status_im/contexts/communities/actions/share_community/view.cljs new file mode 100644 index 00000000000..06374cd8eaa --- /dev/null +++ b/src/status_im/contexts/communities/actions/share_community/view.cljs @@ -0,0 +1,90 @@ +(ns status-im.contexts.communities.actions.share-community.view + (:require + [quo.core :as quo] + [quo.foundations.colors :as colors] + [react-native.core :as rn] + [react-native.fast-image :as fast-image] + [react-native.platform :as platform] + [react-native.safe-area :as safe-area] + [status-im.common.qr-codes.view :as qr-codes] + [status-im.common.resources :as resources] + [status-im.contexts.communities.actions.share-community.style :as style] + [utils.i18n :as i18n] + [utils.re-frame :as rf])) + +(defn view + [] + (let [{:keys [url community-id]} (rf/sub [:get-screen-params]) + window-width (rf/sub [:dimensions/window-width]) + {thumbnail-uri :logo + color :color + community-name :name} (rf/sub [:communities/for-context-tag community-id]) + navigate-back (rn/use-callback #(rf/dispatch [:navigate-back])) + on-press-share (rn/use-callback + (fn [] + (rf/dispatch + [:open-share + {:options (if platform/ios? + {:activityItemSources + [{:placeholderItem {:type :text + :content url} + :item {:default {:type :text + :content url}} + :linkMetadata {:title (i18n/label + :t/share-community)}}]} + {:title (i18n/label :t/share-community) + :subject (i18n/label :t/share-community) + :message url + :isNewTask true})}])) + [url])] + [quo/overlay {:type :shell} + [rn/view + {:style {:padding-top (safe-area/get-top)} + :key :share-community} + [quo/page-nav + {:icon-name :i/close + :on-press navigate-back + :background :blur + :accessibility-label :top-bar}] + [quo/text-combinations + {:container-style style/header-container + :title (i18n/label :t/share-community)}] + [rn/view {:style style/qr-code-wrapper} + [quo/gradient-cover + {:container-style (style/gradient-cover-wrapper window-width) + :customization-color color + :bottom-color-override colors/white-opa-5}] + [rn/view + {:style style/qr-top-wrapper} + [rn/view {:style style/text-wrapper} + (when thumbnail-uri + [fast-image/fast-image + {:source {:uri thumbnail-uri} + :style style/community-avatar}]) + [quo/text + {:size :heading-2 + :weight :semi-bold + :style (style/community-name thumbnail-uri)} + community-name]] + [rn/view {:style style/share-button-container} + [quo/button + {:icon-only? true + :type :grey + :background :blur + :size 32 + :accessibility-label :link-to-community + :on-press on-press-share} + :i/share]]] + [rn/view + {:style style/qr-code-view} + [qr-codes/qr-code + {:size (style/qr-code-size window-width) + :url url + :avatar :community + :customization-color color + :picture (or thumbnail-uri (resources/get-mock-image :status-logo))}]]] + [quo/text + {:size :paragraph-2 + :weight :regular + :style style/scan-notice} + (i18n/label :t/scan-with-status-app)]]])) diff --git a/src/status_im/navigation/screens.cljs b/src/status_im/navigation/screens.cljs index 3b938aa64e6..b638697527d 100644 --- a/src/status_im/navigation/screens.cljs +++ b/src/status_im/navigation/screens.cljs @@ -22,6 +22,7 @@ [status-im.contexts.communities.actions.invite-contacts.view :as communities.invite] [status-im.contexts.communities.actions.request-to-join.view :as join-menu] [status-im.contexts.communities.actions.share-community-channel.view :as share-community-channel] + [status-im.contexts.communities.actions.share-community.view :as share-community] [status-im.contexts.communities.discover.view :as communities.discover] [status-im.contexts.communities.overview.view :as communities.overview] [status-im.contexts.onboarding.create-password.view :as create-password] @@ -147,6 +148,10 @@ :options options/transparent-screen-options :component share-community-channel/view} + {:name :screen/share-community + :options options/transparent-screen-options + :component share-community/view} + ;; Note: the sheet screen is used when selecting addresses to share when ;; joining a community. The non-sheet screen is used when editing shared ;; addresses after the join request was sent.