Rework #6
					 4 changed files with 54 additions and 48 deletions
				
			
		| 
						 | 
				
			
			@ -4,8 +4,17 @@ export function makeApiUrl(pathnameAndQueryparam: string) {
 | 
			
		|||
    return new URL(pathnameAndQueryparam, BASE_API_URL).toString();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function fetcher(url: string) {
 | 
			
		||||
export class ApiError extends Error {
 | 
			
		||||
    constructor(public readonly status: number, message: string) {
 | 
			
		||||
        super(message);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function fetcher(url: string, init?: RequestInit) {
 | 
			
		||||
    const u = makeApiUrl(url);
 | 
			
		||||
    const res = await fetch(u);
 | 
			
		||||
    const res = await fetch(u, init);
 | 
			
		||||
    if (!res.ok) {
 | 
			
		||||
        throw new ApiError(res.status, await res.text());
 | 
			
		||||
    }
 | 
			
		||||
    return res.json();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ export function useDifferenceDoc() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
export async function commit(path: string, type: string) {
 | 
			
		||||
    const res = await fetch("/api/diff/commit", {
 | 
			
		||||
    const data = await fetcher("/api/diff/commit", {
 | 
			
		||||
        method: "POST",
 | 
			
		||||
        body: JSON.stringify([{ path, type }]),
 | 
			
		||||
        headers: {
 | 
			
		||||
| 
						 | 
				
			
			@ -22,11 +22,11 @@ export async function commit(path: string, type: string) {
 | 
			
		|||
        },
 | 
			
		||||
    });
 | 
			
		||||
    mutate("/api/diff/list");
 | 
			
		||||
    return res.ok;
 | 
			
		||||
    return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function commitAll(type: string) {
 | 
			
		||||
    const res = await fetch("/api/diff/commitall", {
 | 
			
		||||
    const data = await fetcher("/api/diff/commitall", {
 | 
			
		||||
        method: "POST",
 | 
			
		||||
        body: JSON.stringify({ type }),
 | 
			
		||||
        headers: {
 | 
			
		||||
| 
						 | 
				
			
			@ -34,5 +34,5 @@ export async function commitAll(type: string) {
 | 
			
		|||
        },
 | 
			
		||||
    });
 | 
			
		||||
    mutate("/api/diff/list");
 | 
			
		||||
    return res.ok;
 | 
			
		||||
    return data;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +26,7 @@ export function DifferencePage() {
 | 
			
		|||
            <Card>
 | 
			
		||||
                <CardHeader className="relative">
 | 
			
		||||
                    <Button className="absolute right-2 top-8" variant="ghost"
 | 
			
		||||
                        onClick={() => commitAll("comic")}
 | 
			
		||||
                        onClick={() => {commitAll("comic")}}
 | 
			
		||||
                    >Commit All</Button>
 | 
			
		||||
                    <CardTitle className="text-2xl">Difference</CardTitle>
 | 
			
		||||
                    <CardDescription>Scanned Files List</CardDescription>
 | 
			
		||||
| 
						 | 
				
			
			@ -45,8 +45,7 @@ export function DifferencePage() {
 | 
			
		|||
                                        <Button
 | 
			
		||||
                                            className="flex-none ml-2"
 | 
			
		||||
                                            variant="outline"
 | 
			
		||||
                                            onClick={() => commit(y.path, y.type)}
 | 
			
		||||
                                        >
 | 
			
		||||
                                            onClick={() => {commit(y.path, y.type)}}>
 | 
			
		||||
                                            Commit
 | 
			
		||||
                                        </Button>
 | 
			
		||||
                                    </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ export default function Gallery() {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }, [virtualItems, setSize, size, data]);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (isLoading) {
 | 
			
		||||
        return <div className="p-4">Loading...</div>
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -66,47 +66,45 @@ export default function Gallery() {
 | 
			
		|||
        {(word || tags) &&
 | 
			
		||||
            <div className="bg-primary rounded-full p-1 sticky top-0 shadow-md z-20">
 | 
			
		||||
                {word && <span className="text-primary-foreground ml-4">Search: {word}</span>}
 | 
			
		||||
                {tags && <span className="text-primary-foreground ml-4">Tags: <ul className="inline-flex">{tags.split(",").map(x => <TagBadge tagname={x} key={x} />)}</ul></span>}
 | 
			
		||||
                {tags && <span className="text-primary-foreground ml-4">Tags: <ul className="inline-flex">{
 | 
			
		||||
                    tags.split(",").map(x => <TagBadge tagname={x} key={x} />)}
 | 
			
		||||
                </ul></span>}
 | 
			
		||||
            </div>
 | 
			
		||||
        }
 | 
			
		||||
        {
 | 
			
		||||
            data?.length === 0 && <div className="p-4 text-3xl">No results</div>
 | 
			
		||||
        }
 | 
			
		||||
        {data?.length === 0 && <div className="p-4 text-3xl">No results</div>}
 | 
			
		||||
        <div className="w-full relative"
 | 
			
		||||
            style={{ height: virtualizer.getTotalSize() }}
 | 
			
		||||
        >
 | 
			
		||||
        {
 | 
			
		||||
            // TODO: date based grouping
 | 
			
		||||
            virtualItems.map((item) => {
 | 
			
		||||
                const isLoaderRow = item.index === size - 1 && isLoadingMore;
 | 
			
		||||
                if (isLoaderRow) {
 | 
			
		||||
                    return <div key={item.index} className="w-full flex justify-center top-0 left-0 absolute" 
 | 
			
		||||
                    style={{
 | 
			
		||||
                        height: `${item.size}px`,
 | 
			
		||||
                        transform: `translateY(${item.start}px)`
 | 
			
		||||
                    }}>
 | 
			
		||||
                        <Spinner />
 | 
			
		||||
                    </div>;
 | 
			
		||||
                }
 | 
			
		||||
                const docs = data[item.index];
 | 
			
		||||
                if (!docs) return null;
 | 
			
		||||
                return <div className="w-full grid gap-2 content-start top-0 left-0 absolute mb-2" key={item.index}
 | 
			
		||||
                style={{
 | 
			
		||||
                    height: `${item.size}px`,
 | 
			
		||||
                    transform: `translateY(${item.start}px)`
 | 
			
		||||
                }}>
 | 
			
		||||
                    {docs.startCursor && <div> 
 | 
			
		||||
                        <h3 className="text-3xl">Start with {docs.startCursor}</h3>
 | 
			
		||||
                        <Separator/>
 | 
			
		||||
                    </div>}
 | 
			
		||||
                    {docs?.data?.map((x) => {
 | 
			
		||||
                        return (
 | 
			
		||||
                            <GalleryCard doc={x} key={x.id} />
 | 
			
		||||
                        );
 | 
			
		||||
                    })}
 | 
			
		||||
                </div>
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
            style={{ height: virtualizer.getTotalSize() }}>
 | 
			
		||||
            {// TODO: date based grouping
 | 
			
		||||
                virtualItems.map((item) => {
 | 
			
		||||
                    const isLoaderRow = item.index === size - 1 && isLoadingMore;
 | 
			
		||||
                    if (isLoaderRow) {
 | 
			
		||||
                        return <div key={item.index} className="w-full flex justify-center top-0 left-0 absolute"
 | 
			
		||||
                            style={{
 | 
			
		||||
                                height: `${item.size}px`,
 | 
			
		||||
                                transform: `translateY(${item.start}px)`
 | 
			
		||||
                            }}>
 | 
			
		||||
                            <Spinner />
 | 
			
		||||
                        </div>;
 | 
			
		||||
                    }
 | 
			
		||||
                    const docs = data[item.index];
 | 
			
		||||
                    if (!docs) return null;
 | 
			
		||||
                    return <div className="w-full grid gap-2 content-start top-0 left-0 absolute mb-2" key={item.index}
 | 
			
		||||
                        style={{
 | 
			
		||||
                            height: `${item.size}px`,
 | 
			
		||||
                            transform: `translateY(${item.start}px)`
 | 
			
		||||
                        }}>
 | 
			
		||||
                        {docs.startCursor && <div>
 | 
			
		||||
                            <h3 className="text-3xl">Start with {docs.startCursor}</h3>
 | 
			
		||||
                            <Separator />
 | 
			
		||||
                        </div>}
 | 
			
		||||
                        {docs?.data?.map((x) => {
 | 
			
		||||
                            return (
 | 
			
		||||
                                <GalleryCard doc={x} key={x.id} />
 | 
			
		||||
                            );
 | 
			
		||||
                        })}
 | 
			
		||||
                    </div>
 | 
			
		||||
                })
 | 
			
		||||
            }
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue