-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generated by create-expo-app 2.1.1.
- Loading branch information
0 parents
commit 7fd892f
Showing
17 changed files
with
370 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { StatusBar } from 'expo-status-bar'; | ||
import { StyleSheet, Text, View } from 'react-native'; | ||
|
||
import Main from './src/Main'; | ||
|
||
export default function App() { | ||
return ( | ||
<View style={styles.container}> | ||
<Main /> | ||
<StatusBar style="auto" /> | ||
</View> | ||
); | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
container: { | ||
flex: 1, | ||
marginTop: 64, | ||
backgroundColor: '#fff', | ||
alignItems: 'center', | ||
justifyContent: 'center', | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"expo": { | ||
"name": "rnsuspense", | ||
"slug": "rnsuspense", | ||
"version": "1.0.0", | ||
"orientation": "portrait", | ||
"icon": "./assets/icon.png", | ||
"userInterfaceStyle": "light", | ||
"splash": { | ||
"image": "./assets/splash.png", | ||
"resizeMode": "contain", | ||
"backgroundColor": "#ffffff" | ||
}, | ||
"assetBundlePatterns": [ | ||
"**/*" | ||
], | ||
"ios": { | ||
"supportsTablet": true | ||
}, | ||
"android": { | ||
"adaptiveIcon": { | ||
"foregroundImage": "./assets/adaptive-icon.png", | ||
"backgroundColor": "#ffffff" | ||
} | ||
}, | ||
"web": { | ||
"favicon": "./assets/favicon.png" | ||
} | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'], | ||
}; | ||
}; |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "rnsuspense", | ||
"version": "1.0.0", | ||
"main": "node_modules/expo/AppEntry.js", | ||
"scripts": { | ||
"start": "expo start", | ||
"android": "expo start --android", | ||
"ios": "expo start --ios", | ||
"web": "expo start --web" | ||
}, | ||
"dependencies": { | ||
"expo": "~49.0.15", | ||
"expo-status-bar": "~1.6.0", | ||
"react": "18.2.0", | ||
"react-error-boundary": "^4.0.11", | ||
"react-native": "0.72.6" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.20.0", | ||
"@types/react": "~18.2.14", | ||
"typescript": "^5.1.3" | ||
}, | ||
"private": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { StyleSheet, Text, View } from 'react-native'; | ||
|
||
import { fetchData } from './data'; | ||
import { use } from './useHook'; | ||
|
||
// Note: this component is written using an experimental API | ||
// that's not yet available in stable versions of React. | ||
|
||
// For a realistic example you can follow today, try a framework | ||
// that's integrated with Suspense, like Relay or Next.js. | ||
|
||
export default function Albums({ artistId }: { artistId: string }) { | ||
const albums = use(fetchData(`/${artistId}/albums`)) ?? []; | ||
return ( | ||
<View style={styles.listContainer}> | ||
{albums.map((album) => ( | ||
<View style={styles.listItem} key={album.id}> | ||
<Text style={styles.listItemText}> | ||
{album.title} ({album.year}) | ||
</Text> | ||
</View> | ||
))} | ||
</View> | ||
); | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
listContainer: { | ||
flex: 1, | ||
}, | ||
listItem: { padding: 16, borderBottomWidth: 1, borderBottomColor: '#ccc' }, | ||
listItemText: { fontSize: 16 }, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { Suspense } from 'react'; | ||
import { ScrollView, StyleSheet, Text } from 'react-native'; | ||
import Albums from './Albums'; | ||
|
||
import type { Artist } from './types'; | ||
|
||
export default function ArtistPage({ artist }: { artist: Artist }) { | ||
return ( | ||
<ScrollView> | ||
<Text style={styles.artistName}>{artist.name}</Text> | ||
<Suspense fallback={<Loading />}> | ||
<Albums artistId={artist.id} /> | ||
</Suspense> | ||
</ScrollView> | ||
); | ||
} | ||
|
||
function Loading() { | ||
return <Text style={styles.loadingText}>🌀 Loading...</Text>; | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
artistName: { | ||
fontSize: 24, | ||
textAlign: 'center', | ||
}, | ||
loadingText: { | ||
fontSize: 20, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { useState } from 'react'; | ||
import { ErrorBoundary } from 'react-error-boundary'; | ||
import { Button, Text } from 'react-native'; | ||
|
||
import ArtistPage from './ArtistPage'; | ||
import type { Artist } from './types'; | ||
|
||
export default function Main() { | ||
const [artist, setArtist] = useState<Artist>(null); | ||
|
||
if (artist != null) { | ||
return ( | ||
<ErrorBoundary fallbackRender={errorFallbackRenderer}> | ||
<ArtistPage artist={artist} /> | ||
</ErrorBoundary> | ||
); | ||
} else { | ||
return ( | ||
<> | ||
<Button | ||
title="Open The Beatles artist page" | ||
onPress={() => setArtist({ id: 'the-beatles', name: 'The Beatles' })} | ||
/> | ||
<Button | ||
title="Open non-existed artist page" | ||
onPress={() => setArtist({ id: 'unknown', name: 'Unknown' })} | ||
/> | ||
</> | ||
); | ||
} | ||
} | ||
|
||
function errorFallbackRenderer({ error }: { error: Error }) { | ||
return <Text>Error Boundary: {error.message}</Text>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// Note: the way you would do data fetching depends on | ||
// the framework that you use together with Suspense. | ||
// Normally, the caching logic would be inside a framework. | ||
|
||
import type { Album } from './types'; | ||
|
||
let cache = new Map(); | ||
|
||
export function fetchData(url: string): Promise<Album[]> { | ||
if (!cache.has(url)) { | ||
cache.set(url, getData(url)); | ||
} | ||
return cache.get(url); | ||
} | ||
|
||
async function getData(url: string): Promise<Album[]> { | ||
if (url === '/the-beatles/albums') { | ||
return await getAlbums(); | ||
} else { | ||
throw Error('Not implemented'); | ||
} | ||
} | ||
|
||
async function getAlbums(): Promise<Album[]> { | ||
// Add a fake delay to make waiting noticeable. | ||
await new Promise((resolve) => { | ||
setTimeout(resolve, 3000); | ||
}); | ||
|
||
return [ | ||
{ | ||
id: 13, | ||
title: 'Let It Be', | ||
year: 1970, | ||
}, | ||
{ | ||
id: 12, | ||
title: 'Abbey Road', | ||
year: 1969, | ||
}, | ||
{ | ||
id: 11, | ||
title: 'Yellow Submarine', | ||
year: 1969, | ||
}, | ||
{ | ||
id: 10, | ||
title: 'The Beatles', | ||
year: 1968, | ||
}, | ||
{ | ||
id: 9, | ||
title: 'Magical Mystery Tour', | ||
year: 1967, | ||
}, | ||
{ | ||
id: 8, | ||
title: "Sgt. Pepper's Lonely Hearts Club Band", | ||
year: 1967, | ||
}, | ||
{ | ||
id: 7, | ||
title: 'Revolver', | ||
year: 1966, | ||
}, | ||
{ | ||
id: 6, | ||
title: 'Rubber Soul', | ||
year: 1965, | ||
}, | ||
{ | ||
id: 5, | ||
title: 'Help!', | ||
year: 1965, | ||
}, | ||
{ | ||
id: 4, | ||
title: 'Beatles For Sale', | ||
year: 1964, | ||
}, | ||
{ | ||
id: 3, | ||
title: "A Hard Day's Night", | ||
year: 1964, | ||
}, | ||
{ | ||
id: 2, | ||
title: 'With The Beatles', | ||
year: 1963, | ||
}, | ||
{ | ||
id: 1, | ||
title: 'Please Please Me', | ||
year: 1963, | ||
}, | ||
]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export interface Album { | ||
id: number; | ||
title: string; | ||
year: number; | ||
} | ||
|
||
export interface Artist { | ||
id: string; | ||
name: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// Referenced from https://github.com/vercel/swr/blob/1d8110900d1aee3747199bfb377b149b7ff6848e/_internal/src/types.ts#L27-L31 | ||
type ReactUsePromise<T, E extends Error = Error> = Promise<T> & { | ||
status?: 'pending' | 'fulfilled' | 'rejected'; | ||
value?: T; | ||
reason?: E; | ||
}; | ||
|
||
// Referenced from https://github.com/reactjs/react.dev/blob/6570e6cd79a16ac3b1a2902632eddab7e6abb9ad/src/content/reference/react/Suspense.md | ||
/** | ||
* A custom hook like `React.use` hook using private Suspense API. | ||
*/ | ||
export function use<T>(promise: Promise<T> | ReactUsePromise<T>) { | ||
if (isReactUsePromise(promise)) { | ||
if (promise.status === 'fulfilled') { | ||
return promise.value; | ||
} else if (promise.status === 'rejected') { | ||
throw promise.reason; | ||
} else if (promise.status === 'pending') { | ||
throw promise; | ||
} | ||
throw new Error('Promise is in an invalid state'); | ||
} | ||
|
||
const suspensePromise = promise as ReactUsePromise<T>; | ||
suspensePromise.status = 'pending'; | ||
suspensePromise.then( | ||
(result: T) => { | ||
suspensePromise.status = 'fulfilled'; | ||
suspensePromise.value = result; | ||
}, | ||
(reason) => { | ||
suspensePromise.status = 'rejected'; | ||
suspensePromise.reason = reason; | ||
} | ||
); | ||
throw suspensePromise; | ||
} | ||
|
||
function isReactUsePromise<T>( | ||
promise: Promise<T> | ReactUsePromise<T> | ||
): promise is ReactUsePromise<T> { | ||
return typeof promise === 'object' && promise !== null && 'status' in promise; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"compilerOptions": {}, | ||
"extends": "expo/tsconfig.base" | ||
} |