Skip to content

Commit f62c19e

Browse files
Merge pull request #21 from solid/feat/my-storages
bug fix: fixed the useBrowseStorage hook to stop making http requests…
2 parents 5902e46 + 3515418 commit f62c19e

1 file changed

Lines changed: 39 additions & 39 deletions

File tree

app/lib/hooks/useBrowseStorage.ts

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ import { getAuthenticatedSession } from "../helpers";
55
import {
66
getSolidDataset,
77
getContainedResourceUrlAll,
8-
isContainer,
98
getThing,
109
getInteger,
1110
getDatetime,
1211
getStringNoLocale,
12+
getIriAll,
1313
UrlString,
1414
} from "@inrupt/solid-client";
1515
import { DCTERMS, POSIX, RDFS } from "@inrupt/vocab-common-rdf";
16+
import { LDP } from "@inrupt/vocab-common-rdf";
1617
import { FileItemData } from "../../components/FileItem";
1718
import { extractNameFromUrl, resolveUrl, isLikelyFile, isBinaryFile } from "../helpers/urlUtils";
1819

@@ -51,12 +52,12 @@ export function useBrowseStorage(containerUrl: string | null, refreshKey?: numbe
5152
// This ensures we get fresh data after uploads/deletes
5253
const cacheBustingFetch = refreshKey !== undefined && refreshKey > 0
5354
? (input: RequestInfo | URL, init?: RequestInit) => {
54-
const headers = new Headers(init?.headers);
55-
// Adding cache-control headers to bypass browser/server cache
56-
headers.set('Cache-Control', 'no-cache, no-store, must-revalidate');
57-
headers.set('Pragma', 'no-cache');
58-
return fetchFn(input, { ...init, headers, cache: 'no-store' });
59-
}
55+
const headers = new Headers(init?.headers);
56+
// Adding cache-control headers to bypass browser/server cache
57+
headers.set('Cache-Control', 'no-cache, no-store, must-revalidate');
58+
headers.set('Pragma', 'no-cache');
59+
return fetchFn(input, { ...init, headers, cache: 'no-store' });
60+
}
6061
: fetchFn;
6162

6263
// Use @inrupt/solid-client to fetch the container dataset
@@ -73,7 +74,7 @@ export function useBrowseStorage(containerUrl: string | null, refreshKey?: numbe
7374
try {
7475
const absoluteUrl = resolveUrl(itemUrl, url) as UrlString;
7576
const isContainerUrl = absoluteUrl.endsWith("/");
76-
77+
7778
// Try to get preferred name in this order:
7879
// 1. RDF metadata from container (dcterms:title or rdfs:label)
7980
// 2. URL extraction (fallback)
@@ -83,6 +84,8 @@ export function useBrowseStorage(containerUrl: string | null, refreshKey?: numbe
8384

8485
// Check RDF metadata from container dataset- using getThing because it reads a resource (thing) from the RDF dataset to access properties like dcterms:title, rdfs:label, dcterms:modified, posix:size
8586
const itemThing = getThing(containerDataset, absoluteUrl);
87+
let finalIsContainer = isContainerUrl;
88+
8689
if (itemThing) {
8790
// Check for preferred name in metadata (dcterms:title or rdfs:label)
8891
const title = getStringNoLocale(itemThing, DCTERMS.title);
@@ -99,7 +102,7 @@ export function useBrowseStorage(containerUrl: string | null, refreshKey?: numbe
99102
if (modifiedDate) {
100103
lastModified = modifiedDate;
101104
}
102-
105+
103106
if (!lastModified) {
104107
const mtime = getDatetime(itemThing, POSIX.mtime);
105108
if (mtime) {
@@ -111,36 +114,33 @@ export function useBrowseStorage(containerUrl: string | null, refreshKey?: numbe
111114
if (fileSize !== null) {
112115
size = fileSize;
113116
}
114-
}
115117

116-
let finalIsContainer = isContainerUrl;
117-
118-
// Skip RDF fetch for known binary files or files with extensions
119-
if (!isContainerUrl && !isLikelyFile(absoluteUrl) && !isBinaryFile(absoluteUrl)) {
120-
try {
121-
const itemDataset = await getSolidDataset(absoluteUrl, {
122-
fetch: fetchFn,
123-
});
124-
finalIsContainer = isContainer(itemDataset);
125-
} catch (e: any) {
126-
const statusCode = e?.response?.status;
127-
const errorMessage = e instanceof Error ? e.message : String(e);
128-
129-
// Check if it's a 501 error (binary file that can't be converted to RDF)
130-
if (statusCode === 501 ||
131-
errorMessage.includes("501") ||
132-
errorMessage.includes("Not Implemented") ||
133-
errorMessage.includes("No conversion path")) {
134-
// Binary file that can't be converted to RDF - treat as file
135-
finalIsContainer = false;
136-
} else {
137-
// Other errors (404, 403, etc.) - assume it's a file
138-
finalIsContainer = false;
139-
}
118+
// Check RDF types to determine if it's a container (from container listing metadata)
119+
// This avoids making individual HTTP requests for each resource
120+
const types = getIriAll(itemThing, "http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
121+
const isContainerType = types.some(type =>
122+
type === LDP.Container ||
123+
type === LDP.BasicContainer ||
124+
type === "http://www.w3.org/ns/ldp#Container" ||
125+
type === "http://www.w3.org/ns/ldp#BasicContainer"
126+
);
127+
128+
if (isContainerType) {
129+
finalIsContainer = true;
130+
} else {
131+
// If RDF metadata says it's not a container type, trust it
132+
// otherwise only treat as container if URL explicitly ends with "/"
133+
finalIsContainer = isContainerUrl;
134+
}
135+
} else {
136+
// If no RDF metadata available
137+
if (isContainerUrl) {
138+
finalIsContainer = true;
139+
} else if (isBinaryFile(absoluteUrl) || isLikelyFile(absoluteUrl)) {
140+
finalIsContainer = false;
141+
} else {
142+
finalIsContainer = false;
140143
}
141-
} else if (isBinaryFile(absoluteUrl)) {
142-
// Known binary file - treat as file without attempting RDF fetch
143-
finalIsContainer = false;
144144
}
145145

146146
fileItems.push({
@@ -155,13 +155,13 @@ export function useBrowseStorage(containerUrl: string | null, refreshKey?: numbe
155155
console.error(`Failed to process item ${itemUrl}:`, err);
156156
}
157157
}
158-
158+
// sort by folder first then in alphabetical order using the name
159159
fileItems.sort((a, b) => {
160160
if (a.type === "folder" && b.type !== "folder") return -1;
161161
if (a.type !== "folder" && b.type === "folder") return 1;
162162
return a.name.localeCompare(b.name);
163163
});
164-
164+
165165
setFiles(fileItems);
166166
} catch (err) {
167167
const errorMessage =

0 commit comments

Comments
 (0)