mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-12 23:31:02 +00:00
92c48fba22
Every file write went straight to the API, so offline a star snapped back
without a word and moving a file to the trash failed with "Failed to delete
file". Notes, the place or booking of a file, a further link, the star, the
trash move, restore, delete for good and emptying the trash now go through
fileRepo and the mutation queue like the other trip data: the local copy
changes at once, and an online write to a file that still has an older one
queued joins the queue behind it, since file writes carry no version token.
The desktop file manager, its assign dialog and the phone's files tab,
menu, link and trash sheets all write through it.
The single file answers carry no ids of further links, so a replayed edit,
star or restore keeps the ones the local copy holds, and the link answer
({ success, links }) writes no row.
What only works online says so instead of failing: an upload shows that it
needs a connection, a place saved with newly picked files is stopped with a
hint, and removing a further link (its row id is known only to the server)
asks to try again once online.
Refs #2601
97 lines
2.8 KiB
TypeScript
97 lines
2.8 KiB
TypeScript
import { useCallback, useEffect, useState } from 'react';
|
|
|
|
import type { useTranslation } from '../../i18n';
|
|
import { fileRepo } from '../../repo/fileRepo';
|
|
import type { TripFile } from '../../types';
|
|
import type { useToast } from '../shared/Toast';
|
|
|
|
export interface FileTrashOptions {
|
|
tripId: number;
|
|
t: ReturnType<typeof useTranslation>['t'];
|
|
toast: ReturnType<typeof useToast>;
|
|
/** Reloads the trip's live files after a restore brought one back. */
|
|
onRestored: () => void;
|
|
/**
|
|
* The phone's sheet: the trash loads every time this turns true, and a load still in
|
|
* flight when it closes or the trip changes is dropped. Left out, nothing loads by
|
|
* itself and the desktop view calls `load` when it opens the trash.
|
|
*/
|
|
open?: boolean;
|
|
}
|
|
|
|
/**
|
|
* The trashed files of a trip behind both shells: the desktop file manager's trash view
|
|
* and the phone's trash sheet. Each shell keeps its own confirm step and busy markers and
|
|
* calls the actions here once the user said yes.
|
|
*/
|
|
export function useFileTrash({ tripId, t, toast, onRestored, open }: FileTrashOptions) {
|
|
const [files, setFiles] = useState<TripFile[]>([]);
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const load = useCallback(async () => {
|
|
setLoading(true);
|
|
try {
|
|
const data = await fileRepo.listTrash(tripId);
|
|
setFiles(data.files || []);
|
|
} catch {
|
|
// An unreachable trash shows as empty.
|
|
}
|
|
setLoading(false);
|
|
}, [tripId]);
|
|
|
|
useEffect(() => {
|
|
if (!open) return;
|
|
let cancelled = false;
|
|
setLoading(true);
|
|
fileRepo
|
|
.listTrash(tripId)
|
|
.then((data: { files?: TripFile[] }) => {
|
|
if (!cancelled) setFiles(data.files || []);
|
|
})
|
|
.catch(() => {})
|
|
.finally(() => {
|
|
if (!cancelled) setLoading(false);
|
|
});
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, [open, tripId]);
|
|
|
|
const restore = async (fileId: number) => {
|
|
try {
|
|
await fileRepo.restore(
|
|
tripId,
|
|
fileId,
|
|
files.find((f) => f.id === fileId)
|
|
);
|
|
setFiles((prev) => prev.filter((f) => f.id !== fileId));
|
|
onRestored();
|
|
toast.success(t('files.toast.restored'));
|
|
} catch {
|
|
toast.error(t('files.toast.restoreError'));
|
|
}
|
|
};
|
|
|
|
const permanentDelete = async (fileId: number) => {
|
|
try {
|
|
await fileRepo.permanentDelete(tripId, fileId);
|
|
setFiles((prev) => prev.filter((f) => f.id !== fileId));
|
|
toast.success(t('files.toast.deleted'));
|
|
} catch {
|
|
toast.error(t('files.toast.deleteError'));
|
|
}
|
|
};
|
|
|
|
const emptyTrash = async () => {
|
|
try {
|
|
await fileRepo.emptyTrash(tripId);
|
|
setFiles([]);
|
|
toast.success(t('files.toast.trashEmptied'));
|
|
} catch {
|
|
toast.error(t('files.toast.deleteError'));
|
|
}
|
|
};
|
|
|
|
return { files, loading, load, restore, permanentDelete, emptyTrash };
|
|
}
|