diff --git a/rn/src/navigation/index.tsx b/rn/src/navigation/index.tsx index e32baa93..2ba2825b 100644 --- a/rn/src/navigation/index.tsx +++ b/rn/src/navigation/index.tsx @@ -22,6 +22,7 @@ import { HTMLModule, IPFSLogs, Browser, + Wikipedia, } from '@berty-labs/screens' import { defaultColors } from '@berty-labs/styles' @@ -111,6 +112,11 @@ export const Navigation: React.FC = React.memo(() => { component={Browser} options={{ ...screenOptions, title: 'Browser' }} /> + ) }) diff --git a/rn/src/navigation/types.ts b/rn/src/navigation/types.ts index 81ddae18..0e5f0f6f 100644 --- a/rn/src/navigation/types.ts +++ b/rn/src/navigation/types.ts @@ -18,8 +18,11 @@ export type ScreensParams = { } IPFSLogs: undefined Browser: undefined + Wikipedia: undefined } +export type ScreenName = keyof ScreensParams + export type ScreenProps = NativeStackScreenProps export type ScreenFC = React.FC> diff --git a/rn/src/screens/Wikipedia.tsx b/rn/src/screens/Wikipedia.tsx new file mode 100644 index 00000000..0c65b2f2 --- /dev/null +++ b/rn/src/screens/Wikipedia.tsx @@ -0,0 +1,131 @@ +import React, { useState } from 'react' +import { Text } from 'react-native' +import WebView from 'react-native-webview' + +import { ScreenFC } from '@berty-labs/navigation' +import { + AppScreenContainer, + Card, + LoaderCard, + LoaderScreen, + PressableCard, +} from '@berty-labs/components' +import { useGomobileIPFS } from '@berty-labs/react-redux' +import { defaultColors } from '@berty-labs/styles' +import { useAsyncTransform } from '@berty-labs/reactutil' + +const PageLoader = () => + +/* +❯ ipfs resolve /ipns/en.wikipedia-on-ipfs.org +/ipfs/bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze +❯ date +Sun Feb 13 16:25:01 CET 2022 +*/ +const fallbackCID = '/ipfs/bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze' +const fallbackDate = 'Sun Feb 13 16:25:01 CET 2022' + +const space = 15 + +const cardStyle = { marginTop: space, marginHorizontal: space } + +// TODO +// - Read wv navigation +// - Allow to pin specific pages to read and distribute them without internet +// - Use global state +// - Store current page and use it as first url +// - Allow to go back +// - Allow to go up +// - Allow to bookmark pages ? since no search could be really painful + +export const Wikipedia: ScreenFC<'Wikipedia'> = () => { + const mobileIPFS = useGomobileIPFS() + const [localError, setLocalError] = useState('') + const [loaded, setLoaded] = useState(false) + const [showResolveError, setShowResolveError] = useState(false) + const [resolvedCID, loadedCID, resolveErr] = useAsyncTransform( + async (ac: AbortController) => { + if (!mobileIPFS.apiURL) { + return + } + setShowResolveError(true) + const reply = await fetch( + `${mobileIPFS.apiURL}/api/v0/resolve?arg=${encodeURIComponent( + '/ipns/en.wikipedia-on-ipfs.org', + )}`, + { + signal: ac.signal, + method: 'POST', + }, + ) + if (!reply.ok) { + throw new Error(`Unexpected status: ${reply.status}\n${await reply.text()}`) + } + const text = await reply.text() + console.log('resolved:', text) + return text + }, + [mobileIPFS.apiURL], + ) + + const cid = resolvedCID || fallbackCID + + if (mobileIPFS.status !== 'up') { + return + } + + return ( + + {showResolveError && !!resolveErr && ( + setShowResolveError(false)} + > + + Using fallback from: {fallbackDate} + {'\n\n'}Tap to hide{`\n\n${resolveErr}`} + + + )} + {!!localError && ( + + {`${resolveErr}`} + + )} + {!loadedCID && !resolveErr && ( + + )} + {!loaded && } + + ( + {JSON.stringify(err, null, 4)} + )} + onLoadEnd={() => setLoaded(true)} + onLoadStart={() => { + setLoaded(false) + }} + renderLoading={PageLoader} + onHttpError={err => { + setLocalError(`${err}`) + }} + onError={evt => { + setLocalError(JSON.stringify(evt.nativeEvent, null, 4)) + }} + originWhitelist={['*']} + forceDarkOn={true} + allowsBackForwardNavigationGestures={true} + /> + + ) +} diff --git a/rn/src/screens/home/ToolsList.tsx b/rn/src/screens/home/ToolsList.tsx index 7dddc766..498a3716 100644 --- a/rn/src/screens/home/ToolsList.tsx +++ b/rn/src/screens/home/ToolsList.tsx @@ -173,6 +173,17 @@ export const ToolsList: React.FC<{ searchText: string }> = React.memo(({ searchT const items = React.useMemo(() => { return [ + { + key: 'rn-distributed-wikipedia', + title: 'Wikipedia', + desc: 'Distributed read-only Wikipedia', + onPress: () => navigate('Wikipedia'), + avatar: ( + + W + + ), + }, { key: 'rn-ipfs-web-ui', title: 'IPFS Web Interface', diff --git a/rn/src/screens/index.ts b/rn/src/screens/index.ts index a13657ef..578e1f89 100644 --- a/rn/src/screens/index.ts +++ b/rn/src/screens/index.ts @@ -10,3 +10,4 @@ export * from './GoModule' export * from './HTMLModule' export * from './IPFSLogs' export * from './Browser' +export * from './Wikipedia'