This commit is contained in:
Manav Rathi
2025-07-04 16:52:26 +05:30
parent 9020907b56
commit 4e474d4f29
4 changed files with 65 additions and 37 deletions

View File

@@ -17,7 +17,11 @@ interface DownloadStatusNotificationsProps {
* {@link Notification} component that was showing the save group's status.
*/
saveGroups: SaveGroup[];
setAttributesList: (value: SaveGroup[]) => void;
/**
* Called when the user closes the download status associated with the given
* {@link saveGroup}.
*/
onCloseSaveGroup: (saveGroup: SaveGroup) => void;
/**
* Called when the hidden section should be shown.
*
@@ -47,17 +51,13 @@ export const DownloadStatusNotifications: React.FC<
DownloadStatusNotificationsProps
> = ({
saveGroups,
setAttributesList,
onCloseSaveGroup,
onShowHiddenSection,
onShowCollection,
}) => {
const { showMiniDialog } = useBaseContext();
const onClose = (id: number) => {
setAttributesList(saveGroups.filter((attr) => attr.id !== id));
};
const confirmCancelDownload = (attributes: SaveGroup) => {
const confirmCancelDownload = (group: SaveGroup) =>
showMiniDialog({
title: t("stop_downloads_title"),
message: t("stop_downloads_message"),
@@ -65,39 +65,37 @@ export const DownloadStatusNotifications: React.FC<
text: t("yes_stop_downloads"),
color: "critical",
action: () => {
attributes?.canceller.abort();
onClose(attributes.id);
group?.canceller.abort();
onCloseSaveGroup(group);
},
},
cancel: t("no"),
});
};
const handleClose = (attributes: SaveGroup) => () => {
if (isSaveComplete(attributes)) {
onClose(attributes.id);
const createOnClose = (group: SaveGroup) => () => {
if (isSaveComplete(group)) {
onCloseSaveGroup(group);
} else {
confirmCancelDownload(attributes);
confirmCancelDownload(group);
}
};
const createHandleOnClick =
(id: number, onShowCollection: (collectionID: number) => void) =>
() => {
const attributes = saveGroups.find((attr) => attr.id === id);
const electron = globalThis.electron;
if (electron) {
electron.openDirectory(attributes.downloadDirPath);
} else if (onShowCollection) {
if (attributes.isHidden) {
void onShowHiddenSection().then(() => {
onShowCollection(attributes.collectionID);
});
} else {
onShowCollection(attributes.collectionID);
}
const createOnClick = (group: SaveGroup) => () => {
const electron = globalThis.electron;
if (electron) {
electron.openDirectory(group.downloadDirPath);
} else if (onShowCollection) {
if (group.isHidden) {
void onShowHiddenSection().then(() => {
onShowCollection(group.collectionID);
});
} else {
onShowCollection(group.collectionID);
}
};
} else {
return undefined;
}
};
if (!saveGroups) {
return <></>;
@@ -117,7 +115,7 @@ export const DownloadStatusNotifications: React.FC<
horizontal="left"
sx={{ "&&": { bottom: `${index * 80 + 20}px` } }}
open={isSaveStarted(group)}
onClose={handleClose(group)}
onClose={createOnClose(group)}
keepOpenOnClick
attributes={{
color: isSaveCompleteWithErrors(group)
@@ -134,9 +132,7 @@ export const DownloadStatusNotifications: React.FC<
count: group.success + group.failed,
total: group.total,
}),
onClick: onShowCollection
? createHandleOnClick(group.id, onShowCollection)
: undefined,
onClick: createOnClick(group),
}}
/>,
);

View File

@@ -42,6 +42,7 @@ import { savedAuthToken } from "ente-base/token";
import { FullScreenDropZone } from "ente-gallery/components/FullScreenDropZone";
import { type UploadTypeSelectorIntent } from "ente-gallery/components/Upload";
import type {
SaveGroup,
SetFilesDownloadProgressAttributes,
SetFilesDownloadProgressAttributesCreator,
} from "ente-gallery/services/save";
@@ -631,6 +632,10 @@ const Page: React.FC = () => {
};
};
const handleCloseSaveGroup = useCallback(({id}) => setFilesDownloadProgressAttributesList((groups) => groups.filter((g) => g.id != id)), []);
const setFilesDownloadProgressAttributesCreator: SetFilesDownloadProgressAttributesCreator =
useCallback((folderName, collectionID, isHidden) => {
const id = Math.random();
@@ -997,7 +1002,7 @@ const Page: React.FC = () => {
/>
<DownloadStatusNotifications
saveGroups={filesDownloadProgressAttributesList}
setAttributesList={setFilesDownloadProgressAttributesList}
onCloseSaveGroup={handleCloseSaveGroup}
onShowHiddenSection={handleShowHiddenSection}
onShowCollection={handleShowCollection}
/>

View File

@@ -135,6 +135,14 @@ export default function PublicCollectionGallery() {
setFilesDownloadProgressAttributesList,
] = useState<SaveGroup[]>([]);
const handleCloseSaveGroup = useCallback(
({ id }) =>
setFilesDownloadProgressAttributesList((groups) =>
groups.filter((g) => g.id != id),
),
[],
);
const setFilesDownloadProgressAttributesCreator: SetFilesDownloadProgressAttributesCreator =
useCallback((folderName, collectionID, isHidden) => {
const id = Math.random();
@@ -574,7 +582,7 @@ export default function PublicCollectionGallery() {
/>
<DownloadStatusNotifications
saveGroups={filesDownloadProgressAttributesList}
setAttributesList={setFilesDownloadProgressAttributesList}
onCloseSaveGroup={handleCloseSaveGroup}
/>
</FullScreenDropZone>
</PublicCollectionGalleryContext.Provider>

View File

@@ -61,7 +61,16 @@ export interface SaveGroup {
folderName: string;
collectionID: number;
isHidden: boolean;
downloadDirPath: string;
/**
* The path to a directory on the user's file system that was selected by
* the user to save the files in when they initiated the download on the
* desktop app.
*
* This property is only set when running in the context of the desktop app.
* The web app downloads to the user's default downloads folder, and when
* running in the web app this property will not be set.
*/
downloadDirPath?: string;
/**
* An {@link AbortController} that can be used to cancel the save.
*/
@@ -70,12 +79,22 @@ export interface SaveGroup {
export const isSaveStarted = (group: SaveGroup) => group.total > 0;
/**
* Return `true` if there are no files in this save group that are pending.
*/
export const isSaveComplete = ({ total, success, failed }: SaveGroup) =>
total == success + failed;
/**
* Return `true` if there are no files in this save group that are pending, but
* one or more files had failed to download.
*/
export const isSaveCompleteWithErrors = (group: SaveGroup) =>
group.failed > 0 && isSaveComplete(group);
/**
* Return `true` if this save was cancelled on a user request.
*/
export const isSaveCancelled = (group: SaveGroup) =>
group.canceller.signal.aborted;