Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/studio/src/api/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,9 +451,9 @@ export function createStudioServer(initialConfig: ProjectConfig, root: string) {
const storyDir = join(bookDir, "story");
try {
const files = await readdir(storyDir);
const mdFiles = files.filter((f) => f.endsWith(".md") || f.endsWith(".json"));
const filteredFiles = files.filter((f) => TRUTH_FILES.includes(f));
const result = await Promise.all(
mdFiles.map(async (f) => {
filteredFiles.map(async (f) => {
const content = await readFile(join(storyDir, f), "utf-8");
return { name: f, size: content.length, preview: content.slice(0, 200) };
}),
Expand Down
20 changes: 17 additions & 3 deletions packages/studio/src/pages/TruthFiles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,16 @@ export function TruthFiles({ bookId, nav, theme, t }: { bookId: string; nav: Nav
const [editMode, setEditMode] = useState(false);
const [editText, setEditText] = useState("");
const [savingEdit, setSavingEdit] = useState(false);
const { data: fileData, refetch: refetchFile } = useApi<{ file: string; content: string | null }>(
const { data: fileData, loading: fileLoading, error: fileError, refetch: refetchFile } = useApi<{ file: string; content: string | null }>(
selected ? `/books/${bookId}/truth/${selected}` : "",
);

// Clear edit mode when switching files
const handleSelect = (name: string) => {
setSelected(name);
setEditMode(false);
};

const startEdit = () => {
setEditText(fileData?.content ?? "");
setEditMode(true);
Expand Down Expand Up @@ -72,7 +78,7 @@ export function TruthFiles({ bookId, nav, theme, t }: { bookId: string; nav: Nav
{data?.files.map((f) => (
<button
key={f.name}
onClick={() => { setSelected(f.name); setEditMode(false); }}
onClick={() => handleSelect(f.name)}
className={`w-full text-left px-3 py-2.5 text-sm border-b border-border/40 transition-colors ${
selected === f.name
? "bg-primary/10 text-primary"
Expand All @@ -90,7 +96,15 @@ export function TruthFiles({ bookId, nav, theme, t }: { bookId: string; nav: Nav

{/* Content viewer */}
<div className={`border ${c.cardStatic} rounded-lg p-5 min-h-[400px] flex flex-col`}>
{selected && fileData?.content != null ? (
{fileLoading || (fileData && fileData.file !== selected) ? (
<div className="flex-1 flex items-center justify-center">
<div className="animate-pulse text-muted-foreground text-sm">Loading...</div>
</div>
) : fileError ? (
<div className="flex-1 flex items-center justify-center">
<div className="text-destructive text-sm bg-destructive/10 px-4 py-2 rounded-md">{fileError}</div>
</div>
) : selected && fileData?.content != null ? (
<>
<div className="flex items-center justify-end gap-2 mb-3">
{editMode ? (
Expand Down