Skip to content

Commit

Permalink
feat: Add IPFS, Swarm as Another Providers for The File Service into …
Browse files Browse the repository at this point in the history
…Mask (DimensionDev#5195)

* try to support ipfs and swarm

* add ipfs and swarm provider

* support ipfs and swarm

* add ipfs and swarm

* fix

* change

* fix

* change

* fix bee-js type error

* fix bee-js type error

* fix i18n error

* hidden Meson CDN button when provider is not arweave

* fix lint error

* fix spell check error

* fix lint error

* fix lint error

* refactor: provider agent

* refactor: provider agent

* refactor: provider agent

* refactor: provider agent

* refactor: typo key cast

* eslint fix

* fix: spell error

* fix: spell error

* fix: revert cspell.json

* fix: add comment, use lodash

* fix: change

* fix: change

* fix: lint error

* chore: more patch

* chore: more patch

* fix: remove duplicate checkbox

* refactor: delay initialization

* fix: add provider to metadata

* refactor: using createLookupTableResolver

* fix: typo

* refactor: remove unuse code

* fix: update frozen-lockfile

* fix: update frozen-lockfile

* fix lint errors

* Update pnpm-lock.yaml

* fix: pnpm-lock

* fix: pnpm no-frozen-lockfile

* fix: lint error

* fix: import JWKInterface from arweave directly

* fix: update

* fix: update

* fix: update

* fix: update

* fix: update

* chore: try fix lockfile

* fix: update color

* fix: listen dialog close

* fix: lint error

* fix: text color, button width

* fix: text color, button width

* fix: text color, button width

* fix: text color, button width

* fix: rename

* fix: update pnpm-lock

* fix: add webpack rule esm module fully specified false

* fix: limit specify package

* chore: update broken package

* chore: update broken package

Co-authored-by: Jack Works <[email protected]>
Co-authored-by: Suji Yan <[email protected]>
Co-authored-by: Suji Yan <[email protected]>
Co-authored-by: guanbinrui <[email protected]>
  • Loading branch information
5 people authored Feb 21, 2022
1 parent 9570eec commit 47253c5
Show file tree
Hide file tree
Showing 19 changed files with 884 additions and 125 deletions.
2 changes: 2 additions & 0 deletions .pnpmfile.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const approvedList = new Map([
['html-parse-stringify2', 'github:locize/html-parse-stringify2'],
/* cspell:disable-next-line */
['async-eventemitter', 'github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c'],
// Introduced by ipfs-utils
['node-fetch', 'https://registry.npmjs.org/@achingbrain/node-fetch/-/node-fetch-2.6.7.tgz'],
])

/**
Expand Down
2 changes: 2 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"elec",
"encryptedmsg",
"endregion",
"ethersphere",
"ethersproject",
"eustatius",
"everytime",
Expand Down Expand Up @@ -106,6 +107,7 @@
"imtokenv2",
"investables",
"ipfs",
"IPFSHTTP",
"ipfsurl",
"ittr",
"jailbroken",
Expand Down
4 changes: 4 additions & 0 deletions packages/plugins/FileService/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@
"types": "./dist/index.d.ts",
"dependencies": {
"@dimensiondev/common-protocols": "1.6.0-20210723072221-8f46a92",
"@ethersphere/bee-js": "^3.3.1",
"@masknet/icons": "workspace:*",
"@masknet/plugin-infra": "workspace:*",
"@masknet/plugin-wallet": "workspace:*",
"@masknet/shared": "workspace:*",
"@masknet/shared-base": "workspace:*",
"@masknet/theme": "workspace:*",
"@msgpack/msgpack": "^2.7.2",
"@masknet/web3-kit": "workspace:*",
"arweave": "^1.10.3",
"ipfs-http-client": "^54.0.2",
"urlcat": "^2.0.4",
"date-fns": "^2.28.0",
"react-feather": "^2.0.9",
"react-router-dom": "5",
Expand Down
20 changes: 18 additions & 2 deletions packages/plugins/FileService/src/SNSAdaptor/MainDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { WalletMessages } from '@masknet/plugin-wallet'
import { Entry } from './components'
import { META_KEY_2 } from '../constants'
import { Exchange } from './hooks/Exchange'
import type { FileInfo } from '../types'
import type { FileInfo, DialogCloseCallback } from '../types'
import { useCompositionContext } from '@masknet/plugin-infra'

interface Props {
Expand Down Expand Up @@ -62,21 +62,37 @@ const FileServiceDialog: React.FC<Props> = (props) => {
closeWalletStatusDialog()
props.onClose()
}

let onDialogCloseCallback: DialogCloseCallback | null
const callDialogClose = () => {
try {
onDialogCloseCallback?.()
} catch (error) {}
onDialogCloseCallback = null
}

const onDecline = () => {
if (onDialogCloseCallback) {
callDialogClose()
return
}
if (!uploading) {
props.onClose()
return
}
showSnackbar(t.uploading_on_cancel())
}
const onDialogClose = (cb: DialogCloseCallback) => {
onDialogCloseCallback = cb
}
return (
<MaskDialog
DialogProps={{ scroll: 'paper', classes: { paper: classes.paper } }}
open={props.open}
title={t.__display_name()}
onClose={onDecline}>
<DialogContent>
<Exchange onUploading={setUploading} onInsert={setSelectedFileInfo}>
<Exchange onDialogClose={onDialogClose} onUploading={setUploading} onInsert={setSelectedFileInfo}>
<Entry />
</Exchange>
</DialogContent>
Expand Down
7 changes: 6 additions & 1 deletion packages/plugins/FileService/src/SNSAdaptor/Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { DownloadCloud, File } from 'react-feather'
import { useI18N } from '../locales/i18n_generated'
import { CopyableCode } from './components/Copyable'
import type { FileInfo } from '../types'
import { resolveGatewayAPI } from '../helpers'
import urlcat from 'urlcat'

const useStyles = makeStyles()((theme) => ({
root: {
Expand Down Expand Up @@ -55,7 +57,10 @@ export function Preview({ info }: { info: FileInfo }) {
{t.unencrypted()}
</Typography>
)
const link = `https://arweave.net/${info.landingTxID}`

const linkPrefix = resolveGatewayAPI(info.provider)
const link = urlcat(linkPrefix, '/:txId', { txId: info.landingTxID })

const onClick = (event: React.MouseEvent) => {
event.preventDefault()
event.stopPropagation()
Expand Down
61 changes: 49 additions & 12 deletions packages/plugins/FileService/src/SNSAdaptor/components/Upload.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { Attachment } from '@dimensiondev/common-protocols'
import { blobToArrayBuffer, encodeArrayBuffer } from '@dimensiondev/kit'
import { Checkbox, FormControlLabel, Link, Typography } from '@mui/material'
import { Checkbox, Radio, FormControlLabel, Link, Typography } from '@mui/material'
import { makeStyles } from '@masknet/theme'
import { isNil } from 'lodash-unified'
import { useState } from 'react'
import { useHistory } from 'react-router-dom'
import { useAsync } from 'react-use'
import { useI18N, Translate } from '../../locales/i18n_generated'
import { makeFileKey } from '../../file-key'
import type { ProviderConfig } from '../../types'
import { FileRouter, MAX_FILE_SIZE } from '../../constants'
import { PluginFileServiceRPC } from '../../Worker/rpc'
import { RecentFiles } from './RecentFiles'
import { UploadDropArea } from './UploadDropArea'
import { Provider } from '../../types'

const useStyles = makeStyles()((theme) => ({
container: {
Expand Down Expand Up @@ -57,7 +59,23 @@ export const Upload: React.FC = () => {
const history = useHistory()
const [encrypted, setEncrypted] = useState(true)
const [useCDN, setUseCDN] = useState(false)
const [provider, setProvider] = useState<Provider>(Provider.arweave)
const recent = useAsync(() => PluginFileServiceRPC.getRecentFiles(), [])
const allProviders: ProviderConfig[] = [
{
provider: Provider.arweave,
name: t.provider_arweave(),
},
{
provider: Provider.ipfs,
name: t.provider_ipfs(),
},
{
provider: Provider.swarm,
name: t.provider_swarm(),
},
]

const onFile = async (file: File) => {
let key: string | undefined = undefined
if (encrypted) {
Expand All @@ -75,11 +93,39 @@ export const Upload: React.FC = () => {
block,
checksum,
useCDN,
provider,
})
} else {
history.replace(FileRouter.uploaded, item)
}
}

const allProviderOptions = allProviders.map((config: ProviderConfig) => (
<FormControlLabel
key={config.provider}
control={
<Radio
color="primary"
checked={provider === config.provider}
onChange={() => setProvider(config.provider)}
/>
}
className={classes.encrypted}
label={config.name}
/>
))

const cdnButton =
provider === Provider.arweave ? (
<FormControlLabel
control={
<Checkbox color="primary" checked={useCDN} onChange={(event) => setUseCDN(event.target.checked)} />
}
className={classes.usedCDN}
label={t.use_cdn()}
/>
) : null

return (
<section className={classes.container}>
<section className={classes.upload}>
Expand All @@ -98,18 +144,9 @@ export const Upload: React.FC = () => {
className={classes.encrypted}
label={t.on_encrypt_it()}
/>
<FormControlLabel
control={
<Checkbox
color="primary"
checked={useCDN}
onChange={(event) => setUseCDN(event.target.checked)}
/>
}
className={classes.usedCDN}
label={t.use_cdn()}
/>
{cdnButton}
</section>
<section className={classes.checkItems}>{allProviderOptions}</section>
<section className={classes.legal}>
<Typography className={classes.legalText}>
<Translate.legal_text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const useStyles = makeStyles()((theme) => ({
here: {
fontSize: 12,
lineHeight: 2.5,
color: theme.palette.grey[100],
color: theme.palette.mode === 'dark' ? theme.palette.grey[100] : theme.palette.grey[500],
userSelect: 'none',
},
hint: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { useI18N } from '../../locales/i18n_generated'
import { FileRouter } from '../../constants'
import type { FileInfo } from '../../types'
import { FileName } from './FileName'
import { resolveGatewayAPI } from '../../helpers'
import urlcat from 'urlcat'

const useStyles = makeStyles()({
container: {
Expand Down Expand Up @@ -41,6 +43,14 @@ const useStyles = makeStyles()({
flexDirection: 'column',
justifyContent: 'center',
},
change: {
fontSize: 14,
margin: '0 auto',
display: 'flex',
padding: '0 60px',
flexDirection: 'column',
justifyContent: 'center',
},
info: {
margin: 0,
},
Expand All @@ -50,7 +60,7 @@ export const Uploaded: React.FC = () => {
const t = useI18N()
const { classes } = useStyles()
const history = useHistory()
const { onInsert } = useExchange()
const { onInsert, onDialogClose } = useExchange()
const { state } = useLocation<FileInfo>()
useEffect(() => {
onInsert(state)
Expand All @@ -59,14 +69,19 @@ export const Uploaded: React.FC = () => {
onInsert(null)
history.replace(FileRouter.upload)
}

// return upload route
onDialogClose(onBack)
const onPreview = (event: React.MouseEvent) => {
// ! THIS METHOD IS ONLY IN THE DEBUGGER !
// ! Trigger: [Shift Key] + [Click] !
// see https://mdn.io/shiftKey
if (!event.shiftKey) {
return
}
const link = `https://arweave.net/${state.landingTxID}`

const linkPrefix = resolveGatewayAPI(state.provider)
const link = urlcat(linkPrefix, '/:txId', { txId: state.landingTxID })
open(state.key ? `${link}#${state.key}` : link)
}
return (
Expand All @@ -82,10 +97,10 @@ export const Uploaded: React.FC = () => {
<span>{' '}</span>
<span>{formatDateTime(state.createdAt, 'yyyy-MM-dd HH:mm:ss')}</span>
</p>
<Button onClick={onBack} variant="contained">
{t.on_change_file()}
</Button>
</Typography>
<Button className={classes.change} onClick={onBack} variant="contained">
{t.on_change_file()}
</Button>
</Grid>
</Grid>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useAsync } from 'react-use'
import { useI18N } from '../../locales/i18n_generated'
import { timeout } from '@masknet/shared-base'
import { FileRouter } from '../../constants'
import type { FileInfo } from '../../types'
import type { FileInfo, Provider } from '../../types'
import { PluginFileServiceRPC, PluginFileServiceRPCGenerator } from '../../Worker/rpc'
import { useExchange } from '../hooks/Exchange'
import { FileName } from './FileName'
Expand Down Expand Up @@ -42,6 +42,7 @@ interface RouteState {
block: Uint8Array
checksum: string
useCDN: boolean
provider: Provider
}

export const Uploading: React.FC = () => {
Expand All @@ -58,20 +59,22 @@ export const Uploading: React.FC = () => {
return () => onUploading(false)
}, [onUploading])
const { error } = useAsync(async () => {
const currentProvider = state.provider as Provider
const payloadTxID = await timeout(
PluginFileServiceRPC.makeAttachment({
PluginFileServiceRPC.makeAttachment(currentProvider, {
name: state.name,
key: state.key,
block: state.block,
type: state.type,
}),
60000, // = 1 minute
)
setPreparing(false)
for await (const pctComplete of PluginFileServiceRPCGenerator.upload(payloadTxID)) {
for await (const pctComplete of PluginFileServiceRPCGenerator.upload(currentProvider, payloadTxID)) {
setSendSize(state.size * (pctComplete / 100))
}
const landingTxID = await timeout(
PluginFileServiceRPC.uploadLandingPage({
PluginFileServiceRPC.uploadLandingPage(currentProvider, {
name: state.name,
size: state.size,
txId: payloadTxID,
Expand All @@ -83,9 +86,8 @@ export const Uploading: React.FC = () => {
)
const item: FileInfo = {
type: 'file',
provider: 'arweave',
provider: currentProvider,
id: state.checksum,

name: state.name,
size: state.size,
createdAt: new Date(startedAt),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { noop, omit } from 'lodash-unified'
import { createContext, useContext } from 'react'
import type { FileInfo } from '../../types'
import type { FileInfo, DialogCloseCallback } from '../../types'

export interface Props {
onInsert(info: FileInfo | null): void
onUploading(enabled: boolean): void
onDialogClose(cb: DialogCloseCallback): void
}

const Context = createContext<Props>({
onInsert: noop,
onUploading: noop,
onDialogClose: noop,
})

export const Exchange: React.FC<Props> = (props) => (
Expand Down
Loading

0 comments on commit 47253c5

Please sign in to comment.