Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 6 additions & 28 deletions app/components/ShareDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Modal from "./shared/Modal";
import Button from "./shared/Button";
import UrlCombobox, { ComboboxOption } from "./shared/UrlCombobox";
import { FileItemData } from "./FileItem";
import { fetchUserContacts, Contact, addContactToProfile } from "../lib/helpers/contactUtils";
import { fetchUserContacts, Contact } from "../lib/helpers/contactUtils";
import { fetchAndParseProfile } from "../lib/helpers/profileUtils";
import { getResourceAccessList, removeAccessFromResource } from "../lib/helpers/acpUtils";
import { UserIcon, MagnifyingGlassIcon, LockClosedIcon, XMarkIcon, CheckCircleIcon, TrashIcon } from "@heroicons/react/24/outline";
Expand Down Expand Up @@ -86,7 +86,7 @@ export default function ShareDialog({
try {
const resourceUrl = file.type === "folder" && !file.url.endsWith("/") ? file.url + "/" : file.url;
await removeAccessFromResource(resourceUrl, webIdToRemove);

// Refresh the access list
const updatedList = await getResourceAccessList(resourceUrl);
setAccessList(updatedList);
Expand Down Expand Up @@ -186,36 +186,14 @@ export default function ShareDialog({
// Share with all people using the selected access level
const webIds = peopleChips.map((chip) => chip.webId);
await onShare(webIds, selectedAccessLevel);

// After successful sharing, add new WebIDs to contacts if they're not already there
const existingContactWebIds = new Set(contacts.map(c => c.webId));
const newWebIds = webIds.filter(webId => !existingContactWebIds.has(webId));

for (const webId of newWebIds) {
try {
await addContactToProfile(webId);
} catch (error) {
console.warn(`Failed to add ${webId} to contacts:`, error);
}
}

// Refresh contacts list if we added any new ones
if (newWebIds.length > 0) {
try {
const updatedContacts = await fetchUserContacts();
setContacts(updatedContacts);
} catch (error) {
console.warn("Failed to refresh contacts list:", error);
}
}


// Refresh access list after sharing
if (file) {
const resourceUrl = file.type === "folder" && !file.url.endsWith("/") ? file.url + "/" : file.url;
const updatedList = await getResourceAccessList(resourceUrl);
setAccessList(updatedList);
}

onClose();
} catch (error) {
console.error("Failed to share:", error);
Expand Down Expand Up @@ -273,7 +251,7 @@ export default function ShareDialog({
<label className="mb-2 block text-sm font-medium text-gray-700">
Add a WebID
</label>

{/* Chips display */}
{peopleChips.length > 0 && (
<div className="mb-3 flex flex-wrap gap-2">
Expand Down Expand Up @@ -346,7 +324,7 @@ export default function ShareDialog({
const hasWrite = access.accessModes.some((mode) => mode.includes("Write"));
const accessLevel = hasWrite ? "Editor" : "Viewer";
const isRemoving = removingWebId === access.webId;

return (
<div
key={access.webId || index}
Expand Down
38 changes: 2 additions & 36 deletions app/lib/helpers/contactUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { fetchAndParseProfile } from "./profileUtils";
import { getSession, getAuthenticatedSession } from "./sessionUtils";
import { fromRdfJsDataset, saveSolidDatasetAt } from "@inrupt/solid-client";
import { getSession } from "./sessionUtils";

export interface Contact {
webId: string;
Expand Down Expand Up @@ -54,37 +53,4 @@ export async function fetchUserContacts(): Promise<Contact[]> {
console.error("Failed to fetch user contacts:", error);
return [];
}
}

/**
* Adds a contact (WebID) to the user's profile using foaf:knows relationship
* @param contactWebId - The WebID of the contact to add
* @returns Promise that resolves when the contact is added
*/
export async function addContactToProfile(contactWebId: string): Promise<void> {
const session = getSession();

if (!session.info.isLoggedIn || !session.info.webId) {
throw new Error("User is not logged in");
}

const userWebId = session.info.webId;
const { fetch } = getAuthenticatedSession();

const profileUrl = userWebId.split('#')[0];

try {
// Fetch the user's profile dataset
// Get the main subject (usually WebID or WebID#me)
const mainSubject = await fetchAndParseProfile(profileUrl);

// Add the foaf:knows relationship
mainSubject.knows.add(contactWebId);

// Save the updated dataset
await saveSolidDatasetAt(profileUrl, fromRdfJsDataset(mainSubject.dataset), { fetch });
} catch (error) {
console.error("Failed to add contact to profile:", error);
throw error;
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure there is an EOF character here - and open an issue to set up eslint so that we have linting rules stopping this from happening in the future.