summaryrefslogtreecommitdiff
path: root/makima/frontend/src/hooks/useFiles.ts
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2025-12-23 22:20:52 +0000
committersoryu <soryu@soryu.co>2025-12-23 22:20:52 +0000
commit72c2590571104b8d10e3f72d7a5b984d0b520c51 (patch)
tree735aa03056a44a93b9abdf915545ad034ee2b597 /makima/frontend/src/hooks/useFiles.ts
parentf5222a7ae5ade5589436778cb01fc0abe625b3c3 (diff)
downloadsoryu-72c2590571104b8d10e3f72d7a5b984d0b520c51.tar.gz
soryu-72c2590571104b8d10e3f72d7a5b984d0b520c51.zip
Add conflict notification and file update WS endpoint
Diffstat (limited to 'makima/frontend/src/hooks/useFiles.ts')
-rw-r--r--makima/frontend/src/hooks/useFiles.ts23
1 files changed, 23 insertions, 0 deletions
diff --git a/makima/frontend/src/hooks/useFiles.ts b/makima/frontend/src/hooks/useFiles.ts
index aacbb6a..1998357 100644
--- a/makima/frontend/src/hooks/useFiles.ts
+++ b/makima/frontend/src/hooks/useFiles.ts
@@ -5,16 +5,24 @@ import {
createFile,
updateFile,
deleteFile,
+ VersionConflictError,
type FileSummary,
type FileDetail,
type CreateFileRequest,
type UpdateFileRequest,
} from "../lib/api";
+export interface ConflictState {
+ hasConflict: boolean;
+ expectedVersion: number;
+ actualVersion: number;
+}
+
export function useFiles() {
const [files, setFiles] = useState<FileSummary[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
+ const [conflict, setConflict] = useState<ConflictState | null>(null);
const fetchFiles = useCallback(async () => {
setLoading(true);
@@ -60,11 +68,20 @@ export function useFiles() {
const editFile = useCallback(
async (id: string, data: UpdateFileRequest): Promise<FileDetail | null> => {
setError(null);
+ setConflict(null);
try {
const file = await updateFile(id, data);
await fetchFiles(); // Refresh list
return file;
} catch (e) {
+ if (e instanceof VersionConflictError) {
+ setConflict({
+ hasConflict: true,
+ expectedVersion: e.expectedVersion,
+ actualVersion: e.actualVersion,
+ });
+ return null;
+ }
setError(e instanceof Error ? e.message : "Failed to update file");
return null;
}
@@ -72,6 +89,10 @@ export function useFiles() {
[fetchFiles]
);
+ const clearConflict = useCallback(() => {
+ setConflict(null);
+ }, []);
+
const removeFile = useCallback(
async (id: string): Promise<boolean> => {
setError(null);
@@ -96,6 +117,8 @@ export function useFiles() {
files,
loading,
error,
+ conflict,
+ clearConflict,
fetchFiles,
fetchFile,
saveFile,