+ sidebar
This commit is contained in:
@@ -24,7 +24,11 @@ interface DownloadStatusNotificationsProps {
|
||||
onRemoveSaveGroup: (saveGroup: SaveGroup) => void;
|
||||
/**
|
||||
* Called when the collection summary with the given {@link collectionID}
|
||||
* and "hidden" {@link attribute} should be shown.
|
||||
* should be shown. If {@link isHiddenCollectionSummary} is set, then any
|
||||
* reauthentication as appropriate before switching to the hidden section of
|
||||
* the app is performed first.
|
||||
*
|
||||
* and hidden attribute should be shown.
|
||||
*
|
||||
* This is only relevant in the context of the photos app, and can be
|
||||
* omitted by the public albums app. See the documentation of
|
||||
|
||||
@@ -140,18 +140,23 @@ type SidebarProps = ModalVisibilityProps & {
|
||||
*/
|
||||
onShowPlanSelector: () => void;
|
||||
/**
|
||||
* Called when the collection summary with the given
|
||||
* {@link collectionSummaryID} should be shown.
|
||||
*/
|
||||
onShowCollectionSummary: (collectionSummaryID: number) => void;
|
||||
/**
|
||||
* Called when the hidden section should be shown.
|
||||
* Called when the collection summary with the given {@link collectionID}
|
||||
* should be shown.
|
||||
*
|
||||
* This triggers the display of the dialog to authenticate the user, exactly
|
||||
* as if {@link onAuthenticateUser} were called. Then, on successful
|
||||
* authentication, the gallery will switch to the hidden section.
|
||||
* @param collectionSummaryID The ID of the {@link CollectionSummary} to
|
||||
* switch to.
|
||||
*
|
||||
* @param isHiddenCollectionSummary If `true`, then any reauthentication as
|
||||
* appropriate before switching to the hidden section of the app is
|
||||
* performed first before showing the collection summary.
|
||||
*
|
||||
* @return A promise that fullfills after any needed reauthentication has
|
||||
* been peformed (The view transition might still be in progress).
|
||||
*/
|
||||
onShowHiddenSection: () => Promise<void>;
|
||||
onShowCollectionSummary: (
|
||||
collectionSummaryID: number,
|
||||
isHiddenCollectionSummary?: boolean,
|
||||
) => Promise<void>;
|
||||
/**
|
||||
* Called when the export dialog should be shown.
|
||||
*/
|
||||
@@ -175,7 +180,6 @@ export const Sidebar: React.FC<SidebarProps> = ({
|
||||
uncategorizedCollectionSummaryID,
|
||||
onShowPlanSelector,
|
||||
onShowCollectionSummary,
|
||||
onShowHiddenSection,
|
||||
onShowExport,
|
||||
onAuthenticateUser,
|
||||
}) => (
|
||||
@@ -189,7 +193,6 @@ export const Sidebar: React.FC<SidebarProps> = ({
|
||||
normalCollectionSummaries,
|
||||
uncategorizedCollectionSummaryID,
|
||||
onShowCollectionSummary,
|
||||
onShowHiddenSection,
|
||||
}}
|
||||
/>
|
||||
<UtilitySection
|
||||
@@ -461,7 +464,6 @@ type ShortcutSectionProps = SectionProps &
|
||||
| "normalCollectionSummaries"
|
||||
| "uncategorizedCollectionSummaryID"
|
||||
| "onShowCollectionSummary"
|
||||
| "onShowHiddenSection"
|
||||
>;
|
||||
|
||||
const ShortcutSection: React.FC<ShortcutSectionProps> = ({
|
||||
@@ -469,25 +471,26 @@ const ShortcutSection: React.FC<ShortcutSectionProps> = ({
|
||||
normalCollectionSummaries,
|
||||
uncategorizedCollectionSummaryID,
|
||||
onShowCollectionSummary,
|
||||
onShowHiddenSection,
|
||||
}) => {
|
||||
const openUncategorizedSection = () => {
|
||||
onShowCollectionSummary(uncategorizedCollectionSummaryID);
|
||||
onCloseSidebar();
|
||||
};
|
||||
const handleOpenUncategorizedSection = () =>
|
||||
void onShowCollectionSummary(uncategorizedCollectionSummaryID).then(
|
||||
onCloseSidebar,
|
||||
);
|
||||
|
||||
const openTrashSection = () => {
|
||||
onShowCollectionSummary(PseudoCollectionID.trash);
|
||||
onCloseSidebar();
|
||||
};
|
||||
const handleOpenTrashSection = () =>
|
||||
void onShowCollectionSummary(PseudoCollectionID.trash).then(
|
||||
onCloseSidebar,
|
||||
);
|
||||
|
||||
const openArchiveSection = () => {
|
||||
onShowCollectionSummary(PseudoCollectionID.archiveItems);
|
||||
onCloseSidebar();
|
||||
};
|
||||
const handleOpenArchiveSection = () =>
|
||||
void onShowCollectionSummary(PseudoCollectionID.archiveItems).then(
|
||||
onCloseSidebar,
|
||||
);
|
||||
|
||||
const openHiddenSection = () =>
|
||||
void onShowHiddenSection().then(onCloseSidebar);
|
||||
const handleOpenHiddenSection = () =>
|
||||
void onShowCollectionSummary(PseudoCollectionID.hiddenItems, true).then(
|
||||
onCloseSidebar,
|
||||
);
|
||||
|
||||
const summaryCaption = (summaryID: number) =>
|
||||
normalCollectionSummaries.get(summaryID)?.fileCount.toString();
|
||||
@@ -498,13 +501,13 @@ const ShortcutSection: React.FC<ShortcutSectionProps> = ({
|
||||
startIcon={<CategoryIcon />}
|
||||
label={t("section_uncategorized")}
|
||||
caption={summaryCaption(uncategorizedCollectionSummaryID)}
|
||||
onClick={openUncategorizedSection}
|
||||
onClick={handleOpenUncategorizedSection}
|
||||
/>
|
||||
<RowButton
|
||||
startIcon={<ArchiveOutlinedIcon />}
|
||||
label={t("section_archive")}
|
||||
caption={summaryCaption(PseudoCollectionID.archiveItems)}
|
||||
onClick={openArchiveSection}
|
||||
onClick={handleOpenArchiveSection}
|
||||
/>
|
||||
<RowButton
|
||||
startIcon={<VisibilityOffIcon />}
|
||||
@@ -517,13 +520,13 @@ const ShortcutSection: React.FC<ShortcutSectionProps> = ({
|
||||
}}
|
||||
/>
|
||||
}
|
||||
onClick={openHiddenSection}
|
||||
onClick={handleOpenHiddenSection}
|
||||
/>
|
||||
<RowButton
|
||||
startIcon={<DeleteOutlineIcon />}
|
||||
label={t("section_trash")}
|
||||
caption={summaryCaption(PseudoCollectionID.trash)}
|
||||
onClick={openTrashSection}
|
||||
onClick={handleOpenTrashSection}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -89,7 +89,6 @@ import {
|
||||
import {
|
||||
haveOnlySystemCollections,
|
||||
PseudoCollectionID,
|
||||
type CollectionSummary,
|
||||
} from "ente-new/photos/services/collection-summary";
|
||||
import exportService from "ente-new/photos/services/export";
|
||||
import { updateFilesVisibility } from "ente-new/photos/services/file";
|
||||
@@ -790,80 +789,74 @@ const Page: React.FC = () => {
|
||||
setUploadTypeSelectorIntent(intent ?? "upload");
|
||||
};
|
||||
|
||||
const handleShowCollectionSummaryWithID = (
|
||||
collectionSummaryID: number | undefined,
|
||||
) => {
|
||||
// Trigger a pull of the latest data from remote when opening the trash.
|
||||
//
|
||||
// This is needed for a specific scenario:
|
||||
//
|
||||
// 1. User deletes a collection, selecting the option to delete files.
|
||||
// 2. Museum acks, and then client does a trash pull.
|
||||
//
|
||||
// This trash pull will not contain the files that belonged to the
|
||||
// collection that got deleted because the collection deletion is a
|
||||
// asynchronous operation.
|
||||
//
|
||||
// So the user might not see the entry for the just deleted file if they
|
||||
// were to go to the trash meanwhile (until the next pull happens). To
|
||||
// avoid this, we trigger a trash pull whenever it is opened.
|
||||
if (collectionSummaryID == PseudoCollectionID.trash) {
|
||||
void remoteFilesPull();
|
||||
}
|
||||
const handleShowCollectionSummaryWithID = useCallback(
|
||||
(collectionSummaryID: number | undefined) => {
|
||||
// Trigger a pull of the latest data from remote when opening the trash.
|
||||
//
|
||||
// This is needed for a specific scenario:
|
||||
//
|
||||
// 1. User deletes a collection, selecting the option to delete files.
|
||||
// 2. Museum acks, and then client does a trash pull.
|
||||
//
|
||||
// This trash pull will not contain the files that belonged to the
|
||||
// collection that got deleted because the collection deletion is a
|
||||
// asynchronous operation.
|
||||
//
|
||||
// So the user might not see the entry for the just deleted file if they
|
||||
// were to go to the trash meanwhile (until the next pull happens). To
|
||||
// avoid this, we trigger a trash pull whenever it is opened.
|
||||
if (collectionSummaryID == PseudoCollectionID.trash) {
|
||||
void remoteFilesPull();
|
||||
}
|
||||
|
||||
dispatch({ type: "showCollectionSummary", collectionSummaryID });
|
||||
};
|
||||
dispatch({ type: "showCollectionSummary", collectionSummaryID });
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
/**
|
||||
* Switch to gallery view to show the {@link CollectionSummary}.
|
||||
* Switch to gallery view to show a collection or pseudo-collection.
|
||||
*
|
||||
* @param cs The {@link CollectionSummary} to show.
|
||||
* If a {@link CollectionSummary} is not provided, show the "All" section.
|
||||
* @param collectionSummaryID The ID of the {@link CollectionSummary} to
|
||||
* show. If not provided, show the "All" section.
|
||||
*
|
||||
* If the given {@link CollectionSummary} is hidden, first perform any
|
||||
* reauthentication as would be needed for showing the hidden section in the
|
||||
* app, and then shows the {@link CollectionSummary}.
|
||||
* @param isHidden If `true`, then any reauthentication as appropriate
|
||||
* before switching to the hidden section of the app is performed first
|
||||
* before before switching to the relevant collection or pseudo-collection.
|
||||
*/
|
||||
// TODO(RE):
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const handleShowCollectionSummary = (cs: CollectionSummary | undefined) => {
|
||||
if (cs?.attributes.has("hidden")) {
|
||||
void handleShowHiddenSection().then(() => {
|
||||
handleShowCollectionSummaryWithID(cs.id);
|
||||
});
|
||||
} else {
|
||||
handleShowCollectionSummaryWithID(cs.id);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A variant / reimplementation of {@link handleShowCollectionSummary} for
|
||||
* use by the {@link DownloadStatusNotifications} component (which does not
|
||||
* know about the {@link CollectionSummary} TypeScript type).
|
||||
*/
|
||||
const handleDownloadStatusNotificationsShowCollectionSummary = (
|
||||
collectionSummaryID: number | undefined,
|
||||
isHiddenCollectionSummary: boolean | undefined,
|
||||
) => {
|
||||
if (isHiddenCollectionSummary) {
|
||||
void handleShowHiddenSection().then(() => {
|
||||
handleShowCollectionSummaryWithID(collectionSummaryID);
|
||||
});
|
||||
} else {
|
||||
const showCollectionSummary = useCallback(
|
||||
async (
|
||||
collectionSummaryID: number | undefined,
|
||||
isHiddenCollectionSummary: boolean | undefined,
|
||||
) => {
|
||||
if (isHiddenCollectionSummary) {
|
||||
await authenticateUser();
|
||||
}
|
||||
handleShowCollectionSummaryWithID(collectionSummaryID);
|
||||
}
|
||||
};
|
||||
},
|
||||
[authenticateUser, handleShowCollectionSummaryWithID],
|
||||
);
|
||||
|
||||
const handleSidebarShowCollectionSummary = showCollectionSummary;
|
||||
|
||||
const handleDownloadStatusNotificationsShowCollectionSummary = useCallback(
|
||||
(
|
||||
collectionSummaryID: number | undefined,
|
||||
isHiddenCollectionSummary: boolean | undefined,
|
||||
) => {
|
||||
void showCollectionSummary(
|
||||
collectionSummaryID,
|
||||
isHiddenCollectionSummary,
|
||||
);
|
||||
},
|
||||
[showCollectionSummary],
|
||||
);
|
||||
|
||||
const handleChangeBarMode = (mode: GalleryBarMode) =>
|
||||
mode == "people"
|
||||
? dispatch({ type: "showPeople" })
|
||||
: dispatch({ type: "showAlbums" });
|
||||
|
||||
const handleShowHiddenSection = useCallback(
|
||||
() => authenticateUser().then(() => dispatch({ type: "showHidden" })),
|
||||
[],
|
||||
);
|
||||
|
||||
const handleFileViewerToggleFavorite = useCallback(
|
||||
async (file: EnteFile) => {
|
||||
const fileID = file.id;
|
||||
@@ -1114,8 +1107,7 @@ const Page: React.FC = () => {
|
||||
state.uncategorizedCollectionSummaryID
|
||||
}
|
||||
onShowPlanSelector={showPlanSelector}
|
||||
onShowCollectionSummary={handleShowCollectionSummaryWithID}
|
||||
onShowHiddenSection={handleShowHiddenSection}
|
||||
onShowCollectionSummary={handleSidebarShowCollectionSummary}
|
||||
onShowExport={showExport}
|
||||
onAuthenticateUser={authenticateUser}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user