diff --git a/packages/storage-ui/package.json b/packages/storage-ui/package.json index de3657e07b..f45cc29cc4 100644 --- a/packages/storage-ui/package.json +++ b/packages/storage-ui/package.json @@ -6,7 +6,7 @@ "@babel/core": "^7.12.10", "@babel/runtime": "^7.0.0", "@chainsafe/browser-storage-hooks": "^1.0.1", - "@chainsafe/files-api-client": "1.14.4-rc1", + "@chainsafe/files-api-client": "^2.1.0-rc-1", "@chainsafe/web3-context": "1.1.4", "@lingui/core": "^3.7.2", "@lingui/react": "^3.7.2", diff --git a/packages/storage-ui/src/App.tsx b/packages/storage-ui/src/App.tsx index 434fc4c257..e2fe1683ae 100644 --- a/packages/storage-ui/src/App.tsx +++ b/packages/storage-ui/src/App.tsx @@ -4,7 +4,7 @@ import { Web3Provider } from "@chainsafe/web3-context" import { ThemeSwitcher } from "@chainsafe/common-theme" import "@chainsafe/common-theme/dist/font-faces.css" import { Button, CssBaseline, Modal, Router, ToasterProvider, Typography } from "@chainsafe/common-components" -import FilesRoutes from "./Components/StorageRoutes" +import StorageRoutes from "./Components/StorageRoutes" import AppWrapper from "./Components/Layouts/AppWrapper" import { useHotjar } from "react-use-hotjar" import { LanguageProvider } from "./Contexts/LanguageContext" @@ -26,8 +26,7 @@ if ( } const availableLanguages = [ - { id: "en", label: "English" }, - { id: "fr", label: "Français" } + { id: "en", label: "English" } ] const onboardConfig = { @@ -55,7 +54,7 @@ const onboardConfig = { } } -const App: React.FC<{}> = () => { +const App = () => { const { initHotjar } = useHotjar() const { canUseLocalStorage } = useLocalStorage() const hotjarId = process.env.REACT_APP_HOTJAR_ID @@ -93,7 +92,7 @@ const App: React.FC<{}> = () => { return ( = () => { > - + diff --git a/packages/storage-ui/src/Components/Elements/PinRow.tsx b/packages/storage-ui/src/Components/Elements/PinRow.tsx new file mode 100644 index 0000000000..9231815f41 --- /dev/null +++ b/packages/storage-ui/src/Components/Elements/PinRow.tsx @@ -0,0 +1,54 @@ +import React from "react" +import { makeStyles, createStyles } from "@chainsafe/common-theme" +import { formatBytes, TableCell, TableRow } from "@chainsafe/common-components" +import { Trans } from "@lingui/macro" +import dayjs from "dayjs" +import { PinObject } from "@chainsafe/files-api-client" + +const useStyles = makeStyles(() => + createStyles({ + root: { + } + }) +) +interface Props { + pinObject: PinObject +} + +const IPFS_GATEWAY = "https://ipfs.infura.io:5001/api/v0/cat/" + +const PinRow = ({ pinObject }: Props) => { + const classes = useStyles() + + return ( + + + {pinObject.pin?.cid} + + + {dayjs(pinObject.created).format("DD MMM YYYY h:mm a")} + + + {/** as any needs to be removed when the api spec will be up to date */} + {formatBytes((pinObject as any).info.size)} + + + + Open on Gateway + + + + + + + ) +} + +export default PinRow \ No newline at end of file diff --git a/packages/storage-ui/src/Components/Layouts/AppHeader.tsx b/packages/storage-ui/src/Components/Layouts/AppHeader.tsx index 2d37c6f363..e9c63fb5df 100644 --- a/packages/storage-ui/src/Components/Layouts/AppHeader.tsx +++ b/packages/storage-ui/src/Components/Layouts/AppHeader.tsx @@ -4,7 +4,7 @@ import clsx from "clsx" import { Link, Typography, - ChainsafeFilesLogo, + ChainsafeLogo, HamburgerMenu, MenuDropdown, PowerDownSvg, @@ -205,9 +205,9 @@ const AppHeader = ({ navOpen, setNavOpen }: IAppHeader) => { /> - + = ({ navOpen, setNavOpen }: IAppNav) => {
- - - Files - -   - - beta + + + ChainSafe Storage
)}
- - Folders - - - {desktop ? Resources : Account} - diff --git a/packages/storage-ui/src/Components/Pages/PinsPage.tsx b/packages/storage-ui/src/Components/Pages/Buckets.tsx similarity index 72% rename from packages/storage-ui/src/Components/Pages/PinsPage.tsx rename to packages/storage-ui/src/Components/Pages/Buckets.tsx index d815280fc0..e68275fc0d 100644 --- a/packages/storage-ui/src/Components/Pages/PinsPage.tsx +++ b/packages/storage-ui/src/Components/Pages/Buckets.tsx @@ -8,18 +8,21 @@ const useStyles = makeStyles(() => position: "relative", minHeight: "100vh", overflow: "hidden" + }, + tableHead: { + marginTop: 24 } }) ) -const PinsPage = () => { +const BucketsPage = () => { const classes = useStyles() return (
- Pins + Buckets
) } -export default PinsPage +export default BucketsPage diff --git a/packages/storage-ui/src/Components/Pages/CidsPage.tsx b/packages/storage-ui/src/Components/Pages/CidsPage.tsx new file mode 100644 index 0000000000..3bd1d1e80a --- /dev/null +++ b/packages/storage-ui/src/Components/Pages/CidsPage.tsx @@ -0,0 +1,79 @@ +import React, { useCallback } from "react" +import { makeStyles, createStyles } from "@chainsafe/common-theme" +import { Table, TableBody, TableHead, TableHeadCell, TableRow, Typography } from "@chainsafe/common-components" +import { useStorage } from "../../Contexts/StorageContext" +import { Trans } from "@lingui/macro" +import PinRow from "../Elements/PinRow" + +const useStyles = makeStyles(() => + createStyles({ + root: { + position: "relative", + minHeight: "100vh", + overflow: "hidden" + }, + tableHead: { + marginTop: 24 + } + }) +) + +const CidsPage = () => { + const classes = useStyles() + const { pins, addPin } = useStorage() + + const onCreateHardcodedPin = useCallback(() => { + addPin("QmNbbff884cwp1pvH8muod4pNaUqHA2ph77nYXP7dps2Xw") + }, [addPin]) + + return ( +
+ Cids + + + + + + Cid + + + Created + + + Size + + {/* IPFS Gateway */} + {/* Menu */} + + + + {pins.map((pinObject, index) => + + )} + +
+
+ ) +} + +export default CidsPage diff --git a/packages/storage-ui/src/Components/Pages/LoginPage.tsx b/packages/storage-ui/src/Components/Pages/LoginPage.tsx index cd25b2ff61..f2b5d04e11 100644 --- a/packages/storage-ui/src/Components/Pages/LoginPage.tsx +++ b/packages/storage-ui/src/Components/Pages/LoginPage.tsx @@ -2,7 +2,7 @@ import React from "react" import { makeStyles, createStyles, useThemeSwitcher } from "@chainsafe/common-theme" import { CSFTheme } from "../../Themes/types" import InitialScreen from "../Modules/LoginModule/InitialScreen" -import { ChainsafeFilesLogo, ChainsafeLogo, Typography } from "@chainsafe/common-components" +import { ChainsafeLogo, Typography } from "@chainsafe/common-components" import { ROUTE_LINKS } from "../StorageRoutes" import { Trans } from "@lingui/macro" import BottomDarkSVG from "../../Media/landing/layers/dark/Bottom.dark.svg" @@ -127,7 +127,7 @@ const LoginPage = () => { return (
- + ChainSafe Storage <> diff --git a/packages/storage-ui/src/Components/StorageRoutes.tsx b/packages/storage-ui/src/Components/StorageRoutes.tsx index 51581fe87d..0970100c3e 100644 --- a/packages/storage-ui/src/Components/StorageRoutes.tsx +++ b/packages/storage-ui/src/Components/StorageRoutes.tsx @@ -2,11 +2,13 @@ import React from "react" import { Switch, ConditionalRoute } from "@chainsafe/common-components" import LoginPage from "./Pages/LoginPage" import { useStorageApi } from "../Contexts/StorageApiContext" -import PinsPage from "./Pages/PinsPage" +import CidsPage from "./Pages/CidsPage" +import BucketsPage from "./Pages/Buckets" export const ROUTE_LINKS = { Landing: "/", - Pins: "/pins", + Cids: "/cids", + Buckets: "/buckets", PrivacyPolicy: "https://files.chainsafe.io/privacy-policy", Terms: "https://files.chainsafe.io/terms-of-service", ChainSafe: "https://chainsafe.io/" @@ -15,27 +17,34 @@ export const ROUTE_LINKS = { export const SETTINGS_PATHS = ["profile", "plan", "security"] as const export type SettingsPath = typeof SETTINGS_PATHS[number] -const FilesRoutes = () => { +const StorageRoutes = () => { const { isLoggedIn } = useStorageApi() return ( + ) } -export default FilesRoutes +export default StorageRoutes diff --git a/packages/storage-ui/src/Contexts/StorageApiContext.tsx b/packages/storage-ui/src/Contexts/StorageApiContext.tsx index d332153515..6deae3924b 100644 --- a/packages/storage-ui/src/Contexts/StorageApiContext.tsx +++ b/packages/storage-ui/src/Contexts/StorageApiContext.tsx @@ -7,8 +7,8 @@ import axios from "axios" import { useLocalStorage, useSessionStorage } from "@chainsafe/browser-storage-hooks" export type { IdentityProvider as OAuthProvider } -const tokenStorageKey = "csf.refreshToken" -const isReturningUserStorageKey = "csf.isReturningUser" +const tokenStorageKey = "css.refreshToken" +const isReturningUserStorageKey = "css.isReturningUser" type StorageApiContextProps = { apiUrl?: string @@ -17,7 +17,7 @@ type StorageApiContextProps = { } type StorageApiContext = { - filesApiClient: IFilesApiClient + storageApiClient: IFilesApiClient isLoggedIn: boolean | undefined secured: boolean | undefined isReturningUser: boolean @@ -44,7 +44,7 @@ const StorageApiProvider = ({ apiUrl, withLocalStorage = true, children }: Stora const maintenanceMode = process.env.REACT_APP_MAINTENANCE_MODE === "true" const { wallet, onboard, checkIsReady, isReady, provider } = useWeb3() - const { localStorageRemove, localStorageGet, localStorageSet } = useLocalStorage() + const { canUseLocalStorage, localStorageRemove, localStorageGet, localStorageSet } = useLocalStorage() const { sessionStorageRemove, sessionStorageGet, sessionStorageSet } = useSessionStorage() // initializing api @@ -58,7 +58,7 @@ const StorageApiProvider = ({ apiUrl, withLocalStorage = true, children }: Stora }, [apiUrl, initialAxiosInstance] ) - const [filesApiClient, setFilesApiClient] = useState(initialApiClient) + const [storageApiClient, setStorageApiClient] = useState(initialApiClient) const [isLoadingUser, setIsLoadingUser] = useState(true) // access tokens @@ -78,8 +78,8 @@ const StorageApiProvider = ({ apiUrl, withLocalStorage = true, children }: Stora setRefreshToken(refreshToken) refreshToken.token && withLocalStorage && localStorageSet(tokenStorageKey, refreshToken.token) !withLocalStorage && sessionStorageSet(tokenStorageKey, refreshToken.token) - accessToken.token && filesApiClient.setToken(accessToken.token) - }, [filesApiClient, localStorageSet, sessionStorageSet, withLocalStorage]) + accessToken.token && storageApiClient.setToken(accessToken.token) + }, [storageApiClient, localStorageSet, sessionStorageSet, withLocalStorage]) const setReturningUser = () => { // set returning user @@ -140,8 +140,11 @@ const StorageApiProvider = ({ apiUrl, withLocalStorage = true, children }: Stora ) const apiClient = new FilesApiClient({}, apiUrl, axiosInstance) - const savedRefreshToken = localStorageGet(tokenStorageKey) - setFilesApiClient(apiClient) + const savedRefreshToken = withLocalStorage + ? localStorageGet(tokenStorageKey) + : sessionStorageGet(tokenStorageKey) + + setStorageApiClient(apiClient) if (!maintenanceMode && savedRefreshToken) { try { const { @@ -160,7 +163,7 @@ const StorageApiProvider = ({ apiUrl, withLocalStorage = true, children }: Stora initializeApiClient() // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) + }, [canUseLocalStorage]) const selectWallet = async () => { if (onboard && !isReady) { @@ -194,8 +197,8 @@ const StorageApiProvider = ({ apiUrl, withLocalStorage = true, children }: Stora }, [refreshToken]) useEffect(() => { - if (accessToken && accessToken.token && filesApiClient) { - filesApiClient?.setToken(accessToken.token) + if (accessToken && accessToken.token && storageApiClient) { + storageApiClient?.setToken(accessToken.token) const decodedAccessToken = jwtDecode<{ perm: { secured?: string } }>( accessToken.token ) @@ -205,7 +208,7 @@ const StorageApiProvider = ({ apiUrl, withLocalStorage = true, children }: Stora setSecured(false) } } - }, [accessToken, filesApiClient]) + }, [accessToken, storageApiClient]) const isLoggedIn = () => { if (isLoadingUser) { @@ -225,7 +228,7 @@ const StorageApiProvider = ({ apiUrl, withLocalStorage = true, children }: Stora const getProviderUrl = async (provider: OAuthIdentityToken) => { try { - const { url } = await filesApiClient.getOauth2Provider(provider) + const { url } = await storageApiClient.getOauth2Provider(provider) return Promise.resolve(url) } catch { return Promise.reject("There was an error logging in") @@ -237,7 +240,7 @@ const StorageApiProvider = ({ apiUrl, withLocalStorage = true, children }: Stora const { access_token, refresh_token - } = await filesApiClient.postOauth2CodeGithub(code, state) + } = await storageApiClient.postOauth2CodeGithub(code, state) setTokensAndSave(access_token, refresh_token) setReturningUser() return Promise.resolve() @@ -258,7 +261,7 @@ const StorageApiProvider = ({ apiUrl, withLocalStorage = true, children }: Stora const { access_token, refresh_token - } = await filesApiClient.postOauth2CodeGoogle( + } = await storageApiClient.postOauth2CodeGoogle( code, state, scope, @@ -280,7 +283,7 @@ const StorageApiProvider = ({ apiUrl, withLocalStorage = true, children }: Stora const { access_token, refresh_token - } = await filesApiClient.postOauth2CodeFacebook(code, state) + } = await storageApiClient.postOauth2CodeFacebook(code, state) setTokensAndSave(access_token, refresh_token) setReturningUser() @@ -299,7 +302,7 @@ const StorageApiProvider = ({ apiUrl, withLocalStorage = true, children }: Stora } const signer = provider.getSigner() try { - const { token } = await filesApiClient.getWeb3Token() + const { token } = await storageApiClient.getWeb3Token() if (token) { const signature = await signer.signMessage(token) @@ -307,7 +310,7 @@ const StorageApiProvider = ({ apiUrl, withLocalStorage = true, children }: Stora const { access_token, refresh_token - } = await filesApiClient.postWeb3Token({ + } = await storageApiClient.postWeb3Token({ signature: signature, token: token, public_address: address @@ -325,7 +328,7 @@ const StorageApiProvider = ({ apiUrl, withLocalStorage = true, children }: Stora setAccessToken(undefined) setRefreshToken(undefined) setDecodedRefreshToken(undefined) - filesApiClient.setToken("") + storageApiClient.setToken("") localStorageRemove(tokenStorageKey) !withLocalStorage && sessionStorageRemove(tokenStorageKey) } @@ -333,7 +336,7 @@ const StorageApiProvider = ({ apiUrl, withLocalStorage = true, children }: Stora return ( { const context = React.useContext(StorageApiContext) if (context === undefined) { - throw new Error("useAuth must be used within a AuthProvider") + throw new Error("useStorage must be used within a StorageProvider") } return context } diff --git a/packages/storage-ui/src/Contexts/StorageContext.tsx b/packages/storage-ui/src/Contexts/StorageContext.tsx index 332a63d2af..5100154ebf 100644 --- a/packages/storage-ui/src/Contexts/StorageContext.tsx +++ b/packages/storage-ui/src/Contexts/StorageContext.tsx @@ -1,17 +1,15 @@ import { - CSFFilesFullInfoResponse, FileContentResponse, DirectoryContentResponse, BucketType, - Bucket as FilesBucket, - SearchEntry + SearchEntry, + PinObject } from "@chainsafe/files-api-client" import React, { useCallback, useEffect, useReducer } from "react" import { useState } from "react" -import { v4 as uuidv4 } from "uuid" +// import { v4 as uuidv4 } from "uuid" import { downloadsInProgressReducer, uploadsInProgressReducer } from "./FilesReducers" -import { CancelToken } from "axios" -import { t } from "@lingui/macro" +// import { t } from "@lingui/macro" import { useBeforeunload } from "react-beforeunload" import { useStorageApi } from "./StorageApiContext" @@ -39,25 +37,16 @@ export type DownloadProgress = { complete: boolean } -interface GetFileContentParams { - cid: string - cancelToken?: CancelToken - onDownloadProgress?: (progressEvent: ProgressEvent) => void - file: FileSystemItem - path: string -} - -type Bucket = FilesBucket - type StorageContext = { - pins: Bucket[] + pins: PinObject[] uploadsInProgress: UploadProgress[] downloadsInProgress: DownloadProgress[] spaceUsed: number - createPin: (bucketId: string, files: File[], path: string) => Promise - downloadPin: (bucketId: string, itemToDownload: FileSystemItem, path: string) => void - getPinContent: (bucketId: string, params: GetFileContentParams) => Promise - refreshPins: () => Promise + addPin: (cid: string) => void + // createPin: (bucketId: string, files: File[], path: string) => Promise + // downloadPin: (bucketId: string, itemToDownload: FileSystemItem, path: string) => void + // getPinContent: (bucketId: string, params: GetFileContentParams) => Promise + refreshPins: () => void } // This represents a File or Folder on the @@ -72,41 +61,37 @@ const REMOVE_UPLOAD_PROGRESS_DELAY = 5000 const StorageContext = React.createContext(undefined) const StorageProvider = ({ children }: StorageContextProps) => { - const { - filesApiClient, - isLoggedIn - } = useStorageApi() - const [spaceUsed, setSpaceUsed] = useState(0) - const [pins, setPins] = useState([]) - - const refreshPins = useCallback(async () => { - const result = await filesApiClient.listBuckets() + const { storageApiClient, isLoggedIn } = useStorageApi() + const [spaceUsed] = useState(0) + const [pins, setPins] = useState([]) - setPins(result.filter(b => b.type === "pinning")) - return Promise.resolve() - }, [filesApiClient]) + const refreshPins = useCallback(() => { + storageApiClient.listPins() + .then((pins) => setPins(pins.results || [])) + .catch(console.error) + }, [storageApiClient]) useEffect(() => { isLoggedIn && refreshPins() }, [isLoggedIn, refreshPins]) - // Space used counter - useEffect(() => { - const getSpaceUsage = async () => { - try { - // TODO: Update this to include Share buckets where the current user is the owner - const totalSize = pins.filter(b => b.type === "pinning") - .reduce((totalSize, bucket) => { return totalSize += (bucket as any).size}, 0) - - setSpaceUsed(totalSize) - } catch (error) { - console.error(error) - } - } - if (isLoggedIn) { - getSpaceUsage() - } - }, [filesApiClient, isLoggedIn, pins]) + // // Space used counter + // useEffect(() => { + // const getSpaceUsage = async () => { + // try { + // // TODO: Update this to include Share buckets where the current user is the owner + // const totalSize = pins.filter(p => p.pin === "pinning") + // .reduce((totalSize, bucket) => { return totalSize += (bucket as any).size}, 0) + + // setSpaceUsed(totalSize) + // } catch (error) { + // console.error(error) + // } + // } + // if (isLoggedIn) { + // getSpaceUsage() + // } + // }, [storageApiClient, isLoggedIn, pins]) // Reset encryption keys on log out useEffect(() => { @@ -120,7 +105,7 @@ const StorageProvider = ({ children }: StorageContextProps) => { [] ) - const [downloadsInProgress, dispatchDownloadsInProgress] = useReducer( + const [downloadsInProgress] = useReducer( downloadsInProgressReducer, [] ) @@ -143,150 +128,157 @@ const StorageProvider = ({ children }: StorageContextProps) => { } }) - const createPin = useCallback(async (bucketId: string, files: File[], path: string) => { - const bucket = pins.find(b => b.id === bucketId) - - if (!bucket) { - console.error("No encryption key for this bucket is available.") - return - } - - const id = uuidv4() - const uploadProgress: UploadProgress = { - id, - fileName: files[0].name, // TODO: Do we need this? - complete: false, - error: false, - noOfFiles: files.length, - progress: 0, - path - } - dispatchUploadsInProgress({ type: "add", payload: uploadProgress }) - try { - // TODO: Make API Request to upload here - - // setting complete - dispatchUploadsInProgress({ type: "complete", payload: { id } }) - setTimeout(() => { - dispatchUploadsInProgress({ type: "remove", payload: { id } }) - }, REMOVE_UPLOAD_PROGRESS_DELAY) - - return Promise.resolve() - } catch (error) { - console.error(error) - // setting error - let errorMessage = t`Something went wrong. We couldn't upload your file` - - // we will need a method to parse server errors - if (Array.isArray(error) && error[0].message.includes("conflict")) { - errorMessage = t`A file with the same name already exists` - } - dispatchUploadsInProgress({ - type: "error", - payload: { id, errorMessage } - }) - setTimeout(() => { - dispatchUploadsInProgress({ type: "remove", payload: { id } }) - }, REMOVE_UPLOAD_PROGRESS_DELAY) - } - }, [pins]) - - const getPinContent = useCallback(async ( - bucketId: string, - { cid, cancelToken, onDownloadProgress, file, path }: GetFileContentParams - ) => { - const bucket = pins.find(b => b.id === bucketId) - - if (!bucket) { - throw new Error("No encryption key for this bucket found") - } - - if (!file) { - console.error("No file passed, and no file found for cid:", cid, "in pathContents:", path) - throw new Error("No file found.") - } - - try { - const result = await filesApiClient.getFileContent( - { - path: path, - source: { - id: bucket.id - } - }, - cancelToken, - onDownloadProgress - ) - - return result.data - } catch (error) { - console.error(error) - return Promise.reject() - } - }, [pins, filesApiClient]) - - const downloadPin = useCallback(async (bucketId: string, itemToDownload: FileSystemItem, path: string) => { - const toastId = uuidv4() - try { - const downloadProgress: DownloadProgress = { - id: toastId, - fileName: itemToDownload.name, - complete: false, - error: false, - progress: 0 - } - dispatchDownloadsInProgress({ type: "add", payload: downloadProgress }) - const result = await getPinContent(bucketId, { - cid: itemToDownload.cid, - file: itemToDownload, - path: `${path}/${itemToDownload.name}`, - onDownloadProgress: (progressEvent) => { - dispatchDownloadsInProgress({ - type: "progress", - payload: { - id: toastId, - progress: Math.ceil( - (progressEvent.loaded / itemToDownload.size) * 100 - ) - } - }) - } - }) - if (!result) return - const link = document.createElement("a") - link.href = URL.createObjectURL(result) - link.download = itemToDownload?.name || "file" - link.click() - dispatchDownloadsInProgress({ - type: "complete", - payload: { id: toastId } - }) - URL.revokeObjectURL(link.href) - setTimeout(() => { - dispatchDownloadsInProgress({ - type: "remove", - payload: { id: toastId } - }) - }, REMOVE_UPLOAD_PROGRESS_DELAY) - return Promise.resolve() - } catch (error) { - dispatchDownloadsInProgress({ type: "error", payload: { id: toastId } }) - return Promise.reject() - } - }, [getPinContent]) + const addPin = useCallback((cid: string) => { + // Remove the as any once the api specs will be updated + storageApiClient.addPin(({ cid }) as any) + .then(res => console.log(res)) + .catch(console.error) + }, [storageApiClient]) + + // const createPin = useCallback(async (bucketId: string, files: File[], path: string) => { + // const bucket = pins.find(b => b.id === bucketId) + + // if (!bucket) { + // console.error("No encryption key for this bucket is available.") + // return + // } + + // const id = uuidv4() + // const uploadProgress: UploadProgress = { + // id, + // fileName: files[0].name, // TODO: Do we need this? + // complete: false, + // error: false, + // noOfFiles: files.length, + // progress: 0, + // path + // } + // dispatchUploadsInProgress({ type: "add", payload: uploadProgress }) + // try { + // // TODO: Make API Request to upload here + + // // setting complete + // dispatchUploadsInProgress({ type: "complete", payload: { id } }) + // setTimeout(() => { + // dispatchUploadsInProgress({ type: "remove", payload: { id } }) + // }, REMOVE_UPLOAD_PROGRESS_DELAY) + + // return Promise.resolve() + // } catch (error) { + // console.error(error) + // // setting error + // let errorMessage = t`Something went wrong. We couldn't upload your file` + + // // we will need a method to parse server errors + // if (Array.isArray(error) && error[0].message.includes("conflict")) { + // errorMessage = t`A file with the same name already exists` + // } + // dispatchUploadsInProgress({ + // type: "error", + // payload: { id, errorMessage } + // }) + // setTimeout(() => { + // dispatchUploadsInProgress({ type: "remove", payload: { id } }) + // }, REMOVE_UPLOAD_PROGRESS_DELAY) + // } + // }, [pins]) + + // const getPinContent = useCallback(async ( + // bucketId: string, + // { cid, cancelToken, onDownloadProgress, file, path }: GetFileContentParams + // ) => { + // const bucket = pins.find(b => b.id === bucketId) + + // if (!bucket) { + // throw new Error("No encryption key for this bucket found") + // } + + // if (!file) { + // console.error("No file passed, and no file found for cid:", cid, "in pathContents:", path) + // throw new Error("No file found.") + // } + + // try { + // const result = await storageApiClient.getFileContent( + // { + // path: path, + // source: { + // id: bucket.id + // } + // }, + // cancelToken, + // onDownloadProgress + // ) + + // return result.data + // } catch (error) { + // console.error(error) + // return Promise.reject() + // } + // }, [pins, storageApiClient]) + + // const downloadPin = useCallback(async (bucketId: string, itemToDownload: FileSystemItem, path: string) => { + // const toastId = uuidv4() + // try { + // const downloadProgress: DownloadProgress = { + // id: toastId, + // fileName: itemToDownload.name, + // complete: false, + // error: false, + // progress: 0 + // } + // dispatchDownloadsInProgress({ type: "add", payload: downloadProgress }) + // const result = await getPinContent(bucketId, { + // cid: itemToDownload.cid, + // file: itemToDownload, + // path: `${path}/${itemToDownload.name}`, + // onDownloadProgress: (progressEvent) => { + // dispatchDownloadsInProgress({ + // type: "progress", + // payload: { + // id: toastId, + // progress: Math.ceil( + // (progressEvent.loaded / itemToDownload.size) * 100 + // ) + // } + // }) + // } + // }) + // if (!result) return + // const link = document.createElement("a") + // link.href = URL.createObjectURL(result) + // link.download = itemToDownload?.name || "file" + // link.click() + // dispatchDownloadsInProgress({ + // type: "complete", + // payload: { id: toastId } + // }) + // URL.revokeObjectURL(link.href) + // setTimeout(() => { + // dispatchDownloadsInProgress({ + // type: "remove", + // payload: { id: toastId } + // }) + // }, REMOVE_UPLOAD_PROGRESS_DELAY) + // return Promise.resolve() + // } catch (error) { + // dispatchDownloadsInProgress({ type: "error", payload: { id: toastId } }) + // return Promise.reject() + // } + // }, [getPinContent]) return ( {children} @@ -306,7 +298,6 @@ export { StorageProvider, useStorage } export type { FileSystemItem, DirectoryContentResponse, - CSFFilesFullInfoResponse as FileFullInfo, BucketType, SearchEntry } diff --git a/yarn.lock b/yarn.lock index b0772a5481..df28248954 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1664,16 +1664,16 @@ resolved "https://registry.yarnpkg.com/@chainsafe/browser-storage-hooks/-/browser-storage-hooks-1.0.1.tgz#26d32cde1999914db755a631e2643823c54959f7" integrity sha512-Q4b5gQAZnsRXKeADspd5isqfwwhhXjDk70y++YadufA6EZ3tf340oW0OVszp74KaGEw+CAYFGQR4X7bzpZ3x9Q== -"@chainsafe/files-api-client@1.14.4-rc1": - version "1.14.4-rc1" - resolved "https://npm.pkg.github.com/download/@chainsafe/files-api-client/1.14.4-rc1/d817fdd4af005c219f6836687e374a70ebc1a882426fab32cf7f2248a478a20f#f2f79b098853c844ac6fa3caecb0db4e7ece4b08" - integrity sha512-p2NhMRWMqadj0uMHyUskhMnroC1ZUZSUUFB4Z8TIFrEPbqZdEfnHTaI9/vwJqaU9VLqMRoJCFxG4JZ0e76VGLQ== - "@chainsafe/files-api-client@2.0.0": version "2.0.0" resolved "https://npm.pkg.github.com/download/@chainsafe/files-api-client/2.0.0/59fcd2bbb4c64e37edae6b31b05ab5e46e2d24bec5424afbe2eb7c2eaa8b9ea0#f2a93ee7a605eccf2ed64ca7c731a1de79f3e001" integrity sha512-28zvyqB8D8Itmsc31xy7gZHFcOg9J2b3BMZWgHNLQLtfJBfLWlE0gHS+CVPUrrPERf02Bbm79Z57qP96YJYOoA== +"@chainsafe/files-api-client@^2.1.0-rc-1": + version "2.1.0-rc-1" + resolved "https://npm.pkg.github.com/download/@chainsafe/files-api-client/2.1.0-rc-1/422fefb018a31955b3fdc525e5a1ea6f5cc6a04f80e2716e6667733c97e3888e#e7e69aa132ec6ccbb396f9b3fc1e6bc270b21162" + integrity sha512-UjKUyelAUpUu7aJTYUpZHEF8py7M2hiY1rBEmlQKOJOrivT5srkdBMPM2SQOzi93jnZm6AVQxYCO9MPOQoGaPA== + "@chainsafe/web3-context@1.1.4": version "1.1.4" resolved "https://registry.yarnpkg.com/@chainsafe/web3-context/-/web3-context-1.1.4.tgz#ce0f140af8ccf93af1a189fbdbd6f018b9bf5fb7"