Skip to content

Commit

Permalink
re-init expo app
Browse files Browse the repository at this point in the history
  • Loading branch information
juliusmarminge committed Jan 29, 2024
1 parent 6194751 commit 3df2b09
Show file tree
Hide file tree
Showing 13 changed files with 339 additions and 0 deletions.
41 changes: 41 additions & 0 deletions examples/minimal_expo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files

# dependencies
node_modules/

# Expo
.expo/
dist/
web-build/

# Native
*.orig.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision

# Metro
.metro-health-check*

# debug
npm-debug.*
yarn-debug.*
yarn-error.*

# macOS
.DS_Store
*.pem

# local env files
.env*.local

# typescript
*.tsbuildinfo

# @generated expo-cli sync-2b81b286409207a5da26e14c78851eb30d8ccbdb
# The following patterns were generated by expo-cli

expo-env.d.ts
# @end expo-cli
35 changes: 35 additions & 0 deletions examples/minimal_expo/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { ExpoConfig } from "expo/config";

export default (): ExpoConfig => ({
name: "Minimal Expo x UploadThing",
slug: "minimal-expo",
version: "1.0.0",
orientation: "portrait",
icon: "./assets/icon.png",
scheme: "myapp",
userInterfaceStyle: "automatic",
splash: {
image: "./assets/splash.jpg",
resizeMode: "contain",
backgroundColor: "#ffffff",
},
assetBundlePatterns: ["**/*"],
ios: {
supportsTablet: true,
},
android: {
adaptiveIcon: {
foregroundImage: "./assets/icon.png",
backgroundColor: "#ffffff",
},
},

web: {
bundler: "metro",
output: "server",
},
plugins: ["expo-router"],
experiments: {
typedRoutes: true,
},
});
17 changes: 17 additions & 0 deletions examples/minimal_expo/app/_layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Stack } from "expo-router";
import { StatusBar } from "expo-status-bar";

export default function RootLayout() {
return (
<>
<Stack
screenOptions={{
headerStyle: {
backgroundColor: "#D73328",
},
}}
/>
<StatusBar />
</>
);
}
88 changes: 88 additions & 0 deletions examples/minimal_expo/app/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { useMemo } from "react";
import * as ImagePicker from "expo-image-picker";
import { Stack } from "expo-router";
import { Button, StyleSheet, Text, View } from "react-native";

import { generateReactHelpers } from "@uploadthing/react/native";
import { generatePermittedFileTypes } from "uploadthing/client";

import type { UploadRouter } from "./uploadthing+api";

const { useUploadThing } = generateReactHelpers<UploadRouter>({
url: new URL("http://localhost:8081/uploadthing"),
});

export default function ModalScreen() {
const { startUpload, permittedFileInfo } = useUploadThing("videoAndImage");
const { fileTypes, multiple } = generatePermittedFileTypes(
permittedFileInfo?.config,
);

const mediaTypes = useMemo(() => {
const allowsImages = fileTypes.includes("image");
const allowsVideos = fileTypes.includes("video");

if (allowsImages && allowsVideos) return ImagePicker.MediaTypeOptions.All;
if (allowsImages) return ImagePicker.MediaTypeOptions.Images;
if (allowsVideos) return ImagePicker.MediaTypeOptions.Videos;
}, [fileTypes]);

console.log({ fileTypes, multiple });

return (
<>
<Stack.Screen options={{ title: "Home Page" }} />
<View style={styles.container}>
<Text style={styles.title}>Modal</Text>
<Button
title="Open Gallery"
onPress={async () => {
const response = await ImagePicker.launchImageLibraryAsync({
mediaTypes,
allowsEditing: true,
allowsMultipleSelection: multiple,
});
if (response.canceled) {
console.log("User cancelled image picker");
return;
}
const files = await Promise.all(
response.assets.map(async (asset) => {
const blob = await fetch(asset.uri).then((r) => r.blob());
const name =
asset.fileName ??
asset.uri.split("/").pop() ??
"unknown-filename";
return new File([blob], name, { type: asset.type });
}),
);
try {
const utresponse = await startUpload(files);
console.log({ utresponse });
} catch (e) {
console.log(e);
}
}}
/>
<View style={styles.separator} />
</View>
</>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
title: {
fontSize: 20,
fontWeight: "bold",
},
separator: {
marginVertical: 30,
height: 1,
width: "80%",
},
});
41 changes: 41 additions & 0 deletions examples/minimal_expo/app/uploadthing+api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { createRouteHandler, createUploadthing } from "uploadthing/server";
import type { FileRouter } from "uploadthing/server";

const f = createUploadthing();

