fix: enhance sharing functionality by renaming state

This commit is contained in:
Linus Rath
2026-05-04 11:24:05 +02:00
parent 2e1f53c899
commit f68e41d81a
2 changed files with 20 additions and 11 deletions
+14 -11
View File
@@ -79,7 +79,7 @@ export function ShareCollectionDialog({
const t = useTranslations("sharing"); const t = useTranslations("sharing");
const tCommon = useTranslations("common"); const tCommon = useTranslations("common");
const modalRef = useRef<HTMLDivElement>(null); const modalRef = useRef<HTMLDivElement>(null);
const [principals, setPrincipals] = useState<Principal[]>([]); const [allPrincipals, setAllPrincipals] = useState<Principal[]>([]);
const [loadingPrincipals, setLoadingPrincipals] = useState(true); const [loadingPrincipals, setLoadingPrincipals] = useState(true);
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
const [savingId, setSavingId] = useState<string | null>(null); const [savingId, setSavingId] = useState<string | null>(null);
@@ -91,23 +91,28 @@ export function ShareCollectionDialog({
setLoadingPrincipals(true); setLoadingPrincipals(true);
client.getPrincipals().then((list) => { client.getPrincipals().then((list) => {
if (cancelled) return; if (cancelled) return;
// Exclude the user themselves and any principal that already has a share setAllPrincipals(list);
const existing = new Set(Object.keys(shareWith || {}));
const filtered = list.filter((p) => p.id !== ownAccountId && !existing.has(p.id));
setPrincipals(filtered);
setLoadingPrincipals(false); setLoadingPrincipals(false);
}).catch(() => { }).catch(() => {
if (!cancelled) setLoadingPrincipals(false); if (!cancelled) setLoadingPrincipals(false);
}); });
return () => { cancelled = true; }; return () => { cancelled = true; };
}, [client, ownAccountId, shareWith]); }, [client]);
// Map principal id -> Principal for displayed shares // Map of every fetched principal by id, used for name/description lookups in
// the shared list. Must include principals that already have a share so the
// list shows their name rather than the raw id.
const allPrincipalsById = useMemo(() => { const allPrincipalsById = useMemo(() => {
const map = new Map<string, Principal>(); const map = new Map<string, Principal>();
for (const p of principals) map.set(p.id, p); for (const p of allPrincipals) map.set(p.id, p);
return map; return map;
}, [principals]); }, [allPrincipals]);
// Principals available to add: exclude self and anyone already shared with.
const principals = useMemo(() => {
const existing = new Set(Object.keys(shareWith || {}));
return allPrincipals.filter((p) => p.id !== ownAccountId && !existing.has(p.id));
}, [allPrincipals, ownAccountId, shareWith]);
// Close on Escape, focus trap, click outside // Close on Escape, focus trap, click outside
useEffect(() => { useEffect(() => {
@@ -155,8 +160,6 @@ export function ShareCollectionDialog({
setSavingId(principal.id); setSavingId(principal.id);
try { try {
await onShare(principal.id, rights); await onShare(principal.id, rights);
// Move principal out of the "to add" list
setPrincipals((prev) => prev.filter((p) => p.id !== principal.id));
setShowAdd(false); setShowAdd(false);
setSearch(""); setSearch("");
toast.success(t("share_added")); toast.success(t("share_added"));
+6
View File
@@ -3314,6 +3314,9 @@ export class JMAPClient implements IJMAPClient {
const err = result.notUpdated[calendarId]; const err = result.notUpdated[calendarId];
throw new Error(err.description || "Failed to update calendar share"); throw new Error(err.description || "Failed to update calendar share");
} }
if (!result?.updated || !(calendarId in result.updated)) {
throw new Error("Server did not confirm the share update");
}
} }
/** /**
@@ -3339,6 +3342,9 @@ export class JMAPClient implements IJMAPClient {
const err = result.notUpdated[addressBookId]; const err = result.notUpdated[addressBookId];
throw new Error(err.description || "Failed to update address book share"); throw new Error(err.description || "Failed to update address book share");
} }
if (!result?.updated || !(addressBookId in result.updated)) {
throw new Error("Server did not confirm the share update");
}
} }
private async fetchPaginatedContacts( private async fetchPaginatedContacts(