Implement share button inside profile settings (#19559)

* tweak: implement the share button inside the profile settings page

* chore: define event and effect handler for opening share sheet

* tidy: refactor share buttons to use open-share event

* tidy: refactor open-share effect to use react-native-share bindings

* tidy: remove unused code for old bindings to react share sheet

* tidy: move effects.share/open definition to navigation effects

* tweak: ensure navigation effects are loaded

* tidy: use open-share dispatch in ui

* tidy: use open-share dispatch instead of calling open function directly

* tidy: refactor react-native.share/open to only receive options and return promise

* tidy: refactor open-share effect to receive map of content and handlers

* tidy: replace strings with keywords

* tweak: always handle failure case when opening share-sheet

* tweak: rename :content to :options

* fix: conditionally call on-error

* tweak: add extra information when logging error from attempting to share-sheet
This commit is contained in:
Sean Hagstrom 2024-04-16 13:26:52 +02:00 committed by GitHub
parent 8b3e639abd
commit 61974dae4d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 91 additions and 82 deletions

View File

@ -226,7 +226,3 @@
(defn open-url [link] (.openURL ^js linking link))
(def set-status-bar-style react-native/StatusBar.setBarStyle)
(defn sharing
[content]
(.share (.-Share ^js react-native) (clj->js content)))

View File

@ -4,9 +4,5 @@
(defn open
([options]
(open options #() #()))
([options on-success on-error]
(-> ^js react-native-share
(.open (clj->js options))
(.then on-success)
(.catch on-error))))
(.open (clj->js options)))))

View File

