mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-04-21 23:18:06 -04:00
* you know, you could just work on first try * fix extension * configure plugin and fix few translation issues * more * more keys * and more * more keys and sort * commit msg * we like keys here * end my suffering * jk i just love keys * key fix * add turkish * add german * Entendido * Demnächst * Mettre une étoile sur GitHub * 成功 * pnpm-lock * vite plugin * remove i18next backends --------- Co-authored-by: Brendan Allan <brendonovich@outlook.com>
113 lines
2.8 KiB
TypeScript
113 lines
2.8 KiB
TypeScript
import { ArrowBendUpRight, TagSimple } from '@phosphor-icons/react';
|
|
import { useMemo } from 'react';
|
|
import { ExplorerItem, ObjectKind, useLibraryMutation, type ObjectKindEnum } from '@sd/client';
|
|
import { ContextMenu, toast } from '@sd/ui';
|
|
import { Menu } from '~/components/Menu';
|
|
import { useLocale } from '~/hooks';
|
|
import { isNonEmpty } from '~/util';
|
|
|
|
import AssignTagMenuItems from '../AssignTagMenuItems';
|
|
import { ConditionalItem } from '../ConditionalItem';
|
|
import { useContextMenuContext } from '../context';
|
|
|
|
export const RemoveFromRecents = new ConditionalItem({
|
|
useCondition: () => {
|
|
const { selectedObjects } = useContextMenuContext();
|
|
|
|
if (!isNonEmpty(selectedObjects)) return null;
|
|
|
|
return { selectedObjects };
|
|
},
|
|
|
|
Component: ({ selectedObjects }) => {
|
|
const removeFromRecents = useLibraryMutation('files.removeAccessTime');
|
|
|
|
const { t } = useLocale();
|
|
|
|
return (
|
|
<ContextMenu.Item
|
|
label={t('remove_from_recents')}
|
|
onClick={async () => {
|
|
try {
|
|
await removeFromRecents.mutateAsync(
|
|
selectedObjects.map((object) => object.id)
|
|
);
|
|
} catch (error) {
|
|
toast.error({
|
|
title: t('failed_to_remove_file_from_recents'),
|
|
body: `Error: ${error}.`
|
|
});
|
|
}
|
|
}}
|
|
/>
|
|
);
|
|
}
|
|
});
|
|
|
|
export const AssignTag = new ConditionalItem({
|
|
useCondition: () => {
|
|
const { selectedItems } = useContextMenuContext();
|
|
|
|
const items = selectedItems
|
|
.map((item) => {
|
|
if (item.type === 'Object' || item.type === 'Path') return item;
|
|
})
|
|
.filter(
|
|
(item): item is Extract<ExplorerItem, { type: 'Object' | 'Path' }> =>
|
|
item !== undefined
|
|
);
|
|
|
|
if (!isNonEmpty(items)) return null;
|
|
|
|
return { items };
|
|
},
|
|
Component: ({ items }) => {
|
|
const { t } = useLocale();
|
|
return (
|
|
<Menu.SubMenu label={t('assign_tag')} icon={TagSimple}>
|
|
<AssignTagMenuItems items={items} />
|
|
</Menu.SubMenu>
|
|
);
|
|
}
|
|
});
|
|
|
|
const ObjectConversions: Record<number, string[]> = {
|
|
[ObjectKind.Image]: ['PNG', 'WebP', 'Gif'],
|
|
[ObjectKind.Video]: ['MP4', 'MOV', 'AVI']
|
|
};
|
|
|
|
const ConvertableKinds = [ObjectKind.Image, ObjectKind.Video];
|
|
|
|
export const ConvertObject = new ConditionalItem({
|
|
useCondition: () => {
|
|
const { selectedObjects } = useContextMenuContext();
|
|
|
|
const kinds = useMemo(() => {
|
|
const set = new Set<ObjectKindEnum>();
|
|
|
|
for (const o of selectedObjects) {
|
|
if (o.kind === null || !ConvertableKinds.includes(o.kind)) break;
|
|
set.add(o.kind);
|
|
}
|
|
|
|
return [...set];
|
|
}, [selectedObjects]);
|
|
|
|
if (!isNonEmpty(kinds) || kinds.length > 1) return null;
|
|
|
|
const [kind] = kinds;
|
|
|
|
return { kind };
|
|
},
|
|
Component: ({ kind }) => {
|
|
const { t } = useLocale();
|
|
return (
|
|
<Menu.SubMenu label={t('convert_to')} icon={ArrowBendUpRight}>
|
|
{ObjectConversions[kind]?.map((ext) => (
|
|
<Menu.Item key={ext} label={ext} disabled />
|
|
))}
|
|
</Menu.SubMenu>
|
|
);
|
|
}
|
|
});
|