code cleanup and fixes

This commit is contained in:
subnub
2024-07-26 07:10:02 -04:00
parent 838de4bedd
commit 19abbb0387
12 changed files with 224 additions and 265 deletions
+6 -1
View File
@@ -92,10 +92,15 @@ export const getFileThumbnailAPI = async (thumbnailID: string) => {
export const getFileFullThumbnailAPI = async (fileID: string) => {
const url = `http://localhost:5173/api/file-service/full-thumbnail/${fileID}`;
const response = await axios.get(url, {
responseType: "arraybuffer",
});
return response.data;
const imgFile = new Blob([response.data]);
const imgUrl = URL.createObjectURL(imgFile);
return imgUrl;
};
export const getVideoTokenAPI = async () => {
+5 -5
View File
@@ -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>
+121 -129
View File
@@ -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>
);
});
+5 -12
View File
@@ -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>
+11 -12
View File
@@ -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 />}
+2 -10
View File
@@ -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>
);
});
+2 -1
View File
@@ -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>
);
+20 -28
View File
@@ -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}
+5 -12
View File
@@ -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>
+1 -1
View File
@@ -25,7 +25,7 @@ export const useContextMenu = () => {
}
if (Y + contextHeight > windowHeight) {
Y = windowHeight - contextHeight;
Y = windowHeight - contextHeight - 60;
}
setContextData({
+39 -53
View File
@@ -8,6 +8,7 @@ import {
} from "react-query";
import { useParams } from "react-router-dom";
import {
getFileFullThumbnailAPI,
getFileThumbnailAPI,
getFilesListAPI,
getQuickFilesListAPI,
@@ -127,65 +128,50 @@ export const useQuickFilesClient = () => {
return { ...quickFilesReactClientQuery, invalidateQuickFilesCache };
};
interface thumbnailState {
hasThumbnail: boolean;
image: undefined | string;
}
export const useThumbnail = (
hasThumbnail: boolean,
thumbnailID?: string,
thumbnailID: string | undefined,
isQuickFile?: boolean
) => {
const requestedThumbnail = useRef(false);
const [state, setState] = useState<thumbnailState>({
hasThumbnail: false,
image: undefined,
});
const { isHome, isMedia } = useUtils();
const listView = useAppSelector((state) => state.filter.listView);
const imageOnError = useCallback(() => {
setState({
hasThumbnail: false,
image: undefined,
});
}, []);
const getThumbnail = useCallback(async () => {
try {
if (!thumbnailID || requestedThumbnail.current) return;
if (isQuickFile && !isHome) return;
if (!isQuickFile && listView && !isMedia) return;
requestedThumbnail.current = true;
const thumbnailData = await getFileThumbnailAPI(thumbnailID);
setState({
hasThumbnail: true,
image: thumbnailData,
});
} catch (e) {
console.log("error getting thumbnail data", e);
imageOnError();
const { isMedia } = useUtils();
const disabled = listView && !isMedia && !isQuickFile;
const thumbnailQuery = useQuery(
["thumbnail", { thumbnailID }],
() => {
if (thumbnailID) {
return getFileThumbnailAPI(thumbnailID);
} else {
return undefined;
}
},
{
enabled: !!thumbnailID && !disabled,
refetchOnWindowFocus: false,
refetchOnMount: false,
keepPreviousData: true,
}
}, [
thumbnailID,
getFileThumbnailAPI,
imageOnError,
listView,
isHome,
isQuickFile,
]);
);
return thumbnailQuery;
};
useEffect(() => {
if (!hasThumbnail || !thumbnailID) return;
getThumbnail();
return () => {
requestedThumbnail.current = false;
};
}, [hasThumbnail, getThumbnail, thumbnailID]);
return { ...state, imageOnError };
export const useFullThumbnail = (fileID: string, isVideo: boolean) => {
console.log("usefullthumbnail", fileID, isVideo);
const thumbnailQuery = useQuery(
["full-thumbnail", { fileID }],
() => {
if (!isVideo) {
return getFileFullThumbnailAPI(fileID);
} else {
return undefined;
}
},
{
enabled: !isVideo,
refetchOnWindowFocus: false,
refetchOnMount: false,
}
);
return thumbnailQuery;
};
export const useSearchSuggestions = (searchText: string) => {