@ -3,7 +3,6 @@
[react-native.cameraroll :as cameraroll]
[react-native.fs :as fs]
[react-native.platform :as platform]
[react-native.share :as share]
[utils.re-frame :as rf]))
(def config
@ -15,10 +14,12 @@
(blob/fetch uri
config
(fn [downloaded-url]
(share/open {:url (str (when platform/android? "file://") downloaded-url)
(rf/dispatch [:open-share
{:options {:url (str (when platform/android? "file://")
downloaded-url)
:isNewTask true}
#(fs/unlink downloaded-url)
#(fs/unlink downloaded-url))))))
:on-success #(fs/unlink downloaded-url)
:on-error #(fs/unlink downloaded-url)}])))))
(rf/reg-fx :effects.lightbox/save-image-to-gallery
(fn [[uri on-success]]

View File

@ -5,7 +5,6 @@
[re-frame.core :as re-frame]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[react-native.share :as share]
[status-im.common.contact-list-item.view :as contact-list-item]
[status-im.common.contact-list.view :as contact-list]
[status-im.common.home.actions.view :as actions]
@ -122,7 +121,7 @@
[:show-bottom-sheet {:content chat.actions.view/new-chat}])
:accessibility-label :new-chat-button}
:card-props
{:on-press #(share/open {:url profile-link})
{:on-press #(rf/dispatch [:open-share {:options {:url profile-link}}])
:banner (resources/get-image :invite-friends)
:title (i18n/label :t/invite-friends-to-status)
:description (i18n/label :t/share-invite-link)}})

View File

@ -38,23 +38,24 @@
:url %}])]
{:fx [[:dispatch [:communities/get-community-channel-share-data chat-id on-success]]]})))
(rf/reg-event-fx :communities/share-community-url-with-data
(fn [_ [community-id]]
(let [title (i18n/label :t/community-on-status)
(rf/reg-event-fx :communities/share-community-channel-url-with-data
(fn [_ [chat-id]]
(let [title (i18n/label :t/channel-on-status)
on-success (fn [url]
(share/open
(if platform/ios?
{:activityItemSources [{:placeholderItem {:type "text"
(rf/dispatch [:open-share
{:options (if platform/ios?
{:activityItemSources
[{:placeholderItem {:type :text
:content title}
:item {:default {:type "url"
:item {:default {:type :url
:content url}}
:linkMetadata {:title title}}]}
{:title title
:subject title
:message url
:url url
:isNewTask true})))]
{:fx [[:dispatch [:communities/get-community-share-data community-id on-success]]]})))
:isNewTask true})}]))]
{:fx [[:dispatch [:communities/get-community-channel-share-data chat-id on-success]]]})))
(rf/reg-event-fx :communities/get-community-channel-share-data
(fn [_ [chat-id on-success]]

View File

@ -48,7 +48,8 @@
(fn []
(rf/dispatch [:universal-links/generate-profile-url
{:public-key public-key
:on-success #(rn/sharing {:message %})}]))
:on-success #(rf/dispatch [:open-share
{:options {:message %}}])}]))
[public-key])
on-remove-contact (rn/use-callback
(fn []

View File

@ -1,6 +1,5 @@
(ns status-im.contexts.profile.contact.share.view
(:require [legacy.status-im.ui.components.list-selection :as list-selection]
[quo.core :as quo]
(:require [quo.core :as quo]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[status-im.common.qr-codes.view :as qr-codes]
@ -19,7 +18,8 @@
abbreviated-url (rn/use-memo (fn []
(address/get-abbreviated-profile-url universal-profile-url))
[universal-profile-url])
on-share-press (rn/use-callback #(list-selection/open-share {:message universal-profile-url})
on-share-press (rn/use-callback #(rf/dispatch [:open-share
{:options {:message universal-profile-url}}])
[universal-profile-url])
on-copy-press (rn/use-callback (fn []
(rf/dispatch [:share/copy-text-and-show-toast

View File

@ -5,7 +5,6 @@
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
[status-im.common.not-implemented :as not-implemented]
[status-im.contexts.profile.settings.header.view :as settings.header]
[status-im.contexts.profile.settings.list-items :as settings.items]
[status-im.contexts.profile.settings.style :as style]
@ -62,7 +61,10 @@
:on-press #(rf/dispatch [:navigate-back])
:right-side [{:icon-name :i/qr-code
:on-press #(debounce/throttle-and-dispatch [:open-modal :share-shell] 1000)}
{:icon-name :i/share :on-press not-implemented/alert}]}]]
{:icon-name :i/share
:on-press #(rf/dispatch [:open-share
{:options {:message (:universal-profile-url
profile)}}])}]}]]
[rn/flat-list
{:key :list
:header [settings.header/view {:scroll-y scroll-y}]

View File

@ -1,7 +1,6 @@
(ns status-im.contexts.shell.share.profile.view
(:require
[clojure.string :as string]
[legacy.status-im.ui.components.list-selection :as list-selection]
[quo.core :as quo]
[quo.foundations.colors :as colors]
[react-native.core :as rn]
@ -30,7 +29,7 @@
:width (- window-width (* style/screen-padding 2))
:qr-data universal-profile-url
:qr-data-label-shown abbreviated-url
:on-share-press #(list-selection/open-share {:message universal-profile-url})
:on-share-press #(rf/dispatch [:open-share {:options {:message universal-profile-url}}])
:on-text-press #(rf/dispatch [:share/copy-text-and-show-toast
{:text-to-copy universal-profile-url
:post-copy-message (i18n/label :t/link-to-profile-copied)}])

View File

@ -4,7 +4,6 @@
[quo.core :as quo]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.share :as share]
[reagent.core :as reagent]
[status-im.constants :as constants]
[status-im.contexts.shell.share.style :as style]
@ -20,18 +19,18 @@
(defn- share-action
[address share-title]
(share/open
(if platform/ios?
{:activityItemSources [{:placeholderItem {:type "text"
(rf/dispatch [:open-share
{:options (if platform/ios?
{:activityItemSources [{:placeholderItem {:type :text
:content address}
:item {:default {:type "text"
:item {:default {:type :text
:content
address}}
:linkMetadata {:title share-title}}]}
{:title share-title
:subject share-title
:message address
:isNewTask true})))
:isNewTask true})}]))
(defn- open-preferences
[selected-networks account]

View File

@ -4,7 +4,6 @@
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.safe-area :as safe-area]
[react-native.share :as share]
[reagent.core :as reagent]
[status-im.constants :as constants]
[status-im.contexts.wallet.account.share-address.style :as style]
@ -18,18 +17,18 @@
(defn- share-action
[address share-title]
(share/open
(if platform/ios?
{:activityItemSources [{:placeholderItem {:type "text"
(rf/dispatch [:open-share
{:options (if platform/ios?
{:activityItemSources [{:placeholderItem {:type :text
:content address}
:item {:default {:type "text"
:item {:default {:type :text
:content
address}}
:linkMetadata {:title share-title}}]}
{:title share-title
:subject share-title
:message address
:isNewTask true})))
:isNewTask true})}]))
(defn- open-preferences
[selected-networks]

View File

@ -2,12 +2,7 @@
(:require
[clojure.string :as string]
[native-module.core :as native-module]
[re-frame.core :as rf]
[react-native.share :as share]))
(rf/reg-fx :effects.share/open
(fn [content]
(share/open content)))
[re-frame.core :as rf]))
(rf/reg-fx
:effects.wallet/create-account-from-mnemonic

View File

@ -402,16 +402,16 @@
(rf/reg-event-fx :wallet/share-account
(fn [_ [{:keys [content title]}]]
{:fx [[:effects.share/open
(if platform/ios?
{:options (if platform/ios?
{:activityItemSources
[{:placeholderItem {:type "text"
[{:placeholderItem {:type :text
:content content}
:item {:default {:type "text"
:item {:default {:type :text
:content content}}
:linkMetadata {:title title}}]}
{:title title
:subject title
:message content})]]}))
:message content})}]]}))
(rf/reg-event-fx
:wallet/blockchain-status-changed

View File

@ -39,6 +39,7 @@
status-im.contexts.wallet.send.events
status-im.contexts.wallet.signals
[status-im.db :as db]
status-im.navigation.effects
status-im.navigation.events
[utils.re-frame :as rf]))

View File

@ -5,6 +5,7 @@
[react-native.core :as rn]
[react-native.navigation :as navigation]
[react-native.platform :as platform]
[react-native.share :as share]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
[status-im.contexts.shell.jump-to.utils :as jump-to.utils]
[status-im.navigation.options :as options]
@ -183,6 +184,19 @@
(rf/reg-fx :open-modal-fx open-modal)
;;;; Share
(rf/reg-fx :effects.share/open
(fn [{:keys [options on-success on-error]}]
(cond-> (share/open options)
(fn? on-success) (.then on-success)
:always (.catch (fn [error]
(log/error "Failed to share content"
{:error error
:effect :effects.share/open})
(when (fn? on-error)
(on-error error)))))))
;;;; Overlay
(defn show-overlay

View File

@ -144,3 +144,9 @@
{:events [:reload-status-nav-color]}
[{:keys [db]} view-id]
{:reload-status-nav-color-fx (or view-id (:view-id db))})
(defn open-share
[_ [config]]
{:fx [[:effects.share/open config]]})
(rf/reg-event-fx :open-share open-share)