Skip to content

Commit 86a8cf3

Browse files
authored
Merge pull request #56 from berty/wikipedia
feat: distributed wikipedia tool
2 parents 32c3440 + 856e53c commit 86a8cf3

File tree

5 files changed

+152
-0
lines changed

5 files changed

+152
-0
lines changed

rn/src/navigation/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
HTMLModule,
2323
IPFSLogs,
2424
Browser,
25+
Wikipedia,
2526
} from '@berty-labs/screens'
2627
import { defaultColors } from '@berty-labs/styles'
2728

@@ -111,6 +112,11 @@ export const Navigation: React.FC = React.memo(() => {
111112
component={Browser}
112113
options={{ ...screenOptions, title: 'Browser' }}
113114
/>
115+
<NavigationStack.Screen
116+
name='Wikipedia'
117+
component={Wikipedia}
118+
options={{ ...screenOptions, title: 'Wikipedia' }}
119+
/>
114120
</NavigationStack.Navigator>
115121
)
116122
})

rn/src/navigation/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ export type ScreensParams = {
1818
}
1919
IPFSLogs: undefined
2020
Browser: undefined
21+
Wikipedia: undefined
2122
}
2223

24+
export type ScreenName = keyof ScreensParams
25+
2326
export type ScreenProps<T extends keyof ScreensParams> = NativeStackScreenProps<ScreensParams, T>
2427

2528
export type ScreenFC<T extends keyof ScreensParams> = React.FC<ScreenProps<T>>

rn/src/screens/Wikipedia.tsx

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import React, { useState } from 'react'
2+
import { Text } from 'react-native'
3+
import WebView from 'react-native-webview'
4+
5+
import { ScreenFC } from '@berty-labs/navigation'
6+
import {
7+
AppScreenContainer,
8+
Card,
9+
LoaderCard,
10+
LoaderScreen,
11+
PressableCard,
12+
} from '@berty-labs/components'
13+
import { useGomobileIPFS } from '@berty-labs/react-redux'
14+
import { defaultColors } from '@berty-labs/styles'
15+
import { useAsyncTransform } from '@berty-labs/reactutil'
16+
17+
const PageLoader = () => <LoaderScreen text='Rendering page...' />
18+
19+
/*
20+
❯ ipfs resolve /ipns/en.wikipedia-on-ipfs.org
21+
/ipfs/bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze
22+
❯ date
23+
Sun Feb 13 16:25:01 CET 2022
24+
*/
25+
const fallbackCID = '/ipfs/bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze'
26+
const fallbackDate = 'Sun Feb 13 16:25:01 CET 2022'
27+
28+
const space = 15
29+
30+
const cardStyle = { marginTop: space, marginHorizontal: space }
31+
32+
// TODO
33+
// - Read wv navigation
34+
// - Allow to pin specific pages to read and distribute them without internet
35+
// - Use global state
36+
// - Store current page and use it as first url
37+
// - Allow to go back
38+
// - Allow to go up
39+
// - Allow to bookmark pages ? since no search could be really painful
40+
41+
export const Wikipedia: ScreenFC<'Wikipedia'> = () => {
42+
const mobileIPFS = useGomobileIPFS()
43+
const [localError, setLocalError] = useState('')
44+
const [loaded, setLoaded] = useState(false)
45+
const [showResolveError, setShowResolveError] = useState(false)
46+
const [resolvedCID, loadedCID, resolveErr] = useAsyncTransform(
47+
async (ac: AbortController) => {
48+
if (!mobileIPFS.apiURL) {
49+
return
50+
}
51+
setShowResolveError(true)
52+
const reply = await fetch(
53+
`${mobileIPFS.apiURL}/api/v0/resolve?arg=${encodeURIComponent(
54+
'/ipns/en.wikipedia-on-ipfs.org',
55+
)}`,
56+
{
57+
signal: ac.signal,
58+
method: 'POST',
59+
},
60+
)
61+
if (!reply.ok) {
62+
throw new Error(`Unexpected status: ${reply.status}\n${await reply.text()}`)
63+
}
64+
const text = await reply.text()
65+
console.log('resolved:', text)
66+
return text
67+
},
68+
[mobileIPFS.apiURL],
69+
)
70+
71+
const cid = resolvedCID || fallbackCID
72+
73+
if (mobileIPFS.status !== 'up') {
74+
return <LoaderScreen text='Waiting for IPFS node...' />
75+
}
76+
77+
return (
78+
<AppScreenContainer>
79+
{showResolveError && !!resolveErr && (
80+
<PressableCard
81+
title='Failed to resolve IPN'
82+
style={cardStyle}
83+
onPress={() => setShowResolveError(false)}
84+
>
85+
<Text style={{ color: defaultColors.text }}>
86+
Using fallback from: {fallbackDate}
87+
{'\n\n'}Tap to hide{`\n\n${resolveErr}`}
88+
</Text>
89+
</PressableCard>
90+
)}
91+
{!!localError && (
92+
<Card style={cardStyle}>
93+
<Text style={{ color: defaultColors.text }}>{`${resolveErr}`}</Text>
94+
</Card>
95+
)}
96+
{!loadedCID && !resolveErr && (
97+
<LoaderCard style={cardStyle} text='Resolving content identifier...' />
98+
)}
99+
{!loaded && <LoaderCard style={cardStyle} text='Loading page...' />}
100+
101+
<WebView
102+
style={{
103+
marginTop: space,
104+
backgroundColor: defaultColors.background,
105+
display: loaded ? undefined : 'none',
106+
}}
107+
source={{
108+
uri: mobileIPFS.gatewayURL + cid,
109+
}}
110+
containerStyle={{ backgroundColor: defaultColors.background }}
111+
renderError={err => (
112+
<Text style={{ color: defaultColors.text }}>{JSON.stringify(err, null, 4)}</Text>
113+
)}
114+
onLoadEnd={() => setLoaded(true)}
115+
onLoadStart={() => {
116+
setLoaded(false)
117+
}}
118+
renderLoading={PageLoader}
119+
onHttpError={err => {
120+
setLocalError(`${err}`)
121+
}}
122+
onError={evt => {
123+
setLocalError(JSON.stringify(evt.nativeEvent, null, 4))
124+
}}
125+
originWhitelist={['*']}
126+
forceDarkOn={true}
127+
allowsBackForwardNavigationGestures={true}
128+
/>
129+
</AppScreenContainer>
130+
)
131+
}

rn/src/screens/home/ToolsList.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,17 @@ export const ToolsList: React.FC<{ searchText: string }> = React.memo(({ searchT
173173

174174
const items = React.useMemo<ToolItemParams[]>(() => {
175175
return [
176+
{
177+
key: 'rn-distributed-wikipedia',
178+
title: 'Wikipedia',
179+
desc: 'Distributed read-only Wikipedia',
180+
onPress: () => navigate('Wikipedia'),
181+
avatar: (
182+
<View style={utfIconContainerStyle}>
183+
<Text style={utfIconStyle}>W</Text>
184+
</View>
185+
),
186+
},
176187
{
177188
key: 'rn-ipfs-web-ui',
178189
title: 'IPFS Web Interface',

rn/src/screens/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ export * from './GoModule'
1010
export * from './HTMLModule'
1111
export * from './IPFSLogs'
1212
export * from './Browser'
13+
export * from './Wikipedia'

0 commit comments

Comments
 (0)