mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-04-21 06:59:17 -04:00
* Update rspc, prisma-client-rust, axum and tanstack-query - Deleted some unused examples and fully commented out frontend code - Implement many changes required due to the updates - Update most rust dependencies * Re-enable p2p * Fix server * Auto format * Fix injected script format - Update some github actions - Update pnpm lock file * Fix devtools showing up when app opens - Fix million complaining about Sparkles component * Fix sd-server * Fix and improve thumbnails rendering - Fix core always saying a new thumbnail was generated even for files that it skiped thumbnail generation - Rewrite FileThumb and improve related components * Ignore tmp files when running prettier * Improve FileThumb component performance - Rework useExplorerDraggable and useExplorerItemData hooks due to reduce unecessary re-renders * More fixes for thumb component - A couple of minor performance improvements to frontend code * auto format * Fix Thumbnail and QuickPreview * Fix logic for when to show 'fail to load original' error message in QuickPreview - Updated prisma-client-rust, libp2p, tauri, tauri-specta, rspc and hyper * Fix type checking - Format scripts * Add script prettier config * Fix serde missing feature - Use rust-libp2p spacedrive fork again - Update rspc * Autoformat + fix pnpm lock * Fix thumbnail first load again * Autoformat * autoformat * Fix rust-libp2p fork url again? * Remove usePathsInfiniteQuery hook * Update tauri 2.0.6
131 lines
3.6 KiB
TypeScript
131 lines
3.6 KiB
TypeScript
import { useLibraryMutation, useZodForm } from '@sd/client';
|
|
import { Dialog, useDialog, UseDialogProps } from '@sd/ui';
|
|
import i18n from '~/app/I18n';
|
|
import { Icon } from '~/components';
|
|
import { useLocale } from '~/hooks';
|
|
|
|
interface Props extends UseDialogProps {
|
|
indexedArgs?: {
|
|
locationId: number;
|
|
rescan?: () => void;
|
|
pathIds: number[];
|
|
};
|
|
ephemeralArgs?: {
|
|
paths: string[];
|
|
};
|
|
dirCount?: number;
|
|
fileCount?: number;
|
|
}
|
|
|
|
function getWording(dirCount: number, fileCount: number) {
|
|
let type = 'file';
|
|
let translatedType = i18n.t('file', { count: 1 });
|
|
let prefix = i18n.t('prefix_a');
|
|
|
|
if (dirCount == 1 && fileCount == 0) {
|
|
type = 'directory';
|
|
translatedType = i18n.t('directory', { count: dirCount });
|
|
prefix = i18n.t('prefix_a');
|
|
}
|
|
|
|
if (dirCount > 1 && fileCount == 0) {
|
|
type = 'directories';
|
|
translatedType = i18n.t('directory', { count: dirCount });
|
|
prefix = dirCount.toString();
|
|
}
|
|
|
|
if (fileCount > 1 && dirCount == 0) {
|
|
type = 'files';
|
|
translatedType = i18n.t('file', { count: fileCount });
|
|
prefix = fileCount.toString();
|
|
}
|
|
|
|
if (fileCount > 0 && dirCount > 0) {
|
|
type = 'items';
|
|
translatedType = i18n.t('item', { count: fileCount + dirCount });
|
|
prefix = (fileCount + dirCount).toString();
|
|
}
|
|
|
|
return { type, prefix, translatedType };
|
|
}
|
|
|
|
export default (props: Props) => {
|
|
const { t } = useLocale();
|
|
const deleteFile = useLibraryMutation('files.deleteFiles');
|
|
const deleteEphemeralFile = useLibraryMutation('ephemeralFiles.deleteFiles');
|
|
const moveToTrashFile = useLibraryMutation('files.moveToTrash');
|
|
const moveToTrashEphemeralFile = useLibraryMutation('ephemeralFiles.moveToTrash');
|
|
|
|
const form = useZodForm();
|
|
const { dirCount = 0, fileCount = 0, indexedArgs, ephemeralArgs } = props;
|
|
|
|
const { type, prefix, translatedType } = getWording(dirCount, fileCount);
|
|
|
|
const icon = type === 'file' || type === 'files' ? 'Document' : 'Folder';
|
|
|
|
const description = t('delete_warning', { type: translatedType });
|
|
|
|
return (
|
|
<Dialog
|
|
form={form}
|
|
onSubmit={form.handleSubmit(async () => {
|
|
if (indexedArgs != undefined) {
|
|
const { locationId, rescan, pathIds } = indexedArgs;
|
|
await deleteFile.mutateAsync({
|
|
location_id: locationId,
|
|
file_path_ids: pathIds
|
|
});
|
|
|
|
rescan?.();
|
|
}
|
|
|
|
if (ephemeralArgs != undefined) {
|
|
const { paths } = ephemeralArgs;
|
|
await deleteEphemeralFile.mutateAsync(paths);
|
|
}
|
|
})}
|
|
onSubmitSecond={form.handleSubmit(async () => {
|
|
if (indexedArgs != undefined) {
|
|
console.log(
|
|
'DEBUG: DeleteDialog.tsx: onSubmitSecond (Move to Trash) -> Indexed Files'
|
|
);
|
|
const { locationId, rescan, pathIds } = indexedArgs;
|
|
await moveToTrashFile.mutateAsync({
|
|
location_id: locationId,
|
|
file_path_ids: pathIds
|
|
});
|
|
|
|
rescan?.();
|
|
}
|
|
|
|
if (ephemeralArgs != undefined) {
|
|
console.log(
|
|
'DEBUG: DeleteDialog.tsx: onSubmitSecond (Move to Trash) -> Ephemeral Files'
|
|
);
|
|
const { paths } = ephemeralArgs;
|
|
await moveToTrashEphemeralFile.mutateAsync(paths);
|
|
}
|
|
})}
|
|
icon={<Icon theme="light" name={icon} size={28} />}
|
|
dialog={useDialog(props)}
|
|
title={t('delete_dialog_title', { prefix, type: translatedType })}
|
|
description={description}
|
|
loading={deleteFile.isPending}
|
|
ctaLabel={t('delete_forever')}
|
|
ctaSecondLabel={t('move_to_trash')}
|
|
closeLabel={t('close')}
|
|
ctaDanger
|
|
className="w-[200px]"
|
|
>
|
|
{/* <Tooltip label={t('coming_soon')}>
|
|
<div className="flex items-center pt-2 opacity-50">
|
|
<CheckBox disabled className="!mt-0" />
|
|
<p className="text-sm text-ink-dull">
|
|
Delete all matching {type.endsWith('s') ? type : type + 's'}
|
|
</p>
|
|
</div>
|
|
</Tooltip> */}
|
|
</Dialog>
|
|
);
|
|
};
|