code cleanup and fixes
This commit is contained in:
@@ -56,24 +56,24 @@ const AddNewDropdown: React.FC<AddNewDropdownProps> = (props) => {
|
||||
multiple={true}
|
||||
onChange={handleUpload}
|
||||
/>
|
||||
<ul className="pl-0 list-none m-0 rounded-[5px] overflow-hidden shadow-md">
|
||||
<ul className="rounded-sm overflow-hidden shadow-lg">
|
||||
<li>
|
||||
<div>
|
||||
<a
|
||||
className="flex items-center justify-start p-[12px_20px] no-underline rounded-[5px] overflow-hidden text-[15px] leading-[18px] bg-white hover:bg-[#f6f5fd]"
|
||||
className="flex items-center justify-start px-5 py-3 no-underline overflow-hidden text-sm bg-white hover:bg-white-hover"
|
||||
onClick={triggerFileUpload}
|
||||
>
|
||||
<UploadFileIcon className="w-[20px] h-[20px] mr-[10px] text-[#3c85ee]" />
|
||||
<UploadFileIcon className="w-5 h-5 mr-2.5 text-primary" />
|
||||
<p className="text-sm">Upload Files</p>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
className="flex items-center justify-start p-[12px_20px] no-underline rounded-[5px] overflow-hidden text-[15px] leading-[18px] bg-white hover:bg-[#f6f5fd]"
|
||||
className="flex items-center justify-start px-5 py-3 no-underline overflow-hidden text-sm bg-white hover:bg-white-hover"
|
||||
onClick={createFolder}
|
||||
>
|
||||
<CreateFolderIcon className="w-[20px] h-[20px] mr-[10px] text-[#3c85ee]" />
|
||||
<CreateFolderIcon className="w-5 h-5 mr-2.5 text-primary" />
|
||||
<p className="text-sm">Create Folder</p>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -61,20 +61,26 @@ const ContextMenu: React.FC<ContextMenuProps> = memo((props) => {
|
||||
const { invalidateFilesCache } = useFilesClient();
|
||||
const { invalidateFoldersCache } = useFoldersClient();
|
||||
const { invalidateQuickFilesCache } = useQuickFilesClient();
|
||||
const { wrapperRef } = useClickOutOfBounds(props.closeContext);
|
||||
const {
|
||||
closeContext,
|
||||
contextSelected,
|
||||
folderMode,
|
||||
file,
|
||||
quickItemMode,
|
||||
stopPropagation,
|
||||
folder,
|
||||
} = props;
|
||||
const { wrapperRef } = useClickOutOfBounds(closeContext);
|
||||
const { isTrash, isMedia } = useUtils();
|
||||
const dispatch = useAppDispatch();
|
||||
const liClassname =
|
||||
"flex w-full px-[20px] py-[12px] items-center font-normal text-[#637381] justify-start no-underline animate hover:bg-[#f6f5fd] hover:text-[#3c85ee] hover:font-medium";
|
||||
const spanClassname = "flex items-center justify-center mr-[18px]";
|
||||
|
||||
const renameItem = async () => {
|
||||
props.closeContext();
|
||||
if (!props.folderMode && props.file) {
|
||||
closeContext();
|
||||
if (!folderMode && file) {
|
||||
try {
|
||||
const filename = await renameFilePopup(props.file.filename);
|
||||
if (!filename || filename === props.file.filename) return;
|
||||
await toast.promise(renameFileAPI(props.file._id, filename), {
|
||||
const filename = await renameFilePopup(file.filename);
|
||||
if (!filename || filename === file.filename) return;
|
||||
await toast.promise(renameFileAPI(file._id, filename), {
|
||||
pending: "Renaming...",
|
||||
success: "Renamed",
|
||||
error: "Error Renaming",
|
||||
@@ -84,11 +90,11 @@ const ContextMenu: React.FC<ContextMenuProps> = memo((props) => {
|
||||
} catch (e) {
|
||||
console.log("Error renaming file", e);
|
||||
}
|
||||
} else if (props.folderMode && props.folder) {
|
||||
} else if (folderMode && folder) {
|
||||
try {
|
||||
const folderName = await renameFolderPopup(props.folder.name);
|
||||
if (!folderName || folderName === props.folder.name) return;
|
||||
await toast.promise(renameFolder(props.folder._id, folderName), {
|
||||
const folderName = await renameFolderPopup(folder.name);
|
||||
if (!folderName || folderName === folder.name) return;
|
||||
await toast.promise(renameFolder(folder._id, folderName), {
|
||||
pending: "Renaming...",
|
||||
success: "Renamed",
|
||||
error: "Error Renaming",
|
||||
@@ -101,13 +107,13 @@ const ContextMenu: React.FC<ContextMenuProps> = memo((props) => {
|
||||
};
|
||||
|
||||
const trashItem = async () => {
|
||||
props.closeContext();
|
||||
if (!props.folderMode && props.file) {
|
||||
closeContext();
|
||||
if (!folderMode && file) {
|
||||
try {
|
||||
const result = await trashItemsPopup();
|
||||
if (!result) return;
|
||||
|
||||
await toast.promise(trashFileAPI(props.file._id), {
|
||||
await toast.promise(trashFileAPI(file._id), {
|
||||
pending: "Trashing...",
|
||||
success: "Trashed",
|
||||
error: "Error Trashing",
|
||||
@@ -118,12 +124,12 @@ const ContextMenu: React.FC<ContextMenuProps> = memo((props) => {
|
||||
} catch (e) {
|
||||
console.log("Error trashing file", e);
|
||||
}
|
||||
} else if (props.folderMode && props.folder) {
|
||||
} else if (folderMode && folder) {
|
||||
try {
|
||||
const result = await trashItemsPopup();
|
||||
if (!result) return;
|
||||
|
||||
await toast.promise(trashFolderAPI(props.folder._id), {
|
||||
await toast.promise(trashFolderAPI(folder._id), {
|
||||
pending: "Trashing...",
|
||||
success: "Trashed",
|
||||
error: "Error Trashing",
|
||||
@@ -137,13 +143,13 @@ const ContextMenu: React.FC<ContextMenuProps> = memo((props) => {
|
||||
};
|
||||
|
||||
const deleteItem = async () => {
|
||||
props.closeContext();
|
||||
if (!props.folderMode && props.file) {
|
||||
closeContext();
|
||||
if (!folderMode && file) {
|
||||
try {
|
||||
const result = await deleteFilePopup();
|
||||
if (!result) return;
|
||||
|
||||
await toast.promise(deleteFileAPI(props.file._id), {
|
||||
await toast.promise(deleteFileAPI(file._id), {
|
||||
pending: "Deleting...",
|
||||
success: "Deleted",
|
||||
error: "Error Deleting",
|
||||
@@ -154,12 +160,12 @@ const ContextMenu: React.FC<ContextMenuProps> = memo((props) => {
|
||||
} catch (e) {
|
||||
console.log("Error deleting file", e);
|
||||
}
|
||||
} else if (props.folderMode && props.folder) {
|
||||
} else if (folderMode && folder) {
|
||||
try {
|
||||
const result = await deleteFolderPopup();
|
||||
if (!result) return;
|
||||
|
||||
await toast.promise(deleteFolderAPI(props.folder._id), {
|
||||
await toast.promise(deleteFolderAPI(folder._id), {
|
||||
pending: "Deleting...",
|
||||
success: "Deleted",
|
||||
error: "Error Deleting",
|
||||
@@ -173,12 +179,12 @@ const ContextMenu: React.FC<ContextMenuProps> = memo((props) => {
|
||||
};
|
||||
|
||||
const restoreItem = async () => {
|
||||
props.closeContext();
|
||||
closeContext();
|
||||
const result = await restoreItemPopup();
|
||||
if (!result) return;
|
||||
if (!props.folderMode && props.file) {
|
||||
if (!folderMode && file) {
|
||||
try {
|
||||
await toast.promise(restoreFileAPI(props.file._id), {
|
||||
await toast.promise(restoreFileAPI(file._id), {
|
||||
pending: "Restoring...",
|
||||
success: "Restored",
|
||||
error: "Error Restoring",
|
||||
@@ -187,9 +193,9 @@ const ContextMenu: React.FC<ContextMenuProps> = memo((props) => {
|
||||
} catch (e) {
|
||||
console.log("Error restoring file", e);
|
||||
}
|
||||
} else if (props.folderMode && props.folder) {
|
||||
} else if (folderMode && folder) {
|
||||
try {
|
||||
await toast.promise(restoreFolderAPI(props.folder._id), {
|
||||
await toast.promise(restoreFolderAPI(folder._id), {
|
||||
pending: "Restoring...",
|
||||
success: "Restored",
|
||||
error: "Error Restoring",
|
||||
@@ -202,41 +208,41 @@ const ContextMenu: React.FC<ContextMenuProps> = memo((props) => {
|
||||
};
|
||||
|
||||
const openMoveItemModal = async () => {
|
||||
props.closeContext();
|
||||
if (!props.folderMode && props.file) {
|
||||
dispatch(setMoverID(props.file._id, props.file.metadata.parent, true));
|
||||
} else if (props.folderMode && props.folder) {
|
||||
dispatch(setMoverID(props.folder._id, props.folder.parent, false));
|
||||
closeContext();
|
||||
if (!folderMode && file) {
|
||||
dispatch(setMoverID(file._id, file.metadata.parent, true));
|
||||
} else if (folderMode && folder) {
|
||||
dispatch(setMoverID(folder._id, folder.parent, false));
|
||||
}
|
||||
};
|
||||
|
||||
const openShareItemModal = () => {
|
||||
props.closeContext();
|
||||
dispatch(setShareModal(props.file!));
|
||||
closeContext();
|
||||
dispatch(setShareModal(file!));
|
||||
};
|
||||
|
||||
const downloadItem = () => {
|
||||
props.closeContext();
|
||||
if (props.file) downloadFileAPI(props.file._id);
|
||||
closeContext();
|
||||
if (file) downloadFileAPI(file._id);
|
||||
};
|
||||
|
||||
const selectItemMultiSelect = () => {
|
||||
props.closeContext();
|
||||
if (props.folderMode && props.folder) {
|
||||
closeContext();
|
||||
if (folderMode && folder) {
|
||||
dispatch(
|
||||
setMultiSelectMode({
|
||||
type: "folder",
|
||||
id: props.folder._id,
|
||||
id: folder._id,
|
||||
file: null,
|
||||
folder: props.folder,
|
||||
folder: folder,
|
||||
})
|
||||
);
|
||||
} else if (!props.folderMode && props.file) {
|
||||
} else if (!folderMode && file) {
|
||||
dispatch(
|
||||
setMultiSelectMode({
|
||||
type: props.quickItemMode ? "quick-item" : "file",
|
||||
id: props.file._id,
|
||||
file: props.file,
|
||||
type: quickItemMode ? "quick-item" : "file",
|
||||
id: file._id,
|
||||
file: file,
|
||||
folder: null,
|
||||
})
|
||||
);
|
||||
@@ -245,105 +251,91 @@ const ContextMenu: React.FC<ContextMenuProps> = memo((props) => {
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={props.stopPropagation}
|
||||
onClick={stopPropagation}
|
||||
ref={wrapperRef}
|
||||
className={classNames(
|
||||
"fixed min-w-[215px] bg-white shadow-[0px_2px_4px_rgba(0,0,0,0.15),_inset_0px_1px_0px_#f5f7fa] rounded-[4px] mt-[-5px] z-50 ",
|
||||
props.contextSelected.selected ? "opacity-100" : "opacity-0"
|
||||
)}
|
||||
className="fixed min-w-[215px] bg-white shadow-lg rounded-md z-50"
|
||||
style={
|
||||
props.contextSelected.selected
|
||||
contextSelected.selected
|
||||
? {
|
||||
display: "block",
|
||||
left: `${props.contextSelected.X}px`,
|
||||
top: `${props.contextSelected.Y}px`,
|
||||
left: `${contextSelected.X}px`,
|
||||
top: `${contextSelected.Y}px`,
|
||||
}
|
||||
: { display: "none" }
|
||||
}
|
||||
>
|
||||
<ul className="p-0 list-none m-0 ">
|
||||
<li onClick={selectItemMultiSelect} className={liClassname}>
|
||||
<a className="flex">
|
||||
<span className={spanClassname}>
|
||||
<MultiSelectIcon className="w-[19px] h-[20px]" />
|
||||
</span>
|
||||
Multi-select
|
||||
</a>
|
||||
</li>
|
||||
<div>
|
||||
<div
|
||||
onClick={selectItemMultiSelect}
|
||||
className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-primary rounded-t-md"
|
||||
>
|
||||
<MultiSelectIcon className="w-5 h-5" />
|
||||
<p className="ml-2.5 text-sm">Multi-select</p>
|
||||
</div>
|
||||
{!isTrash && !isMedia && (
|
||||
<li onClick={renameItem} className={liClassname}>
|
||||
<a className="flex">
|
||||
<span className={spanClassname}>
|
||||
<RenameIcon />
|
||||
</span>
|
||||
Rename
|
||||
</a>
|
||||
</li>
|
||||
<div
|
||||
onClick={renameItem}
|
||||
className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-primary"
|
||||
>
|
||||
<RenameIcon className="w-5 h-5" />
|
||||
<p className="ml-2.5 text-sm">Rename</p>
|
||||
</div>
|
||||
)}
|
||||
{!folderMode && !isTrash && (
|
||||
<div
|
||||
onClick={openShareItemModal}
|
||||
className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-primary"
|
||||
>
|
||||
<ShareIcon className="w-5 h-5" />
|
||||
<p className="ml-2.5 text-sm">Share</p>
|
||||
</div>
|
||||
)}
|
||||
{!folderMode && !isTrash && (
|
||||
<div
|
||||
onClick={downloadItem}
|
||||
className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-primary"
|
||||
>
|
||||
<DownloadIcon className="w-5 h-5" />
|
||||
<p className="ml-2.5 text-sm">Download</p>
|
||||
</div>
|
||||
)}
|
||||
{!props.folderMode && !isTrash ? (
|
||||
<li onClick={openShareItemModal} className={liClassname}>
|
||||
<a className="flex" data-modal="share__modal">
|
||||
<span className="inline-flex mr-[18px]">
|
||||
<ShareIcon />
|
||||
</span>
|
||||
Share
|
||||
</a>
|
||||
</li>
|
||||
) : undefined}
|
||||
{!props.folderMode && !isTrash ? (
|
||||
<li onClick={downloadItem} className={liClassname}>
|
||||
<a className="flex">
|
||||
<span className={spanClassname}>
|
||||
<DownloadIcon />
|
||||
</span>
|
||||
Download
|
||||
</a>
|
||||
</li>
|
||||
) : undefined}
|
||||
{!isTrash && !isMedia && (
|
||||
<li onClick={openMoveItemModal} className={liClassname}>
|
||||
<a className="flex" data-modal="destination__modal">
|
||||
<span className={spanClassname}>
|
||||
<MoveIcon />
|
||||
</span>{" "}
|
||||
Move
|
||||
</a>
|
||||
</li>
|
||||
<div
|
||||
onClick={openMoveItemModal}
|
||||
className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-primary"
|
||||
>
|
||||
<MoveIcon className="w-5 h-5" />
|
||||
<p className="ml-2.5 text-sm">Move</p>
|
||||
</div>
|
||||
)}
|
||||
{!isTrash && (
|
||||
<li onClick={trashItem} className={liClassname}>
|
||||
<a className="flex">
|
||||
<span className={spanClassname}>
|
||||
<TrashIcon />
|
||||
</span>
|
||||
Trash
|
||||
</a>
|
||||
</li>
|
||||
)}
|
||||
{isTrash && (
|
||||
<li onClick={restoreItem} className={liClassname}>
|
||||
<a className="flex">
|
||||
<span className={spanClassname}>
|
||||
<RestoreIcon className="w-[19px] h-[20px]" />
|
||||
</span>
|
||||
Restore
|
||||
</a>
|
||||
</li>
|
||||
)}
|
||||
{isTrash && (
|
||||
<li
|
||||
onClick={deleteItem}
|
||||
className={classNames(liClassname, "hover:text-red-500")}
|
||||
<div
|
||||
onClick={trashItem}
|
||||
className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-primary rounded-b-md"
|
||||
>
|
||||
<a className="flex">
|
||||
<span className={spanClassname}>
|
||||
<TrashIcon />
|
||||
</span>
|
||||
Delete
|
||||
</a>
|
||||
</li>
|
||||
<TrashIcon className="w-5 h-5" />
|
||||
<p className="ml-2.5 text-sm">Trash</p>
|
||||
</div>
|
||||
)}
|
||||
</ul>
|
||||
{isTrash && (
|
||||
<div
|
||||
onClick={restoreItem}
|
||||
className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-primary"
|
||||
>
|
||||
<RestoreIcon className="w-5 h-5" />
|
||||
<p className="ml-2.5 text-sm">Restore</p>
|
||||
</div>
|
||||
)}
|
||||
{isTrash && (
|
||||
<div
|
||||
onClick={deleteItem}
|
||||
className="text-gray-primary flex flex-row p-4 hover:bg-white-hover hover:text-red-500 rounded-b-md"
|
||||
>
|
||||
<TrashIcon className="w-5 h-5" />
|
||||
<p className="ml-2.5 text-sm">Delete</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -34,10 +34,7 @@ const FileItem: React.FC<FileItemProps> = memo((props) => {
|
||||
(state) => state.selected.multiSelectMode
|
||||
);
|
||||
const listView = useAppSelector((state) => state.filter.listView);
|
||||
const { image, hasThumbnail, imageOnError } = useThumbnail(
|
||||
file.metadata.hasThumbnail,
|
||||
file.metadata.thumbnailID
|
||||
);
|
||||
const { data: thumbnail } = useThumbnail(file.metadata.thumbnailID);
|
||||
const dispatch = useAppDispatch();
|
||||
const lastSelected = useRef(0);
|
||||
const {
|
||||
@@ -201,17 +198,13 @@ const FileItem: React.FC<FileItemProps> = memo((props) => {
|
||||
className={classNames(
|
||||
"inline-flex items-center w-full bg-white relative",
|
||||
{
|
||||
"mt-2": !hasThumbnail,
|
||||
"mt-2": !thumbnail,
|
||||
}
|
||||
)}
|
||||
>
|
||||
{hasThumbnail ? (
|
||||
{!!thumbnail ? (
|
||||
<div className="w-full min-h-[88px] max-h-[88px] h-full flex">
|
||||
<img
|
||||
className="object-cover"
|
||||
src={image}
|
||||
onError={imageOnError}
|
||||
/>
|
||||
<img className="object-cover" src={thumbnail} />
|
||||
{file.metadata.isVideo && (
|
||||
<div className="w-full h-full absolute flex justify-center items-center text-white">
|
||||
<PlayButtonIcon className="w-[50px] h-[50px]" />
|
||||
@@ -234,7 +227,7 @@ const FileItem: React.FC<FileItemProps> = memo((props) => {
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
{!hasThumbnail && (
|
||||
{!thumbnail && (
|
||||
<div className="w-full h-full absolute flex justify-center items-center text-white mt-3">
|
||||
<p className="text-sm">{fileExtension}</p>
|
||||
</div>
|
||||
|
||||
@@ -10,27 +10,26 @@ import FileInfoPopup from "../FileInfoPopup";
|
||||
import SharePopup from "../SharePopup";
|
||||
|
||||
const MainSection = memo(() => {
|
||||
const selectedItem = useAppSelector((state) => state.selected.popupModal);
|
||||
const popupModalItem = useAppSelector(
|
||||
(state) => state.selected.popupModal.file
|
||||
);
|
||||
const shareModalItem = useAppSelector(
|
||||
(state) => state.selected.shareModal.file
|
||||
);
|
||||
|
||||
const isMediaSelected =
|
||||
popupModalItem?.metadata.isVideo || popupModalItem?.metadata.hasThumbnail;
|
||||
const isFileInfoSelected = !isMediaSelected && popupModalItem;
|
||||
|
||||
const { isMedia } = useUtils();
|
||||
return (
|
||||
<div>
|
||||
<div className="flex h-full">
|
||||
{/* {showPopup ? <PopupWindow /> : undefined} */}
|
||||
{selectedItem?.file &&
|
||||
(selectedItem.file.metadata.hasThumbnail ||
|
||||
selectedItem.file.metadata.isVideo) ? (
|
||||
<PhotoViewerPopup />
|
||||
) : undefined}
|
||||
{isMediaSelected && (
|
||||
<PhotoViewerPopup file={popupModalItem} key={popupModalItem._id} />
|
||||
)}
|
||||
|
||||
{selectedItem?.file &&
|
||||
!selectedItem.file.metadata.isVideo &&
|
||||
!selectedItem.file.metadata.hasThumbnail ? (
|
||||
<FileInfoPopup />
|
||||
) : undefined}
|
||||
{isFileInfoSelected && <FileInfoPopup />}
|
||||
|
||||
{shareModalItem && <SharePopup />}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
setPopupSelect,
|
||||
} from "../../reducers/selected";
|
||||
import mobilecheck from "../../utils/mobileCheck";
|
||||
import { setPopupFile } from "../../actions/popupFile";
|
||||
import classNames from "classnames";
|
||||
import { useContextMenu } from "../../hooks/contextMenu";
|
||||
import ContextMenu from "../ContextMenu";
|
||||
@@ -42,10 +41,7 @@ const MediaItem: React.FC<MediaItemType> = memo(({ file }) => {
|
||||
} = useContextMenu();
|
||||
const lastSelected = useRef(0);
|
||||
const dispatch = useAppDispatch();
|
||||
const { image, imageOnError } = useThumbnail(
|
||||
file.metadata.hasThumbnail,
|
||||
file.metadata.thumbnailID
|
||||
);
|
||||
const { data: thumbnail } = useThumbnail(file.metadata.thumbnailID);
|
||||
|
||||
// TODO: See if we can memoize this and remove any
|
||||
const mediaItemClick = (e: any) => {
|
||||
@@ -110,11 +106,7 @@ const MediaItem: React.FC<MediaItemType> = memo(({ file }) => {
|
||||
<PlayButtonIcon className="w-[50px] h-[50px]" />
|
||||
</div>
|
||||
)}
|
||||
<img
|
||||
className="object-cover h-full w-full"
|
||||
src={image}
|
||||
onError={imageOnError}
|
||||
/>
|
||||
<img className="object-cover h-full w-full" src={thumbnail} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import classNames from "classnames";
|
||||
import React, { memo, useEffect, useMemo, useState } from "react";
|
||||
import MediaItem from "../MediaItem";
|
||||
import { useFiles, useThumbnail } from "../../hooks/files";
|
||||
import { useFiles } from "../../hooks/files";
|
||||
import MultiSelectBar from "../MultiSelectBar";
|
||||
import { useInfiniteScroll } from "../../hooks/infiniteScroll";
|
||||
|
||||
@@ -44,6 +44,7 @@ const Medias = memo(() => {
|
||||
</React.Fragment>
|
||||
))}
|
||||
</div>
|
||||
{/* @ts-ignore */}
|
||||
<div ref={sentinelRef} className="h-1"></div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -12,20 +12,27 @@ import ContextMenu from "../ContextMenu";
|
||||
import { resetPopupSelect, setPopupSelect } from "../../reducers/selected";
|
||||
import CircleLeftIcon from "../../icons/CircleLeftIcon";
|
||||
import CircleRightIcon from "../../icons/CircleRightIcon";
|
||||
import { useFiles, useQuickFiles } from "../../hooks/files";
|
||||
import { useFiles, useFullThumbnail, useQuickFiles } from "../../hooks/files";
|
||||
import { FileInterface } from "../../types/file";
|
||||
import { InfiniteData } from "react-query";
|
||||
import { getFileColor, getFileExtension } from "../../utils/files";
|
||||
import Spinner from "../Spinner";
|
||||
import { toast } from "react-toastify";
|
||||
|
||||
const PhotoViewerPopup = memo(() => {
|
||||
const [image, setImage] = useState("");
|
||||
interface PhotoViewerPopupProps {
|
||||
file: FileInterface;
|
||||
}
|
||||
|
||||
const PhotoViewerPopup: React.FC<PhotoViewerPopupProps> = memo((props) => {
|
||||
const { file } = props;
|
||||
const [video, setVideo] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [isVideoLoading, setIsVideoLoading] = useState(false);
|
||||
const videoRef = useRef<HTMLVideoElement | null>(null);
|
||||
const file = useAppSelector((state) => state.selected.popupModal.file)!;
|
||||
const type = useAppSelector((state) => state.selected.popupModal.type)!;
|
||||
const { data: thumbnail, isLoading: isThumbnailLoading } = useFullThumbnail(
|
||||
file._id,
|
||||
file.metadata.isVideo
|
||||
);
|
||||
const finalLastPageLoaded = useRef(false);
|
||||
const loadingNextPage = useRef(false);
|
||||
const { data: quickFiles } = useQuickFiles(false);
|
||||
@@ -51,29 +58,16 @@ const PhotoViewerPopup = memo(() => {
|
||||
[file.filename]
|
||||
);
|
||||
|
||||
const getImage = useCallback(async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const imageData = await getFileFullThumbnailAPI(file._id);
|
||||
const imgFile = new Blob([imageData]);
|
||||
const imgUrl = URL.createObjectURL(imgFile);
|
||||
setImage(imgUrl);
|
||||
setLoading(false);
|
||||
} catch (e) {
|
||||
console.log("Error getting image", e);
|
||||
toast.error("Error getting image");
|
||||
}
|
||||
}, [file._id, getFileFullThumbnailAPI]);
|
||||
|
||||
const getVideo = useCallback(async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setIsVideoLoading(true);
|
||||
setVideo("");
|
||||
// TODO: Change this
|
||||
await getVideoTokenAPI();
|
||||
const videoURL = `http://localhost:5173/api/file-service/stream-video/${file._id}`;
|
||||
console.log("video url", videoURL);
|
||||
setVideo(videoURL);
|
||||
setLoading(false);
|
||||
setIsVideoLoading(false);
|
||||
} catch (e) {
|
||||
console.log("Error getting video", e);
|
||||
toast.error("Error getting video");
|
||||
@@ -225,14 +219,12 @@ const PhotoViewerPopup = memo(() => {
|
||||
useEffect(() => {
|
||||
if (file.metadata.isVideo) {
|
||||
getVideo();
|
||||
} else {
|
||||
getImage();
|
||||
}
|
||||
|
||||
return () => {
|
||||
cleanUpVideo();
|
||||
};
|
||||
}, [file._id, getVideo, getImage, cleanUpVideo]);
|
||||
}, [file.metadata.isVideo, getVideo, cleanUpVideo]);
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -296,14 +288,14 @@ const PhotoViewerPopup = memo(() => {
|
||||
/>
|
||||
</div>
|
||||
<div className="max-w-[80vw] max-h-[80vh] flex justify-center items-center">
|
||||
{loading && <Spinner />}
|
||||
{!file.metadata.isVideo && !loading && (
|
||||
{(isVideoLoading || isThumbnailLoading) && <Spinner />}
|
||||
{!file.metadata.isVideo && !isThumbnailLoading && (
|
||||
<img
|
||||
src={image}
|
||||
src={thumbnail}
|
||||
className="max-w-full max-h-full object-contain select-none"
|
||||
/>
|
||||
)}
|
||||
{file.metadata.isVideo && !loading && (
|
||||
{file.metadata.isVideo && !isVideoLoading && (
|
||||
<video
|
||||
src={video}
|
||||
ref={videoRef}
|
||||
|
||||
@@ -6,10 +6,7 @@ import classNames from "classnames";
|
||||
import { getFileColor, getFileExtension } from "../../utils/files";
|
||||
import { useThumbnail } from "../../hooks/files";
|
||||
import { useContextMenu } from "../../hooks/contextMenu";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import mobilecheck from "../../utils/mobileCheck";
|
||||
import { startSetSelectedItem } from "../../actions/selectedItem";
|
||||
import { setPopupFile } from "../../actions/popupFile";
|
||||
import { FileInterface } from "../../types/file";
|
||||
import { useAppDispatch, useAppSelector } from "../../hooks/store";
|
||||
import {
|
||||
@@ -37,11 +34,7 @@ const QuickAccessItem = memo((props: QuickAccessItemProps) => {
|
||||
const multiSelectMode = useAppSelector(
|
||||
(state) => state.selected.multiSelectMode
|
||||
);
|
||||
const { image, hasThumbnail, imageOnError } = useThumbnail(
|
||||
file.metadata.hasThumbnail,
|
||||
file.metadata.thumbnailID,
|
||||
true
|
||||
);
|
||||
const { data: thumbnail } = useThumbnail(file.metadata.thumbnailID, true);
|
||||
const dispatch = useAppDispatch();
|
||||
const lastSelected = useRef(0);
|
||||
|
||||
@@ -127,13 +120,13 @@ const QuickAccessItem = memo((props: QuickAccessItemProps) => {
|
||||
className={classNames(
|
||||
"inline-flex items-center w-full bg-white relative",
|
||||
{
|
||||
"mt-2": !hasThumbnail,
|
||||
"mt-2": !thumbnail,
|
||||
}
|
||||
)}
|
||||
>
|
||||
{hasThumbnail ? (
|
||||
{!!thumbnail ? (
|
||||
<div className="w-full min-h-[88px] max-h-[88px] h-full flex">
|
||||
<img className=" object-cover" src={image} onError={imageOnError} />
|
||||
<img className=" object-cover" src={thumbnail} />
|
||||
{file.metadata.isVideo && (
|
||||
<div className="w-full h-full absolute flex justify-center items-center text-white">
|
||||
<PlayButtonIcon className="w-[50px] h-[50px]" />
|
||||
@@ -156,7 +149,7 @@ const QuickAccessItem = memo((props: QuickAccessItemProps) => {
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
{!hasThumbnail && (
|
||||
{!thumbnail && (
|
||||
<div className="w-full h-full absolute flex justify-center items-center text-white mt-3">
|
||||
<p className="text-sm">{fileExtension}</p>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user