hotfix for identifier orphan query

This commit is contained in:
Jamie Pine 2022-09-07 14:05:33 -07:00
parent 98f900b99e
commit 6b1e8c3088
No known key found for this signature in database
GPG key ID: D5AC85A0C2F646E9
5 changed files with 235 additions and 209 deletions

View file

@ -90,7 +90,7 @@ impl StatefulJob for FileIdentifierJob {
let total_count = library
.db
.file_path()
.count(orphan_path_filters(location_id))
.count(orphan_path_filters(location_id, None))
.exec()
.await? as usize;
@ -106,7 +106,7 @@ impl StatefulJob for FileIdentifierJob {
let first_path_id = library
.db
.file_path()
.find_first(orphan_path_filters(location_id))
.find_first(orphan_path_filters(location_id, None))
.exec()
.await?
.map(|d| d.id)
@ -310,12 +310,17 @@ impl StatefulJob for FileIdentifierJob {
}
}
fn orphan_path_filters(location_id: i32) -> Vec<file_path::WhereParam> {
vec![
fn orphan_path_filters(location_id: i32, file_path_id: Option<i32>) -> Vec<file_path::WhereParam> {
let mut params = vec![
file_path::file_id::equals(None),
file_path::is_dir::equals(false),
file_path::location_id::equals(location_id),
]
];
// this is a workaround for the cursor not working properly
if let Some(file_path_id) = file_path_id {
params.push(file_path::id::gte(file_path_id))
}
params
}
#[derive(Deserialize, Serialize, Debug)]
@ -334,9 +339,9 @@ async fn get_orphan_file_paths(
);
ctx.db
.file_path()
.find_many(orphan_path_filters(location_id))
.find_many(orphan_path_filters(location_id, Some(cursor.file_path_id)))
.order_by(file_path::id::order(Direction::Asc))
.cursor(cursor.into())
// .cursor(cursor.into())
.take(CHUNK_SIZE as i64)
.skip(1)
.exec()

View file

@ -1,122 +1,125 @@
import { explorerStore, useLibraryMutation, useLibraryQuery } from '@sd/client';
import { ContextMenu as CM } from '@sd/ui';
import {
ArrowBendUpRight,
FilePlus,
FileX,
LockSimple,
Package,
Plus,
Share,
TagSimple,
Trash,
TrashSimple,
ArrowBendUpRight,
FilePlus,
FileX,
LockSimple,
Package,
Plus,
Share,
TagSimple,
Trash,
TrashSimple
} from 'phosphor-react';
import React from 'react';
import { useSnapshot } from 'valtio';
import { NewContextMenu as CM } from "@sd/ui"
const AssignTagMenuItems = (props: { objectId: number }) => {
const tags = useLibraryQuery(['tags.getAll'], { suspense: true });
const tagsForFile = useLibraryQuery(['tags.getForFile', props.objectId], { suspense: true });
const tags = useLibraryQuery(['tags.getAll'], { suspense: true });
const tagsForFile = useLibraryQuery(['tags.getForFile', props.objectId], { suspense: true });
const { mutate: assignTag } = useLibraryMutation('tags.assign');
const { mutate: assignTag } = useLibraryMutation('tags.assign');
return (
<>
{tags.data?.map(tag => {
const active = !!tagsForFile.data?.find(t => t.id === tag.id)
return (
<>
{tags.data?.map((tag) => {
const active = !!tagsForFile.data?.find((t) => t.id === tag.id);
return <CM.Item
key={tag.id}
onClick={(e) => {
e.preventDefault();
if (props.objectId === null) return;
return (
<CM.Item
key={tag.id}
onClick={(e) => {
e.preventDefault();
if (props.objectId === null) return;
assignTag({
tag_id: tag.id,
file_id: props.objectId,
unassign: active
});
}}
>
<div
className="block w-[15px] h-[15px] mr-0.5 border rounded-full"
style={{
backgroundColor: active
? tag.color || '#efefef'
: 'transparent' || '#efefef',
borderColor: tag.color || '#efefef'
}}
/>
<p>{tag.name}</p>
</CM.Item>
})}
</>
);
}
assignTag({
tag_id: tag.id,
file_id: props.objectId,
unassign: active
});
}}
>
<div
className="block w-[15px] h-[15px] mr-0.5 border rounded-full"
style={{
backgroundColor: active ? tag.color || '#efefef' : 'transparent' || '#efefef',
borderColor: tag.color || '#efefef'
}}
/>
<p>{tag.name}</p>
</CM.Item>
);
})}
</>
);
};
interface Props {
children: React.ReactNode;
children: React.ReactNode;
}
export default function ExplorerContextMenu(props: Props) {
const store = useSnapshot(explorerStore);
const store = useSnapshot(explorerStore);
return (
<div className="relative" >
<CM.ContextMenu
trigger={props.children}
>
<CM.Item label="Open" />
<CM.Item label="Open with..." />
return (
<div className="relative">
<CM.ContextMenu trigger={props.children}>
<CM.Item label="Open" />
<CM.Item label="Open with..." />
<CM.Separator />
<CM.Separator />
<CM.Item label="Quick view" />
<CM.Item label="Open in Finder" />
<CM.Item label="Quick view" />
<CM.Item label="Open in Finder" />
<CM.Separator />
<CM.Separator />
<CM.Item label="Rename" />
<CM.Item label="Duplicate" />
<CM.Item label="Rename" />
<CM.Item label="Duplicate" />
<CM.Separator />
<CM.Separator />
<CM.Item label="Share" icon={Share} onClick={e => {
e.preventDefault();
<CM.Item
label="Share"
icon={Share}
onClick={(e) => {
e.preventDefault();
navigator.share?.({
title: 'Spacedrive',
text: 'Check out this cool app',
url: 'https://spacedrive.com'
});
}} />
navigator.share?.({
title: 'Spacedrive',
text: 'Check out this cool app',
url: 'https://spacedrive.com'
});
}}
/>
<CM.Separator />
<CM.Separator />
{store.contextMenuObjectId && <CM.SubMenu label="Assign tag" icon={TagSimple}>
<AssignTagMenuItems objectId={store.contextMenuObjectId} />
</CM.SubMenu>}
<CM.SubMenu label="More actions..." icon={Plus}>
<CM.SubMenu label="Move to library" icon={FilePlus}>
{/* {libraries.map(library => <CM.Item key={library.id} label={library.config.name} />)} */}
<CM.Item label="Remove from library" icon={FileX} />
</CM.SubMenu>
<CM.Separator />
<CM.Item label="Encrypt" icon={LockSimple} />
<CM.Item label="Compress" icon={Package} />
<CM.SubMenu label="Convert to" icon={ArrowBendUpRight}>
<CM.Item label="PNG" />
<CM.Item label="WebP" />
</CM.SubMenu>
<CM.Item label="Secure delete" icon={TrashSimple} />
</CM.SubMenu>
{store.contextMenuObjectId && (
<CM.SubMenu label="Assign tag" icon={TagSimple}>
<AssignTagMenuItems objectId={store.contextMenuObjectId} />
</CM.SubMenu>
)}
<CM.SubMenu label="More actions..." icon={Plus}>
<CM.SubMenu label="Move to library" icon={FilePlus}>
{/* {libraries.map(library => <CM.Item key={library.id} label={library.config.name} />)} */}
<CM.Item label="Remove from library" icon={FileX} />
</CM.SubMenu>
<CM.Separator />
<CM.Item label="Encrypt" icon={LockSimple} />
<CM.Item label="Compress" icon={Package} />
<CM.SubMenu label="Convert to" icon={ArrowBendUpRight}>
<CM.Item label="PNG" />
<CM.Item label="WebP" />
</CM.SubMenu>
<CM.Item label="Secure delete" icon={TrashSimple} />
</CM.SubMenu>
<CM.Separator />
<CM.Separator />
<CM.Item icon={Trash} label="Delete" variant="danger" />
</CM.ContextMenu>
</div >
);
<CM.Item icon={Trash} label="Delete" variant="danger" />
</CM.ContextMenu>
</div>
);
}

View file

@ -0,0 +1,126 @@
import * as RadixCM from '@radix-ui/react-context-menu';
import { VariantProps, cva } from 'class-variance-authority';
import clsx from 'clsx';
import { CaretRight, Icon } from 'phosphor-react';
import { HTMLAttributes, PropsWithChildren, Suspense } from 'react';
import React from 'react';
interface Props extends RadixCM.MenuContentProps {
trigger: React.ReactNode;
}
const MENU_CLASSES = `
flex flex-col
min-w-[11rem] p-2 space-y-1
text-left text-sm dark:text-gray-100 text-gray-800
bg-gray-50 border-gray-200 dark:bg-gray-950
shadow-md shadow-gray-300 dark:shadow-gray-750
select-none cursor-default rounded-lg
`;
export const ContextMenu = ({
trigger,
children,
className,
...props
}: PropsWithChildren<Props>) => {
return (
<RadixCM.Root>
<RadixCM.Trigger>{trigger}</RadixCM.Trigger>
<RadixCM.Portal>
<RadixCM.Content {...props} className={clsx(MENU_CLASSES, className)}>
{children}
</RadixCM.Content>
</RadixCM.Portal>
</RadixCM.Root>
);
};
export const Separator = () => (
<RadixCM.Separator className="mx-2 border-0 border-b pointer-events-none border-b-gray-300 dark:border-b-gray-600" />
);
export const SubMenu = ({
label,
icon,
className,
...props
}: RadixCM.MenuSubContentProps & ItemProps) => {
return (
<RadixCM.Sub>
<RadixCM.SubTrigger className="[&[data-state='open']_div]:bg-primary focus:outline-none">
<DivItem rightArrow {...{ label, icon }} />
</RadixCM.SubTrigger>
<RadixCM.Portal>
<Suspense fallback={null}>
<RadixCM.SubContent {...props} className={clsx(MENU_CLASSES, '-mt-2', className)} />
</Suspense>
</RadixCM.Portal>
</RadixCM.Sub>
);
};
const ITEM_CLASSES = `
flex flex-row items-center justify-start flex-1
px-2 py-1 space-x-2
cursor-default rounded
focus:outline-none
`;
const itemStyles = cva([ITEM_CLASSES], {
variants: {
variant: {
default: 'hover:bg-primary focus:bg-primary',
danger: `
text-red-600 dark:text-red-400
hover:text-white focus:text-white
hover:bg-red-500 focus:bg-red-500
`
}
},
defaultVariants: {
variant: 'default'
}
});
interface ItemProps extends VariantProps<typeof itemStyles> {
icon?: Icon;
rightArrow?: boolean;
label?: string;
}
export const Item = ({
icon,
label,
rightArrow,
children,
variant,
...props
}: ItemProps & RadixCM.MenuItemProps) => (
<RadixCM.Item {...props} className={itemStyles({ variant })}>
{children ? children : <ItemInternals {...{ icon, label, rightArrow }} />}
</RadixCM.Item>
);
const DivItem = ({ variant, ...props }: ItemProps) => (
<div className={itemStyles({ variant })}>
<ItemInternals {...props} />
</div>
);
const ItemInternals = ({ icon, label, rightArrow }: ItemProps) => {
const ItemIcon = icon;
return (
<>
{ItemIcon && <ItemIcon size={18} />}
{label && <p>{label}</p>}
{rightArrow && (
<>
<div className="flex-1" />
<CaretRight weight="fill" size={12} alt="" />
</>
)}
</>
);
};

View file

@ -1,107 +0,0 @@
import * as RadixCM from "@radix-ui/react-context-menu"
import clsx from "clsx";
import { CaretRight, Icon } from "phosphor-react";
import { HTMLAttributes, PropsWithChildren, Suspense, } from "react"
import React from 'react'
import { cva, VariantProps } from "class-variance-authority";
interface Props extends RadixCM.MenuContentProps {
trigger: React.ReactNode,
}
const MENU_CLASSES = `
flex flex-col
min-w-[11rem] p-2 space-y-1
text-left text-sm dark:text-gray-100 text-gray-800
bg-gray-50 border-gray-200 dark:bg-gray-950
shadow-md shadow-gray-300 dark:shadow-gray-750
select-none cursor-default rounded-lg
`;
export const ContextMenu = ({ trigger, children, className, ...props }: PropsWithChildren<Props>) => {
return (
<RadixCM.Root>
<RadixCM.Trigger>{trigger}</RadixCM.Trigger>
<RadixCM.Portal>
<RadixCM.Content {...props} className={clsx(MENU_CLASSES, className)}>
{children}
</RadixCM.Content>
</RadixCM.Portal>
</RadixCM.Root>
)
}
export const Separator = () =>
<RadixCM.Separator className="mx-2 border-0 border-b pointer-events-none border-b-gray-300 dark:border-b-gray-600" />
export const SubMenu = ({ label, icon, className, ...props }: RadixCM.MenuSubContentProps & ItemProps) => {
return (
<RadixCM.Sub>
<RadixCM.SubTrigger className="[&[data-state='open']_div]:bg-primary focus:outline-none">
<DivItem rightArrow {...{ label, icon }} />
</RadixCM.SubTrigger>
<RadixCM.Portal>
<Suspense fallback={null}>
<RadixCM.SubContent {...props} className={clsx(MENU_CLASSES, "-mt-2", className)} />
</Suspense>
</RadixCM.Portal>
</RadixCM.Sub>
)
}
const ITEM_CLASSES = `
flex flex-row items-center justify-start flex-1
px-2 py-1 space-x-2
cursor-default rounded
focus:outline-none
`;
const itemStyles = cva([ITEM_CLASSES], {
variants: {
variant: {
default: 'hover:bg-primary focus:bg-primary',
danger: `
text-red-600 dark:text-red-400
hover:text-white focus:text-white
hover:bg-red-500 focus:bg-red-500
`
}
},
defaultVariants: {
variant: 'default'
}
})
interface ItemProps extends VariantProps<typeof itemStyles> {
icon?: Icon,
rightArrow?: boolean,
label?: string,
}
export const Item = ({ icon, label, rightArrow, children, variant, ...props }: ItemProps & RadixCM.MenuItemProps) => (
<RadixCM.Item {...props} className={itemStyles({ variant })}>
{children ? children : <ItemInternals {...{icon, label, rightArrow}} />}
</RadixCM.Item>
)
const DivItem = ({ variant, ...props }: ItemProps) => (
<div className={itemStyles({ variant })}>
<ItemInternals {...props} />
</div>
)
const ItemInternals = ({ icon, label, rightArrow }: ItemProps) => {
const ItemIcon = icon;
return (
<>
{ItemIcon && <ItemIcon size={18} />}
{label && <p>{label}</p>}
{rightArrow && <>
<div className="flex-1"/>
<CaretRight weight="fill" size={12} alt=""/>
</>}
</>
)
}

View file

@ -1,5 +1,4 @@
export * from './Button';
export * from './Dropdown';
export * from './ContextMenu';
export * as NewContextMenu from "./ContextMenu/index"
export * as ContextMenu from './ContextMenu';
export * from './Input';