This commit is contained in:
Manav Rathi
2025-02-27 17:07:58 +05:30
parent 0bfd355233
commit e87d596b4c
3 changed files with 108 additions and 46 deletions

View File

@@ -554,6 +554,7 @@ const PhotoFrame = ({
onTriggerSyncWithRemote={handleTriggerSyncWithRemote} onTriggerSyncWithRemote={handleTriggerSyncWithRemote}
onSaveEditedImageCopy={handleSaveEditedImageCopy} onSaveEditedImageCopy={handleSaveEditedImageCopy}
{...{ {...{
favoriteFileIDs,
fileCollectionIDs, fileCollectionIDs,
allCollectionsNameByID, allCollectionsNameByID,
onSelectCollection, onSelectCollection,

View File

@@ -76,6 +76,13 @@ export type FileViewerProps = ModalVisibilityProps & {
* If true then the viewer does not show controls for downloading the file. * If true then the viewer does not show controls for downloading the file.
*/ */
disableDownload?: boolean; disableDownload?: boolean;
/**
* File IDs of all the files that the user has marked as a favorite.
*
* If this is not provided then the favorite toggle button will not be shown
* in the file actions.
*/
favoriteFileIDs?: Set<number>;
/** /**
* Called when there was some update performed within the file viewer that * Called when there was some update performed within the file viewer that
* necessitates us to sync with remote again to fetch the latest updates. * necessitates us to sync with remote again to fetch the latest updates.
@@ -119,6 +126,7 @@ const FileViewer: React.FC<FileViewerProps> = ({
files, files,
initialIndex, initialIndex,
disableDownload, disableDownload,
favoriteFileIDs,
fileCollectionIDs, fileCollectionIDs,
allCollectionsNameByID, allCollectionsNameByID,
onSelectCollection, onSelectCollection,
@@ -162,14 +170,27 @@ const FileViewer: React.FC<FileViewerProps> = ({
const handleAnnotate = useCallback( const handleAnnotate = useCallback(
(file: EnteFile) => { (file: EnteFile) => {
log.debug(() => ["viewer", { action: "annotate", file }]);
const fileID = file.id; const fileID = file.id;
const isOwnFile = file.ownerID == user?.id; const isOwnFile = file.ownerID == user?.id;
const isEditableImage = fileIsEditableImage(file); const isFavorite = favoriteFileIDs?.has(file.id);
return { fileID, isOwnFile, isEditableImage }; const isEditableImage = onSaveEditedImageCopy
? fileIsEditableImage(file)
: undefined;
return { fileID, isOwnFile, isFavorite, isEditableImage };
}, },
[user], [user, favoriteFileIDs, onSaveEditedImageCopy],
); );
const handleToggleFavorite = useMemo(() => {
return favoriteFileIDs
? (annotatedFile: FileViewerAnnotatedFile) => {
setActiveAnnotatedFile(annotatedFile);
console.log("handleToggleFavorite", annotatedFile);
}
: undefined;
}, [favoriteFileIDs]);
const handleViewInfo = useCallback( const handleViewInfo = useCallback(
(annotatedFile: FileViewerAnnotatedFile) => { (annotatedFile: FileViewerAnnotatedFile) => {
setActiveAnnotatedFile(annotatedFile); setActiveAnnotatedFile(annotatedFile);
@@ -208,7 +229,6 @@ const FileViewer: React.FC<FileViewerProps> = ({
return onSaveEditedImageCopy return onSaveEditedImageCopy
? (annotatedFile: FileViewerAnnotatedFile) => { ? (annotatedFile: FileViewerAnnotatedFile) => {
setActiveAnnotatedFile(annotatedFile); setActiveAnnotatedFile(annotatedFile);
setActiveFileExif(undefined);
setOpenImageEditor(true); setOpenImageEditor(true);
} }
: undefined; : undefined;
@@ -242,6 +262,7 @@ const FileViewer: React.FC<FileViewerProps> = ({
disableDownload, disableDownload,
onClose: handleClose, onClose: handleClose,
onAnnotate: handleAnnotate, onAnnotate: handleAnnotate,
onToggleFavorite: handleToggleFavorite,
onViewInfo: handleViewInfo, onViewInfo: handleViewInfo,
onEditImage: handleEditImage, onEditImage: handleEditImage,
}); });

View File

@@ -1,11 +1,11 @@
/* eslint-disable */ /* eslint-disable */
// @ts-nocheck // @ts-nocheck
import { pt } from "@/base/i18n";
import log from "@/base/log"; import log from "@/base/log";
import type { EnteFile } from "@/media/file"; import type { EnteFile } from "@/media/file";
import { FileType } from "@/media/file-type"; import { FileType } from "@/media/file-type";
import { t } from "i18next"; import { t } from "i18next";
import { pt } from "@/base/i18n";
import { import {
forgetExif, forgetExif,
forgetExifForItemData, forgetExifForItemData,
@@ -35,31 +35,6 @@ if (process.env.NEXT_PUBLIC_ENTE_WIP_PS5) {
PhotoSwipe = require("./ps5/dist/photoswipe.esm.js").default; PhotoSwipe = require("./ps5/dist/photoswipe.esm.js").default;
} }
type FileViewerPhotoSwipeOptions = {
/**
* Called when the file viewer is closed.
*/
onClose: () => void;
/**
* Called whenever the slide changes to obtain the derived data for the file
* that is about to be displayed.
*/
onAnnotate: (file: EnteFile) => FileViewerFileAnnotation;
/**
* Called when the user activates the info action on a file.
*/
onViewInfo: (annotatedFile: FileViewerAnnotatedFile) => void;
/**
* Called when the user activates the edit action on an image.
*
* If this callback is not provided, then the edit button is never shown. If
* this callback is provided, then the visibility of the edit button is
* determined by the {@link isEditableImage} property of
* {@link FileViewerFileAnnotation} for the file.
*/
onEditImage?: (annotatedFile: FileViewerAnnotatedFile) => void;
} & Pick<FileViewerProps, "files" | "initialIndex" | "disableDownload">;
/** /**
* Derived data for a file that is needed to display the file viewer controls * Derived data for a file that is needed to display the file viewer controls
* etc associated with the file. * etc associated with the file.
@@ -75,15 +50,59 @@ export interface FileViewerFileAnnotation {
* `true` if this file is owned by the logged in user (if any). * `true` if this file is owned by the logged in user (if any).
*/ */
isOwnFile: boolean; isOwnFile: boolean;
/**
* `true` if this file has been marked as a favorite by the user.
*
* It will not be provided if favorite functionality is not available.
*
* Otherwise it determines the toggle state of the toggle favorite button.
*/
isFavorite?: boolean;
/** /**
* `true` if this is an image which can be edited. * `true` if this is an image which can be edited.
* *
* The edit button is shown when this is true. See also the * It will not be provided if editing is not available.
*
* Otherwise the edit button is shown when this is true. See also the
* {@link onEditImage} option for {@link FileViewerPhotoSwipe} constructor. * {@link onEditImage} option for {@link FileViewerPhotoSwipe} constructor.
*/ */
isEditableImage: boolean; isEditableImage?: boolean;
} }
type FileViewerPhotoSwipeOptions = {
/**
* Called when the file viewer is closed.
*/
onClose: () => void;
/**
* Called whenever the slide changes to obtain the derived data for the file
* that is about to be displayed.
*/
onAnnotate: (file: EnteFile) => FileViewerFileAnnotation;
/**
* Called when the user activates the toggle favorite action on a file.
*
* If this callback is not provided, then the toggle favorite button is not
* shown. If this callback is provided, then the current toggle state of the
* favorite button is determined by the {@link isFavorite} property of
* {@link FileViewerFileAnnotation} for the file.
*/
onToggleFavorite?: (annotatedFile: FileViewerAnnotatedFile) => void;
/**
* Called when the user activates the info action on a file.
*/
onViewInfo: (annotatedFile: FileViewerAnnotatedFile) => void;
/**
* Called when the user activates the edit action on an image.
*
* If this callback is not provided, then the edit button is never shown. If
* this callback is provided, then the visibility of the edit button is
* determined by the {@link isEditableImage} property of
* {@link FileViewerFileAnnotation} for the file.
*/
onEditImage?: (annotatedFile: FileViewerAnnotatedFile) => void;
} & Pick<FileViewerProps, "files" | "initialIndex" | "disableDownload">;
/** /**
* A file and its annotation, in a nice cosy box. * A file and its annotation, in a nice cosy box.
*/ */
@@ -159,6 +178,7 @@ export class FileViewerPhotoSwipe {
disableDownload, disableDownload,
onClose, onClose,
onAnnotate, onAnnotate,
onToggleFavorite,
onViewInfo, onViewInfo,
onEditImage, onEditImage,
}: FileViewerPhotoSwipeOptions) { }: FileViewerPhotoSwipeOptions) {
@@ -416,14 +436,26 @@ export class FileViewerPhotoSwipe {
}); });
}, },
}); });
pswp.ui.registerElement({
name: "info", if (onToggleFavorite) {
title: t("info"), pswp.ui.registerElement({
order: 16, name: "favorite",
isButton: true, title: t("favorite"),
html: createPSRegisterElementIconHTML("info"), order: 15,
onClick: withCurrentAnnotatedFile(onViewInfo), isButton: true,
}); html: createPSRegisterElementIconHTML("favorite"),
onClick: withCurrentAnnotatedFile(onToggleFavorite),
onInit: (buttonElement, pswp) => {
// TODO:
// pswp.on("change", () =>
// buttonElement.classList.toggle(
// "pswp--ui-visible",
// currentFileAnnotation().isFavorite,
// ),
// );
},
});
}
if (onEditImage) { if (onEditImage) {
pswp.ui.registerElement({ pswp.ui.registerElement({
@@ -431,21 +463,29 @@ export class FileViewerPhotoSwipe {
// TODO(PS): // TODO(PS):
// title: t("edit_image"), // title: t("edit_image"),
title: pt("Edit image"), title: pt("Edit image"),
order: 15, order: 16,
isButton: true, isButton: true,
html: createPSRegisterElementIconHTML("edit"), html: createPSRegisterElementIconHTML("edit"),
onClick: withCurrentAnnotatedFile(onEditImage), onClick: withCurrentAnnotatedFile(onEditImage),
onInit: (buttonElement, pswp) => { onInit: (buttonElement, pswp) => {
pswp.on("change", () => { pswp.on("change", () =>
const { annotation } = currentAnnotatedFile();
buttonElement.classList.toggle( buttonElement.classList.toggle(
"pswp--ui-visible", "pswp--ui-visible",
annotation.isEditableImage, currentFileAnnotation().isEditableImage,
); ),
}); );
}, },
}); });
} }
pswp.ui.registerElement({
name: "info",
title: t("info"),
order: 17,
isButton: true,
html: createPSRegisterElementIconHTML("info"),
onClick: withCurrentAnnotatedFile(onViewInfo),
});
}); });
// Modify the default UI elements. // Modify the default UI elements.