2026-01-19 14:36:58 +02:00
|
|
|
import { atom } from "jotai";
|
|
|
|
|
import type { ChatVisibility } from "@/lib/chat/thread-persistence";
|
2026-03-10 14:00:29 +05:30
|
|
|
import { reportPanelAtom } from "./report-panel.atom";
|
2026-01-19 14:36:58 +02:00
|
|
|
|
|
|
|
|
interface CurrentThreadState {
|
|
|
|
|
id: number | null;
|
2026-06-04 18:16:33 +05:30
|
|
|
searchSpaceId: number | null;
|
2026-01-19 14:36:58 +02:00
|
|
|
visibility: ChatVisibility | null;
|
|
|
|
|
hasComments: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-04 14:15:48 +05:30
|
|
|
interface CurrentThreadMetadataPatch {
|
|
|
|
|
id: number | null;
|
2026-06-04 18:16:33 +05:30
|
|
|
searchSpaceId?: number | null;
|
2026-06-04 14:15:48 +05:30
|
|
|
visibility?: ChatVisibility | null;
|
|
|
|
|
hasComments?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface CurrentThreadMetadataUpdate {
|
|
|
|
|
id: number;
|
|
|
|
|
visibility?: ChatVisibility | null;
|
|
|
|
|
hasComments?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-19 14:36:58 +02:00
|
|
|
const initialState: CurrentThreadState = {
|
|
|
|
|
id: null,
|
2026-06-04 18:16:33 +05:30
|
|
|
searchSpaceId: null,
|
2026-01-19 14:36:58 +02:00
|
|
|
visibility: null,
|
|
|
|
|
hasComments: false,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const currentThreadAtom = atom<CurrentThreadState>(initialState);
|
|
|
|
|
|
|
|
|
|
export const commentsEnabledAtom = atom(
|
|
|
|
|
(get) => get(currentThreadAtom).visibility === "SEARCH_SPACE"
|
|
|
|
|
);
|
|
|
|
|
|
2026-06-04 14:15:48 +05:30
|
|
|
export const setCurrentThreadMetadataAtom = atom(
|
|
|
|
|
null,
|
|
|
|
|
(get, set, metadata: CurrentThreadMetadataPatch) => {
|
|
|
|
|
const current = get(currentThreadAtom);
|
2026-06-04 18:16:33 +05:30
|
|
|
const isSameThread = current.id === metadata.id;
|
2026-06-04 14:15:48 +05:30
|
|
|
|
|
|
|
|
set(currentThreadAtom, {
|
|
|
|
|
...current,
|
|
|
|
|
id: metadata.id,
|
2026-06-04 18:16:33 +05:30
|
|
|
searchSpaceId:
|
|
|
|
|
"searchSpaceId" in metadata
|
|
|
|
|
? (metadata.searchSpaceId ?? null)
|
|
|
|
|
: isSameThread
|
|
|
|
|
? current.searchSpaceId
|
|
|
|
|
: null,
|
|
|
|
|
visibility:
|
|
|
|
|
"visibility" in metadata
|
|
|
|
|
? (metadata.visibility ?? null)
|
|
|
|
|
: isSameThread
|
|
|
|
|
? current.visibility
|
|
|
|
|
: null,
|
2026-06-04 14:15:48 +05:30
|
|
|
hasComments:
|
2026-06-04 18:16:33 +05:30
|
|
|
"hasComments" in metadata
|
|
|
|
|
? (metadata.hasComments ?? false)
|
|
|
|
|
: isSameThread
|
|
|
|
|
? current.hasComments
|
|
|
|
|
: false,
|
2026-06-04 14:15:48 +05:30
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
export const patchCurrentThreadMetadataAtom = atom(
|
|
|
|
|
null,
|
|
|
|
|
(get, set, patch: CurrentThreadMetadataUpdate) => {
|
|
|
|
|
const current = get(currentThreadAtom);
|
|
|
|
|
if (current.id !== patch.id) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set(currentThreadAtom, {
|
|
|
|
|
...current,
|
|
|
|
|
visibility: "visibility" in patch ? (patch.visibility ?? null) : current.visibility,
|
|
|
|
|
hasComments: "hasComments" in patch ? (patch.hasComments ?? false) : current.hasComments,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2026-01-19 14:36:58 +02:00
|
|
|
export const resetCurrentThreadAtom = atom(null, (_, set) => {
|
|
|
|
|
set(currentThreadAtom, initialState);
|
2026-04-30 22:37:11 +05:30
|
|
|
set(reportPanelAtom, {
|
|
|
|
|
isOpen: false,
|
|
|
|
|
reportId: null,
|
|
|
|
|
title: null,
|
|
|
|
|
wordCount: null,
|
|
|
|
|
shareToken: null,
|
|
|
|
|
contentType: "markdown",
|
|
|
|
|
});
|
2026-01-19 14:36:58 +02:00
|
|
|
});
|
2026-01-27 20:59:03 +05:30
|
|
|
|
2026-01-27 22:14:02 +05:30
|
|
|
/** Target comment ID to scroll to (from URL navigation or inbox click) */
|
|
|
|
|
export const targetCommentIdAtom = atom<number | null>(null);
|
|
|
|
|
|
2026-03-10 14:00:29 +05:30
|
|
|
export const setTargetCommentIdAtom = atom(null, (_, set, commentId: number | null) => {
|
2026-01-27 22:14:02 +05:30
|
|
|
set(targetCommentIdAtom, commentId);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export const clearTargetCommentIdAtom = atom(null, (_, set) => {
|
|
|
|
|
set(targetCommentIdAtom, null);
|
|
|
|
|
});
|