Skip to content

Commit

Permalink
add ui + improve import export
Browse files Browse the repository at this point in the history
  • Loading branch information
codyzu committed Jul 13, 2023
1 parent e9ac542 commit 7eb9397
Show file tree
Hide file tree
Showing 4 changed files with 304 additions and 153 deletions.
225 changes: 141 additions & 84 deletions src/components/PresentationPreferencesEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import {useDebouncedCallback} from 'use-debounce';
import {useRef} from 'react';
import {type Note} from '../../functions/src/presentation';
import NoteEditor from './NoteEditor';
import SaveIndicator from './SaveIndicator';
import Button from './toolbar/Button';
import {exportNotes, importNotes} from './slides/parse-notes';

export type NotesSaveState = 'dirty' | 'saved' | 'saving';

Expand All @@ -28,96 +31,150 @@ export default function PresentationPreferencesEditor({
onSave();
}, 3000);

return (
<div className="w-full max-w-screen-md mx-auto flex flex-col text-base">
<input
placeholder="Give your presentation a name..."
className="input w-full max-w-screen-sm self-center"
value={title}
onChange={(event) => {
onDirty();
setTitle(event.target.value);
debouncedSaveNotes();
}}
/>
{notes.map((note, noteIndex) => (
<NoteEditor
key={note.pageIndices.toString()}
pageIndices={note.pageIndices}
markdown={note.markdown}
handleFoldUp={() => {
onDirty();
setNotes((currentNotes) => {
// Add the current index to the previous note
const previousNote: Note = {
...currentNotes[noteIndex - 1],
pageIndices: [
...currentNotes[noteIndex - 1].pageIndices,
...note.pageIndices,
],
};

const nextNotes = [
// Copy up to the previous note
...currentNotes.slice(0, Math.max(noteIndex - 1, 0)),
// Add the previous note
previousNote,
// Skip the current note and copy everything else
...currentNotes.slice(noteIndex + 1),
];
const fileRef = useRef<HTMLInputElement>(null);

return nextNotes;
});
debouncedSaveNotes();
return (
<div className="w-full max-w-screen-md mx-auto flex flex-col text-base gap-4">
<div className="grid grid-cols-[6fr_1fr_1fr] lt-sm:(grid-cols-2) gap-4">
<label className="flex flex-row gap-2 items-center lt-sm:col-span-2">
Title:
<input
placeholder="Give your presentation a name..."
className="input w-full max-w-screen-sm self-center h-full"
value={title}
onChange={(event) => {
onDirty();
setTitle(event.target.value);
debouncedSaveNotes();
}}
/>
</label>
<Button
border
icon="i-tabler-package-import"
label="import"
title="Import notes"
onClick={() => {
fileRef.current?.click?.();
}}
handleFoldDown={() => {
onDirty();
setNotes((currentNotes) => {
const lastIndexInNote =
currentNotes[noteIndex].pageIndices.at(-1)!;

// Remove the last index from the current note
const currentNote: Note = {
...currentNotes[noteIndex],
pageIndices: currentNotes[noteIndex].pageIndices.slice(0, -1),
};

const nextNote: Note = {
pageIndices: [lastIndexInNote],
markdown: '',
};

const nextNotes = [
// Copy up to the current note
...currentNotes.slice(0, noteIndex),
// Add the current note
currentNote,
// Insert the next note
nextNote,
// Copy the rest
...currentNotes.slice(noteIndex + 1),
];
console.log('next notes', nextNotes);
return nextNotes;
});
/>
<input
ref={fileRef}
type="file"
className="hidden"
accept="text/markdown,.md"
onChange={async (event) => {
try {
if ((event.target.files?.length ?? 0) < 1) {
return;
}

debouncedSaveNotes();
const markdown = await event.target.files![0].text();
const importedNotes = importNotes(markdown, pages.length);
console.log('imported notes', importedNotes);
onDirty();
setNotes(() => importedNotes);
debouncedSaveNotes();
} finally {
// Clear the input so that even if the same file is chosen, it will be re-parsed
event.target.value = '';
}
}}
pages={pages}
onMarkdownChange={(markdown) => {
onDirty();
setNotes((currentNotes) => {
const nextNotes = Array.from(currentNotes);
nextNotes[noteIndex] = {...currentNotes[noteIndex], markdown};
return nextNotes;
});
debouncedSaveNotes();
}}
onMarkdownDirty={() => {
onDirty();
/>
<Button
border
icon="i-tabler-package-export"
label="export"
title="Export notes"
onClick={() => {
const markdown = exportNotes(notes);
const blob = new Blob([markdown], {type: 'text/markdown'});
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.download = `${title || 'notes'}.md`;
link.href = url;
link.click();
URL.revokeObjectURL(url);
}}
/>
))}
</div>
<div className="flex flex-col w-full">
{notes.map((note, noteIndex) => (
<NoteEditor
key={note.pageIndices.toString()}
pageIndices={note.pageIndices}
markdown={note.markdown}
handleFoldUp={() => {
onDirty();
setNotes((currentNotes) => {
// Add the current index to the previous note
const previousNote: Note = {
...currentNotes[noteIndex - 1],
pageIndices: [
...currentNotes[noteIndex - 1].pageIndices,
...note.pageIndices,
],
};
const nextNotes = [
// Copy up to the previous note
...currentNotes.slice(0, Math.max(noteIndex - 1, 0)),
// Add the previous note
previousNote,
// Skip the current note and copy everything else
...currentNotes.slice(noteIndex + 1),
];
return nextNotes;
});
debouncedSaveNotes();
}}
handleFoldDown={() => {
onDirty();
setNotes((currentNotes) => {
const lastIndexInNote =
currentNotes[noteIndex].pageIndices.at(-1)!;
// Remove the last index from the current note
const currentNote: Note = {
...currentNotes[noteIndex],
pageIndices: currentNotes[noteIndex].pageIndices.slice(
0,
-1,
) as [number, ...number[]],
};
const nextNote: Note = {
pageIndices: [lastIndexInNote],
markdown: '',
};
const nextNotes = [
// Copy up to the current note
...currentNotes.slice(0, noteIndex),
// Add the current note
currentNote,
// Insert the next note
nextNote,
// Copy the rest
...currentNotes.slice(noteIndex + 1),
];
console.log('next notes', nextNotes);
return nextNotes;
});
debouncedSaveNotes();
}}
pages={pages}
onMarkdownChange={(markdown) => {
onDirty();
setNotes((currentNotes) => {
const nextNotes = Array.from(currentNotes);
nextNotes[noteIndex] = {...currentNotes[noteIndex], markdown};
return nextNotes;
});
debouncedSaveNotes();
}}
onMarkdownDirty={() => {
onDirty();
}}
/>
))}
</div>
<SaveIndicator saveState={saveState} />
</div>
);
Expand Down
51 changes: 0 additions & 51 deletions src/components/slides/notes.test.ts

This file was deleted.

Loading

0 comments on commit 7eb9397

Please sign in to comment.