Skip to content

Commit 5087dc2

Browse files
FSM1tanmoyAtbTbaut
authored
Resolve File Browser race condition (#1069)
* fixed * fix search redirects * resolve race condition * remove stray import * Apply suggestions from code review Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * make eslint :D Co-authored-by: tanmoy12 <tanmoy3399@gmail.com> Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com>
1 parent af17b2a commit 5087dc2

File tree

5 files changed

+30
-61
lines changed

5 files changed

+30
-61
lines changed

packages/files-ui/src/Components/Modules/FileBrowsers/BinFileBrowser.tsx

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { t } from "@lingui/macro"
77
import { CONTENT_TYPES } from "../../../Utils/Constants"
88
import { IFilesTableBrowserProps } from "../../Modules/FileBrowsers/types"
99
import { useHistory, useLocation, useToaster } from "@chainsafe/common-components"
10-
import { extractDrivePath, getPathWithFile } from "../../../Utils/pathUtils"
10+
import { extractFileBrowserPathFromURL, getArrayOfPaths, getPathWithFile, getURISafePathFromArray } from "../../../Utils/pathUtils"
1111
import { ROUTE_LINKS } from "../../FilesRoutes"
1212
import { FileBrowserContext } from "../../../Contexts/FileBrowserContext"
1313
import { useFilesApi } from "@chainsafe/common-contexts"
@@ -20,7 +20,10 @@ const BinFileBrowser: React.FC<IFileBrowserModuleProps> = ({ controls = false }:
2020
const [loadingCurrentPath, setLoadingCurrentPath] = useState(false)
2121
const [pathContents, setPathContents] = useState<FileSystemItem[]>([])
2222
const { pathname } = useLocation()
23-
const [currentPath, setCurrentPath] = useState(extractDrivePath(pathname.split("/").slice(1).join("/")))
23+
const currentPath = useMemo(() =>
24+
extractFileBrowserPathFromURL(pathname, ROUTE_LINKS.Bin("")),
25+
[pathname]
26+
)
2427
const { redirect } = useHistory()
2528

2629
const bucket = useMemo(() => buckets.find(b => b.type === "trash"), [buckets])
@@ -52,22 +55,6 @@ const BinFileBrowser: React.FC<IFileBrowserModuleProps> = ({ controls = false }:
5255
refreshContents(true)
5356
}, [bucket, refreshContents])
5457

55-
useEffect(() => {
56-
let binPath = extractDrivePath(pathname)
57-
if (binPath[0] !== "/") {
58-
binPath = "/" + binPath
59-
}
60-
if (binPath !== currentPath) {
61-
if (binPath === "/") {
62-
setCurrentPath(binPath)
63-
} else {
64-
setCurrentPath(decodeURIComponent(binPath.slice(0, -1)))
65-
}
66-
refreshContents(true)
67-
}
68-
}, [refreshContents, pathname, currentPath])
69-
70-
7158
const deleteFile = useCallback(async (cid: string) => {
7259
const itemToDelete = pathContents.find((i) => i.cid === cid)
7360

@@ -153,10 +140,8 @@ const BinFileBrowser: React.FC<IFileBrowserModuleProps> = ({ controls = false }:
153140
const viewFolder = useCallback((cid: string) => {
154141
const fileSystemItem = pathContents.find(f => f.cid === cid)
155142
if (fileSystemItem && fileSystemItem.content_type === CONTENT_TYPES.Directory) {
156-
let urlSafePath
157-
if (currentPath !== "/") {
158-
urlSafePath = `/${currentPath.slice(1).split("/").map(encodeURIComponent).join("/")}`
159-
} else {
143+
let urlSafePath = getURISafePathFromArray(getArrayOfPaths(currentPath))
144+
if (urlSafePath === "/") {
160145
urlSafePath = ""
161146
}
162147
redirect(ROUTE_LINKS.Bin(`${urlSafePath}/${encodeURIComponent(`${fileSystemItem.name}`)}`))

packages/files-ui/src/Components/Modules/FileBrowsers/CSFFileBrowser.tsx

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useCallback, useEffect, useMemo, useState } from "react"
22
import { Crumb, useToaster, useHistory, useLocation } from "@chainsafe/common-components"
33
import { useFiles, FileSystemItem } from "../../../Contexts/FilesContext"
4-
import { extractDrivePath, getArrayOfPaths, getURISafePathFromArray, getPathWithFile } from "../../../Utils/pathUtils"
4+
import { getArrayOfPaths, getURISafePathFromArray, getPathWithFile, extractFileBrowserPathFromURL } from "../../../Utils/pathUtils"
55
import { IBulkOperations, IFileBrowserModuleProps, IFilesTableBrowserProps } from "./types"
66
import FilesList from "./views/FilesList"
77
import { CONTENT_TYPES } from "../../../Utils/Constants"
@@ -29,8 +29,10 @@ const CSFFileBrowser: React.FC<IFileBrowserModuleProps> = () => {
2929
const { redirect } = useHistory()
3030

3131
const { pathname } = useLocation()
32-
const [currentPath, setCurrentPath] = useState(extractDrivePath(pathname.split("/").slice(1).join("/")))
33-
32+
const currentPath = useMemo(() =>
33+
extractFileBrowserPathFromURL(pathname, ROUTE_LINKS.Drive("")),
34+
[pathname]
35+
)
3436
const bucket = useMemo(() => buckets.find(b => b.type === "csf"), [buckets])
3537

3638
const refreshContents = useCallback((showLoading?: boolean) => {
@@ -71,22 +73,6 @@ const CSFFileBrowser: React.FC<IFileBrowserModuleProps> = () => {
7173
refreshContents(true)
7274
}, [bucket, refreshContents])
7375

74-
useEffect(() => {
75-
let drivePath = extractDrivePath(pathname)
76-
if (drivePath[0] !== "/") {
77-
drivePath = "/" + drivePath
78-
}
79-
if (drivePath !== currentPath) {
80-
if (drivePath === "/") {
81-
setCurrentPath(drivePath)
82-
} else {
83-
setCurrentPath(decodeURIComponent(drivePath.slice(0, -1)))
84-
}
85-
86-
refreshContents(true)
87-
}
88-
}, [refreshContents, pathname, currentPath])
89-
9076
const moveItemsToBin = useCallback(async (cids: string[]) => {
9177
if (!bucket) return
9278
await Promise.all(
@@ -162,7 +148,6 @@ const CSFFileBrowser: React.FC<IFileBrowserModuleProps> = () => {
162148
const crumbs: Crumb[] = useMemo(() => arrayOfPaths.map((path, index) => ({
163149
text: decodeURIComponent(path),
164150
onClick: () => {
165-
166151
redirect(
167152
ROUTE_LINKS.Drive(getURISafePathFromArray(arrayOfPaths.slice(0, index + 1)))
168153
)
@@ -191,10 +176,8 @@ const CSFFileBrowser: React.FC<IFileBrowserModuleProps> = () => {
191176
const viewFolder = useCallback((cid: string) => {
192177
const fileSystemItem = pathContents.find(f => f.cid === cid)
193178
if (fileSystemItem && fileSystemItem.content_type === CONTENT_TYPES.Directory) {
194-
let urlSafePath
195-
if (currentPath !== "/") {
196-
urlSafePath = `/${currentPath.slice(1).split("/").map(encodeURIComponent).join("/")}`
197-
} else {
179+
let urlSafePath = getURISafePathFromArray(getArrayOfPaths(currentPath))
180+
if (urlSafePath === "/") {
198181
urlSafePath = ""
199182
}
200183
redirect(ROUTE_LINKS.Drive(`${urlSafePath}/${encodeURIComponent(`${fileSystemItem.name}`)}`))
@@ -221,7 +204,7 @@ const CSFFileBrowser: React.FC<IFileBrowserModuleProps> = () => {
221204
bucket,
222205
bulkOperations,
223206
crumbs,
224-
moduleRootPath: ROUTE_LINKS.Drive(""),
207+
moduleRootPath: ROUTE_LINKS.Drive("/"),
225208
currentPath,
226209
refreshContents,
227210
deleteItems: moveItemsToBin,

packages/files-ui/src/Components/Modules/FileBrowsers/SearchFileBrowser.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const SearchFileBrowser: React.FC<IFileBrowserModuleProps> = ({ controls = false
1515
const { pathname } = useLocation()
1616
const { filesApiClient } = useFilesApi()
1717
const { buckets } = useFiles()
18-
const [searchTerm, setSearchTerm] = useState(pathname.split("/").slice(2)[0])
18+
const searchTerm = useMemo(() => decodeURIComponent(pathname.split("/").slice(2)[0]), [pathname])
1919
const { redirect } = useHistory()
2020

2121
const { addToastMessage } = useToaster()
@@ -38,11 +38,10 @@ const SearchFileBrowser: React.FC<IFileBrowserModuleProps> = ({ controls = false
3838
}, [addToastMessage, bucket, filesApiClient])
3939

4040
useEffect(() => {
41-
const searchPath = pathname.split("/").slice(2)[0]
42-
43-
setSearchTerm(decodeURI(searchPath))
44-
getSearchResults(decodeURI(searchPath))
45-
}, [getSearchResults, pathname])
41+
getSearchResults(searchTerm)
42+
.then(setSearchResults)
43+
.catch(console.error)
44+
}, [searchTerm, getSearchResults])
4645

4746
const [loadingSearchResults, setLoadingSearchResults] = useState(true)
4847
const [searchResults, setSearchResults] = useState<SearchEntry[]>([])

packages/files-ui/src/Components/Modules/SearchModule.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import { getArrayOfPaths, getParentPathFromFilePath, getURISafePathFromArray } f
2323
import { t, Trans } from "@lingui/macro"
2424
import { CSFTheme } from "../../Themes/types"
2525
import { useFilesApi } from "@chainsafe/common-contexts"
26-
import { trimChar } from "../../Utils/pathUtils"
2726

2827
export interface SearchParams {
2928
bucketType: BucketType
@@ -209,7 +208,7 @@ const SearchModule: React.FC<ISearchModule> = ({
209208
const onSearchSubmit = (e: React.FormEvent<HTMLFormElement>) => {
210209
e.preventDefault()
211210
setSearchActive(false)
212-
redirect(ROUTE_LINKS.Search(searchQuery))
211+
redirect(ROUTE_LINKS.Search(encodeURIComponent(searchQuery)))
213212
}
214213

215214
const searchResultsFiles = searchResults?.results.filter(

packages/files-ui/src/Utils/pathUtils.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@ export function getArrayOfPaths(path: string): string[] {
2525
export function getURISafePathFromArray(arrayOfPaths: string[]): string {
2626
if (!arrayOfPaths.length) return "/"
2727
else {
28-
return "/" + arrayOfPaths.map(encodeURIComponent).join("/")
28+
return `/${arrayOfPaths.map(encodeURIComponent).join("/")}`
2929
}
3030
}
3131

32-
// get path and file
32+
// Safe append path to file name
33+
// /path/to/somewhere + 1.txt -> /path/to/somewhere/1.txt
34+
// /path/to/somewhere/ + 1.txt -> /path/to/somewhere/1.txt
3335
export function getPathWithFile(path: string, fileName: string) {
3436
return path === "/"
3537
? `/${fileName}`
@@ -38,13 +40,14 @@ export function getPathWithFile(path: string, fileName: string) {
3840
: `${path}/${fileName}`
3941
}
4042

41-
// get path and file
43+
// /path/to/somewhere/1.txt -> /path/to/somewhere
4244
export function getParentPathFromFilePath(filePath: string) {
4345
const parentPath = filePath.substring(0, filePath.lastIndexOf("/"))
4446
if (!parentPath) return "/"
4547
return parentPath
4648
}
4749

48-
export function extractDrivePath(pathname: string) {
49-
return pathname.split("/").slice(2).join("/").concat("/")
50-
}
50+
// /drive/path/to/somewhere -> /path/to/somewhere
51+
export function extractFileBrowserPathFromURL(browserUrl: string, modulePath: string) {
52+
return browserUrl.replace(modulePath, "").split("/").map(decodeURIComponent).join("/")
53+
}

0 commit comments

Comments
 (0)