Skip to content

Commit

Permalink
feat: ios preprocessing page (url metadata) (#145)
Browse files Browse the repository at this point in the history
  • Loading branch information
achorein committed Dec 21, 2024
1 parent c4440fd commit b27fce9
Show file tree
Hide file tree
Showing 16 changed files with 431 additions and 139 deletions.
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,14 @@ export default const App = () => {
const { shareIntent } = useShareIntent();
```

| attribute | description | example |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `shareIntent.text` | raw text from text/weburl (ios) and text/\* (android) | "`some text`", "`http://example.com`", "`Hey, Click on my link : http://example.com/nickname`" |
| `shareIntent.webUrl` | link extracted from raw text | `null`, "`http://example.com`", "`http://example.com/nickname`" |
| `shareIntent.files` | image / movies / audio / files with name, path, mimetype, size (in octets) and image/video dimensions (width/height/duration) | `[{ path: "file:///local/path/filename", mimeType: "image/jpeg", fileName: "originalFilename.jpg", size: 2567402, width: 800, height: 600 }, { path: "file:///local/path/filename", mimeType: "video/mp4", fileName: "originalFilename.mp4", size: 2567402, width: 800, height: 600, duration: 20000 }]` |
| `shareIntent.meta` | meta object which contains extra information about the share intent | `{ title: "My cool blog article" }` |
| `shareIntent.meta.title` | optional title property sent by other app. Currently only filled on Android | `My cool blog article` |
| attribute | description | example |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `shareIntent.text` | raw text from text/weburl (ios) and text/\* (android) | "`some text`", "`http://example.com`", "`Hey, Click on my link : http://example.com/nickname`" |
| `shareIntent.webUrl` | link extracted from raw text | `null`, "`http://example.com`", "`http://example.com/nickname`" |
| `shareIntent.files` | image / movies / audio / files with name, path, mimetype, size (in octets) and image/video dimensions (width/height/duration) | `[{ path: "file:///local/path/filename", mimeType: "image/jpeg", fileName: "originalFilename.jpg", size: 2567402, width: 800, height: 600 }, { path: "file:///local/path/filename", mimeType: "video/mp4", fileName: "originalFilename.mp4", size: 2567402, width: 800, height: 600, duration: 20000 }]` |
| `shareIntent.meta` | meta object which contains extra information about the share intent | `{ title: "My cool blog article", "og:image": "https://.../image.png" }` |
| `shareIntent.meta.title` | optional title property sent by other app (available on Android and when `NSExtensionActivationSupportsWebPageWithMaxCount` is enabled on iOS) | `My cool blog article` |
| `shareIntent.meta.xxx` | list all webpage metadata available in meta tags `<meta name=""... />` (iOS only, available with `NSExtensionActivationSupportsWebPageWithMaxCount`) | |

#### Customize Content Types in `app.json`

Expand Down Expand Up @@ -188,8 +189,9 @@ Simply choose content types you need :
| androidIntentFilters | **one file sharing** array of MIME types :`"text/*"` / `"image/*"` / `"video/*"` / `"*/*"`<br/>_default value_: `["text/*"]` (text and url) |
| androidMultiIntentFilters | **multiple files sharing** array of MIME types : `"image/*"` / `"video/*"` / `"audio/*`/ `"*/*"`<br/>_default value_: `[]` |
| androidMainActivityAttributes | _default value_: `{ "android:launchMode": "singleTask" }` |
| preprocessorInjectJS | Add javascript to webpage preprocessor before the share extension is called (cf [Accessing a Webpage](https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW12)).<br/>Example: <code>preprocessorInjectJS: "metas['og\\:image'] = metas['og\\:image'] &#124;&#124; document.querySelector('img#seo-image')?.getAttribute('src')"</code> |
| disableAndroid | Disable the android share intent. Useful if you want to use a custom implementation. _default value_: `false` |
| disableIOS | Disable the ios share extension. Useful if you want to use a custom implementation (ex: iOS custom view). _default value_: `false` |
| disableIOS | Disable the ios share extension. Useful if you want to use a custom implementation (ex: [iOS Custom View](#ios-custom-view-)). _default value_: `false` |

### Expo Router

Expand Down
49 changes: 45 additions & 4 deletions example/basic/App.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,39 @@
import { Button, Image, StyleSheet, Text, View } from "react-native";

import { useShareIntent, ShareIntentFile } from "expo-share-intent";
import {
useShareIntent,
ShareIntentFile,
ShareIntent,
} from "expo-share-intent";
import { Fragment } from "react";

const WebUrlComponent = ({ shareIntent }: { shareIntent: ShareIntent }) => {
return (
<View
style={[
styles.gap,
styles.row,
{ borderWidth: 1, borderRadius: 5, height: 102 },
]}
>
<Image
source={
shareIntent.meta?.["og:image"]
? { uri: shareIntent.meta?.["og:image"] }
: undefined
}
style={[styles.icon, styles.gap, { borderRadius: 5 }]}
/>
<View style={{ flexShrink: 1, padding: 5 }}>
<Text style={[styles.gap]}>
{shareIntent.meta?.title || "<NO TITLE>"}
</Text>
<Text style={styles.gap}>{shareIntent.webUrl}</Text>
</View>
</View>
);
};

export default function App() {
const { hasShareIntent, shareIntent, resetShareIntent, error } =
useShareIntent({
Expand All @@ -22,8 +53,8 @@ export default function App() {

{/* TEXT and URL */}
{!!shareIntent.text && <Text style={styles.gap}>{shareIntent.text}</Text>}
{!!shareIntent.meta?.title && (
<Text style={styles.gap}>{JSON.stringify(shareIntent.meta)}</Text>
{shareIntent?.type === "weburl" && (
<WebUrlComponent shareIntent={shareIntent} />
)}

{/* FILES */}
Expand Down Expand Up @@ -69,6 +100,7 @@ const styles = StyleSheet.create({
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
paddingHorizontal: 10,
},
logo: {
width: 75,
Expand All @@ -79,7 +111,16 @@ const styles = StyleSheet.create({
width: 300,
height: 200,
resizeMode: "contain",
// backgroundColor: "lightgray",
},
icon: {
width: 100,
height: 100,
resizeMode: "contain",
backgroundColor: "lightgray",
},
row: {
flexDirection: "row",
gap: 10,
},
gap: {
marginBottom: 20,
Expand Down
4 changes: 1 addition & 3 deletions example/basic/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,9 @@
"NSExtensionActivationSupportsFileWithMaxCount": 1
},
"iosShareExtensionName": "ExpoShareIntent Example Extension",
"iosAppGroupIdentifier": "customgroup.expo.modules.exposhareintent.example",
"androidIntentFilters": ["text/*", "image/*", "video/*"],
"androidMultiIntentFilters": ["image/*"],
"disableIOS": false,
"disableAndroid": false
"preprocessorInjectJS": "metas['og\\:image'] = metas['og\\:image'] || document.querySelector('img#main-image')?.getAttribute('src') ;"
}
],
["expo-updates"]
Expand Down
2 changes: 2 additions & 0 deletions example/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"test:fix": "expo install --fix",
"doctor": "npx --yes expo-doctor@latest",
"lint": "eslint .",
"open:ios": "open -a \"Xcode\" ios",
"open:android": "open -a \"Android Studio\" android",
"postinstall": "patch-package"
},
"dependencies": {
Expand Down
47 changes: 44 additions & 3 deletions example/expo-router/app/shareintent.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,37 @@
import { Button, Image, StyleSheet, Text, View } from "react-native";

import { useRouter } from "expo-router";
import { useShareIntentContext } from "expo-share-intent";
import {
ShareIntent as ShareIntentType,
useShareIntentContext,
} from "expo-share-intent";

const WebUrlComponent = ({ shareIntent }: { shareIntent: ShareIntentType }) => {
return (
<View
style={[
styles.gap,
styles.row,
{ borderWidth: 1, borderRadius: 5, height: 102 },
]}
>
<Image
source={
shareIntent.meta?.["og:image"]
? { uri: shareIntent.meta?.["og:image"] }
: undefined
}
style={[styles.icon, styles.gap, { borderRadius: 5 }]}
/>
<View style={{ flexShrink: 1, padding: 5 }}>
<Text style={[styles.gap]}>
{shareIntent.meta?.title || "<NO TITLE>"}
</Text>
<Text style={styles.gap}>{shareIntent.webUrl}</Text>
</View>
</View>
);
};

export default function ShareIntent() {
const router = useRouter();
Expand All @@ -21,8 +51,8 @@ export default function ShareIntent() {
</Text>
)}
{!!shareIntent.text && <Text style={styles.gap}>{shareIntent.text}</Text>}
{!!shareIntent.meta?.title && (
<Text style={styles.gap}>{JSON.stringify(shareIntent.meta)}</Text>
{shareIntent?.type === "weburl" && (
<WebUrlComponent shareIntent={shareIntent} />
)}
{shareIntent?.files?.map((file) => (
<Image
Expand All @@ -46,6 +76,7 @@ const styles = StyleSheet.create({
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
paddingHorizontal: 10,
},
logo: {
width: 75,
Expand All @@ -57,6 +88,16 @@ const styles = StyleSheet.create({
height: 200,
resizeMode: "contain",
},
icon: {
width: 100,
height: 100,
resizeMode: "contain",
backgroundColor: "lightgray",
},
row: {
flexDirection: "row",
gap: 10,
},
gap: {
marginBottom: 20,
},
Expand Down
Loading

0 comments on commit b27fce9

Please sign in to comment.