const uploadRouter = {
videoAndImage: f({
image: {
maxFileSize: "4MB",
maxFileCount: 4,
},
video: {
maxFileSize: "16MB",
},
})
.middleware(({ req }) => {
// Check some condition based on the incoming requrest
req;
//^?
// if (!req.headers["x-some-header"]) {
// throw new Error("x-some-header is required");
// }

// Return some metadata to be stored with the file
return { foo: "bar" as const };
})
.onUploadComplete(({ file, metadata }) => {
metadata;
// ^?
console.log("upload completed", file);
}),
} satisfies FileRouter;

export type UploadRouter = typeof uploadRouter;

export const { GET, POST } = createRouteHandler({
router: uploadRouter,
config: {
uploadthingSecret: "sk_live_xxx",
},
});
Binary file added examples/minimal_expo/assets/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/minimal_expo/assets/splash.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions examples/minimal_expo/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = function (api) {
api.cache(true);
return {
presets: ["babel-preset-expo"],
};
};
47 changes: 47 additions & 0 deletions examples/minimal_expo/metro.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const { getDefaultConfig } = require("expo/metro-config");
const { FileStore } = require("metro-cache");
const path = require("path");

module.exports = withTurborepoManagedCache(
withMonorepoPaths(getDefaultConfig(__dirname)),
);

/**
* Add the monorepo paths to the Metro config.
* This allows Metro to resolve modules from the monorepo.
*
* @see https://docs.expo.dev/guides/monorepos/#modify-the-metro-config
* @param {import('expo/metro-config').MetroConfig} config
* @returns {import('expo/metro-config').MetroConfig}
*/
function withMonorepoPaths(config) {
const projectRoot = __dirname;
const workspaceRoot = path.resolve(projectRoot, "../..");

// #1 - Watch all files in the monorepo
config.watchFolders = [workspaceRoot];

// #2 - Resolve modules within the project's `node_modules` first, then all monorepo modules
config.resolver.nodeModulesPaths = [
path.resolve(projectRoot, "node_modules"),
path.resolve(workspaceRoot, "node_modules"),
];

return config;
}

/**
* Move the Metro cache to the `node_modules/.cache/metro` folder.
* This repository configured Turborepo to use this cache location as well.
* If you have any environment variables, you can configure Turborepo to invalidate it when needed.
*
* @see https://turbo.build/repo/docs/reference/configuration#env
* @param {import('expo/metro-config').MetroConfig} config
* @returns {import('expo/metro-config').MetroConfig}
*/
function withTurborepoManagedCache(config) {
config.cacheStores = [
new FileStore({ root: path.join(__dirname, "node_modules/.cache/metro") }),
];
return config;
}
42 changes: 42 additions & 0 deletions examples/minimal_expo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "minimal-expo",
"main": "expo-router/entry",
"version": "1.0.0",
"scripts": {
"dev": "expo start --ios",
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios"
},
"jest": {
"preset": "jest-expo"
},
"dependencies": {
"@expo/vector-icons": "^14.0.0",
"@react-navigation/native": "^6.0.2",
"@uploadthing/mime-types": "^0.2.2",
"@uploadthing/react": "^6.2.2",
"expo": "~50.0.4",
"expo-font": "~11.10.2",
"expo-image-picker": "^14.7.1",
"expo-linking": "~6.2.2",
"expo-router": "~3.4.6",
"expo-splash-screen": "~0.26.3",
"expo-status-bar": "~1.11.1",
"expo-system-ui": "~2.9.3",
"expo-web-browser": "~12.8.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.73.2",
"react-native-safe-area-context": "4.8.2",
"react-native-screens": "~3.29.0",
"uploadthing": "^6.3.1"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@types/react": "18.2.33",
"typescript": "^5.3.3"
},
"private": true
}
10 changes: 10 additions & 0 deletions examples/minimal_expo/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true,
"paths": {
"~/*": ["./*"]
}
},
"include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts"]
}
11 changes: 11 additions & 0 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@
"default": "./hooks/index.js"
}
},
"./native": {
"import": {
"types": "./native/index.d.mts",
"default": "./native/index.mjs"
},
"require": {
"types": "./native/index.d.ts",
"default": "./native/index.js"
}
},
"./next-ssr-plugin": {
"import": {
"types": "./next-ssr-plugin/index.d.mts",
Expand All @@ -42,6 +52,7 @@
"files": [
"dist",
"hooks",
"native",
"next-ssr-plugin"
],
"publishConfig": {
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/native.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { generateReactHelpers } from "./useUploadThing";

0 comments on commit 3df2b09

Please sign in to comment.