mirror of
https://github.com/inaturalist/iNaturalistReactNative.git
synced 2025-12-23 22:18:36 -05:00
922 share sheet changes (#3129)
* Allow 500 photos in image picker
* Allow 500 photos from share extension
* Basic React share sheet setup
Following the setup here: f5805e9208/SHARE_EXTENSION_VIEW.md
* Basic ShareSheet React component
* Update ShareSheet.tsx
* Update ShareSheet.tsx
This commit is contained in:
5
index.share.js
Normal file
5
index.share.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import { AppRegistry } from "react-native";
|
||||
|
||||
import ShareSheet from "./src/components/ShareSheet/ShareSheet";
|
||||
|
||||
AppRegistry.registerComponent( "ShareMenuModuleComponent", () => ShareSheet );
|
||||
@@ -9,7 +9,7 @@
|
||||
<!--Share View Controller-->
|
||||
<scene sceneID="ceB-am-kn3">
|
||||
<objects>
|
||||
<viewController id="j1y-V4-xli" customClass="ShareViewController" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<viewController id="j1y-V4-xli" customClass="ReactShareViewController" customModule="iNaturalistReactNative-ShareExtension" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" opaque="NO" contentMode="scaleToFill" id="wbc-yd-nQP">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<key>NSExtensionActivationRule</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
|
||||
<integer>20</integer>
|
||||
<integer>500</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSExtensionMainStoryboard</key>
|
||||
@@ -21,5 +21,31 @@
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.share-services</string>
|
||||
</dict>
|
||||
<key>ReactShareViewBackgroundColor</key>
|
||||
<dict>
|
||||
<key>Red</key>
|
||||
<integer>1</integer>
|
||||
<key>Green</key>
|
||||
<integer>1</integer>
|
||||
<key>Blue</key>
|
||||
<integer>1</integer>
|
||||
<key>Alpha</key>
|
||||
<integer>1</integer>
|
||||
<key>Transparent</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//
|
||||
// Use this file to import your target's public headers that you would like to expose to Swift.
|
||||
//
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTBridgeDelegate.h>
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
8F1AC6772BC1B610002F994B /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 8F1AC6762BC1B610002F994B /* PrivacyInfo.xcprivacy */; };
|
||||
8F1AC6792BC1B610002F994B /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 8F1AC6762BC1B610002F994B /* PrivacyInfo.xcprivacy */; };
|
||||
8F346E4A2CF6912700CED7B4 /* geomodel.mlmodel in Sources */ = {isa = PBXBuildFile; fileRef = 8F346E492CF6912700CED7B4 /* geomodel.mlmodel */; };
|
||||
8FA933AD2E99522900179553 /* ReactShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FA933AC2E99522900179553 /* ReactShareViewController.swift */; };
|
||||
A5C00A8934ED4A48A1495179 /* INatIcon.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0972395C34134C71A54A2A5D /* INatIcon.ttf */; };
|
||||
AE4DC81B3A87484CB3FD6750 /* Lato-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 4B0AEEF6CA584BCF9880EB35 /* Lato-Regular.ttf */; };
|
||||
E5DFC1C6FBFA45739CE91C69 /* Lato-MediumItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 69DF855D92EA4ADFB73B47F1 /* Lato-MediumItalic.ttf */; };
|
||||
@@ -92,6 +93,7 @@
|
||||
8C2D97D72EED451C887998A8 /* Lato-BoldItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-BoldItalic.ttf"; path = "../assets/fonts/Lato-BoldItalic.ttf"; sourceTree = "<group>"; };
|
||||
8F1AC6762BC1B610002F994B /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||
8F346E492CF6912700CED7B4 /* geomodel.mlmodel */ = {isa = PBXFileReference; lastKnownFileType = file.mlmodel; path = geomodel.mlmodel; sourceTree = "<group>"; };
|
||||
8FA933AC2E99522900179553 /* ReactShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ReactShareViewController.swift; path = "../node_modules/react-native-share-menu/ios/ReactShareViewController.swift"; sourceTree = SOURCE_ROOT; };
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||
F15C1390617A309CE0A194B2 /* Pods_iNaturalistReactNative_ShareExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_iNaturalistReactNative_ShareExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
@@ -202,6 +204,7 @@
|
||||
8B65ED2C29F575C10054CCEF /* iNaturalistReactNative-ShareExtension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8FA933AC2E99522900179553 /* ReactShareViewController.swift */,
|
||||
8B65ED3C29F576D00054CCEF /* iNaturalistReactNative-ShareExtension.entitlements */,
|
||||
8B65ED3A29F575FE0054CCEF /* ShareViewController.swift */,
|
||||
8B65ED2F29F575C10054CCEF /* MainInterface.storyboard */,
|
||||
@@ -260,6 +263,7 @@
|
||||
8B65ED2829F575C10054CCEF /* Frameworks */,
|
||||
8B65ED2929F575C10054CCEF /* Resources */,
|
||||
CBBE96E94BCFC337E2A3EDB6 /* [CP] Copy Pods Resources */,
|
||||
8F0FF30C2E9AF08F005DCE05 /* Bundle React Native code and images */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -397,6 +401,24 @@
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-iNaturalistReactNative/Pods-iNaturalistReactNative-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
8F0FF30C2E9AF08F005DCE05 /* Bundle React Native code and images */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Bundle React Native code and images";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "export ENTRY_FILE=index.share.js\n\nset -e\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
|
||||
};
|
||||
987B044B8ED1BE214203D222 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -472,6 +494,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8B65ED3B29F575FE0054CCEF /* ShareViewController.swift in Sources */,
|
||||
8FA933AD2E99522900179553 /* ReactShareViewController.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@ import { useLayoutPrefs } from "sharedHooks";
|
||||
import useExitObservationsFlow from "sharedHooks/useExitObservationFlow";
|
||||
import useStore from "stores/useStore";
|
||||
|
||||
const MAX_PHOTOS_ALLOWED = 20;
|
||||
const MAX_PHOTOS_ALLOWED = 500;
|
||||
const FROM_AICAMERA_MAX_PHOTOS_ALLOWED = 1;
|
||||
|
||||
const PhotoLibrary = ( ): Node => {
|
||||
|
||||
86
src/components/ShareSheet/ShareSheet.tsx
Normal file
86
src/components/ShareSheet/ShareSheet.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
// Fellow developers: This is the component that is rendered when the share extension is opened.
|
||||
// It uses a separate React instance and entry point that is registered in index.share.js
|
||||
// It is not set up to use anything from the main app, like nativewind or styled components.
|
||||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
Pressable, StyleSheet, Text, View
|
||||
} from "react-native";
|
||||
import { ShareMenuReactView } from "react-native-share-menu";
|
||||
|
||||
interface ButtonProps {
|
||||
onPress: () => void;
|
||||
title: string;
|
||||
style?: object;
|
||||
}
|
||||
|
||||
const Button = ( { onPress, title, style }: ButtonProps ) => (
|
||||
<Pressable accessibilityRole="button" onPress={onPress}>
|
||||
{/* eslint-disable-next-line no-use-before-define */}
|
||||
<Text style={[styles.button, style]}>{title}</Text>
|
||||
</Pressable>
|
||||
);
|
||||
|
||||
const ShareSheet = () => {
|
||||
const [sharedData, setSharedData] = useState( [] );
|
||||
|
||||
useEffect( () => {
|
||||
// @ts-expect-error data has any type here, but the actual type should come from the library
|
||||
ShareMenuReactView.data().then( ( { data } ) => {
|
||||
setSharedData( data );
|
||||
} );
|
||||
}, [] );
|
||||
|
||||
const {
|
||||
container, text, buttonGroup, destructive
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
} = styles;
|
||||
|
||||
return (
|
||||
<View style={container}>
|
||||
<Text style={text}>
|
||||
{`Share ${sharedData.length} photos with iNaturalist?`}
|
||||
</Text>
|
||||
<View style={buttonGroup}>
|
||||
<Button
|
||||
title="Yes"
|
||||
onPress={( ) => {
|
||||
ShareMenuReactView.continueInApp( );
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
title="No"
|
||||
onPress={( ) => {
|
||||
ShareMenuReactView.dismissExtension( );
|
||||
}}
|
||||
style={destructive}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create( {
|
||||
button: {
|
||||
fontSize: 16,
|
||||
margin: 16
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: "white"
|
||||
},
|
||||
text: {
|
||||
fontSize: 20,
|
||||
textAlign: "center",
|
||||
margin: 16
|
||||
},
|
||||
buttonGroup: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-around",
|
||||
alignItems: "center"
|
||||
},
|
||||
destructive: {
|
||||
color: "red"
|
||||
}
|
||||
} );
|
||||
|
||||
export default ShareSheet;
|
||||
Reference in New Issue
Block a user