diff --git a/.github/workflows/eas-update.yml b/.github/workflows/eas-update.yml new file mode 100644 index 0000000..c8ac563 --- /dev/null +++ b/.github/workflows/eas-update.yml @@ -0,0 +1,40 @@ +name: preview +on: pull_request + +jobs: + update: + name: EAS Update + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + steps: + - name: Check for EXPO_TOKEN + run: | + if [ -z "${{ secrets.EXPO_TOKEN }}" ]; then + echo "You must provide an EXPO_TOKEN secret linked to this project's Expo account in this repo's secrets. Learn more: https://docs.expo.dev/eas-update/github-actions" + exit 1 + fi + + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: 18.x + cache: 'npm' + + - name: Setup EAS + uses: expo/expo-github-action@v8 + with: + eas-version: latest + token: ${{ secrets.EXPO_TOKEN }} + + - name: Install dependencies + run: npm install + + - name: Create preview + uses: expo/expo-github-action/preview@v8 + with: + command: eas update --auto diff --git a/.gitignore b/.gitignore index ae6d12e..4b1331f 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,6 @@ expo-env.d.ts storage/** /ios -/android \ No newline at end of file +/android + +.idea diff --git a/app.json b/app.json index aac748c..c013f44 100644 --- a/app.json +++ b/app.json @@ -33,13 +33,27 @@ "plugins": [ [ "expo-router" - ] + ], + "react-native-image-marker" ], "experiments": { "typedRoutes": true }, "runtimeVersion": { "policy": "appVersion" + }, + "extra": { + "router": { + "origin": false + }, + "eas": { + "projectId": "b19fc96e-91a2-416a-a658-9271e4d93855" + } + }, + "owner": "robertogolee", + "updates": { + "url": "https://u.expo.dev/b19fc96e-91a2-416a-a658-9271e4d93855" } + } } diff --git a/app/works/[id]/index.tsx b/app/works/[id]/index.tsx index 40af1d8..7d440d2 100644 --- a/app/works/[id]/index.tsx +++ b/app/works/[id]/index.tsx @@ -14,6 +14,8 @@ import { useFavStatusMutation } from "@/data/hooks/useFavStatusMutation"; import colors from "@/constants/colors"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { LoadingShade } from "@/components/LoadingShade"; +import * as Sharing from "expo-sharing"; +import ImagePicker from "react-native-image-crop-picker"; export default function DisplayWork() { const dimensions = useWindowDimensions(); @@ -35,6 +37,10 @@ export default function DisplayWork() { // update fav status const favMutation = useFavStatusMutation(); + async function share() { + await Sharing.shareAsync(work.images.web.url); + } + return ( {work?.title} - + + + + @@ -111,4 +120,4 @@ export default function DisplayWork() { function stripTags(htmlish: string) { return htmlish.replace(/<[^>]*>?/gm, ""); -} \ No newline at end of file +} diff --git a/app/works/[id]/share.tsx b/app/works/[id]/share.tsx new file mode 100644 index 0000000..f813a82 --- /dev/null +++ b/app/works/[id]/share.tsx @@ -0,0 +1,130 @@ +import {View, Text, useWindowDimensions, Pressable, Platform} from "react-native"; +import {Stack, useLocalSearchParams} from "expo-router"; +import {Image} from "expo-image"; +import {useWorkByIdQuery} from "@/data/hooks/useWorkByIdQuery"; +import {LoadingShade} from "@/components/LoadingShade"; +import ImagePicker from "react-native-image-crop-picker"; +import {useState} from "react"; +import * as Sharing from "expo-sharing"; +import Marker, {ImageFormat, Position, TextBackgroundType} from "react-native-image-marker"; + +export default function ShareWork() { + const dimensions = useWindowDimensions(); + const {id} = useLocalSearchParams<{ id: string }>(); + const {data: work, isLoading} = useWorkByIdQuery(id!); + + function normalizeFilePath(path: string) { + if (Platform.OS === "android" && !path.startsWith("file://")) { + return `file://${path}`; + } + return path; + } + + const [editedImagePath, setEditedImagePath] = useState( + undefined + ); + + async function crop() { + + const image = await ImagePicker.openCropper({ + path: work.images.web.url, + width: 300, + height: 300, + mediaType: "photo", + }); + + const markedImagePath = await Marker.markText({ + backgroundImage: { + src: image.path, + scale: 1, + }, + + watermarkTexts: [ + { + text: "#cma", + position: { + position: Position.bottomRight, + }, + style: { + color: "#fff", + fontSize: 20, + textBackgroundStyle: { + type: TextBackgroundType.none, + color: "#000", + paddingX: 16, + paddingY: 6, + }, + }, + }, + ], + quality: 100, + filename: image.filename, + saveFormat: ImageFormat.jpg, + }); + + setEditedImagePath(normalizeFilePath(markedImagePath)); + } + + async function share() { + editedImagePath && await Sharing.shareAsync(editedImagePath); + } + + + return ( + + + + + Share a clip of this work with your friends. + + + + + + + + + + ); +} + +function RoundButton({ + title, + onPress, + disabled = false, + }: { + title: string; + onPress: () => void; + disabled?: boolean; +}) { + return ( + + {title} + + ); +}