diff --git a/notes/Another note.md b/notes/Another note.md new file mode 100644 index 0000000..a130f7a --- /dev/null +++ b/notes/Another note.md @@ -0,0 +1 @@ +Sup yo \ No newline at end of file diff --git a/notes/Super complicated, note.md b/notes/Super complicated, note.md new file mode 100644 index 0000000..1f52d50 --- /dev/null +++ b/notes/Super complicated, note.md @@ -0,0 +1 @@ +Yo!! \ No newline at end of file diff --git a/notes/Zef is cool.md b/notes/Zef is cool.md new file mode 100644 index 0000000..47ef1a1 --- /dev/null +++ b/notes/Zef is cool.md @@ -0,0 +1 @@ +I know he is! **Bold** \ No newline at end of file diff --git a/notes/start.md b/notes/start.md index 8e3b89b..0ee7ac1 100644 --- a/notes/start.md +++ b/notes/start.md @@ -9,6 +9,7 @@ For the rest of you, if you are not a parent, have no plan to be, or have absolu Thank you for sharing that perspective. However, in your case specifically, I have to insist you keep reading. It’s kids with your independent mindset that we’re trying to raise here. Although, perhaps you already know how to do that. Get in touch. + Hello there ----- diff --git a/notes/test.md b/notes/test.md index db486cb..e7409dc 100644 --- a/notes/test.md +++ b/notes/test.md @@ -1 +1,3 @@ -# Sappie \ No newline at end of file +# Sappie + +Sup \ No newline at end of file diff --git a/notes/test3.md b/notes/test3.md new file mode 100644 index 0000000..ede42e1 --- /dev/null +++ b/notes/test3.md @@ -0,0 +1,5 @@ +# Hello + +## Second level header + +bla \ No newline at end of file diff --git a/server/server.ts b/server/server.ts index 070220e..e135486 100644 --- a/server/server.ts +++ b/server/server.ts @@ -27,14 +27,24 @@ fsRouter.get('/', async context => { fsRouter.get('/:note', async context => { const noteName = context.params.note; const localPath = `${notesPath}/${noteName}.md`; - const text = await Deno.readTextFile(localPath); - context.response.body = text; + try { + const text = await Deno.readTextFile(localPath); + context.response.body = text; + } catch (e) { + context.response.status = 404; + context.response.body = ""; + } }); fsRouter.options('/:note', async context => { const localPath = `${notesPath}/${context.params.note}.md`; - const stat = await Deno.stat(localPath); - context.response.headers.set('Content-length', `${stat.size}`); + try { + const stat = await Deno.stat(localPath); + context.response.headers.set('Content-length', `${stat.size}`); + } catch (e) { + context.response.status = 200; + context.response.body = ""; + } }) fsRouter.put('/:note', async context => { diff --git a/webapp/src/app.js b/webapp/src/app.js deleted file mode 100644 index bb59f7f..0000000 --- a/webapp/src/app.js +++ /dev/null @@ -1,130 +0,0 @@ -import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; -import { autocompletion, completionKeymap } from "@codemirror/autocomplete"; -import { closeBrackets, closeBracketsKeymap } from "@codemirror/closebrackets"; -import { indentWithTab, standardKeymap } from "@codemirror/commands"; -import { history, historyKeymap } from "@codemirror/history"; -import { indentOnInput } from "@codemirror/language"; -import { bracketMatching } from "@codemirror/matchbrackets"; -import { searchKeymap } from "@codemirror/search"; -import { EditorState, StateField } from "@codemirror/state"; -import { drawSelection, dropCursor, EditorView, highlightSpecialChars, keymap, } from "@codemirror/view"; -import * as commands from "./commands"; -import { markdown } from "./markdown"; -import { lineWrapper } from "./lineWrapper"; -import customMarkDown from "./parser"; -import customMarkdownStyle from "./style"; -import { HttpFileSystem } from "./fs"; -import ReactDOM from "react-dom"; -import { useEffect, useRef } from "react"; -const fs = new HttpFileSystem("http://localhost:2222/fs"); -class Editor { - constructor(parent, currentNote, text) { - this.view = new EditorView({ - state: this.createEditorState(text), - parent: parent, - }); - this.currentNote = currentNote; - } - load(name, text) { - this.currentNote = name; - this.view.setState(this.createEditorState(text)); - } - async save() { - await fs.writeNote(this.currentNote, this.view.state.sliceDoc()); - } - focus() { - this.view.focus(); - } - createEditorState(text) { - return EditorState.create({ - doc: text, - extensions: [ - highlightSpecialChars(), - history(), - drawSelection(), - dropCursor(), - indentOnInput(), - customMarkdownStyle, - bracketMatching(), - closeBrackets(), - autocompletion(), - EditorView.lineWrapping, - lineWrapper([ - { selector: "ATXHeading1", class: "line-h1" }, - { selector: "ATXHeading2", class: "line-h2" }, - { selector: "ListItem", class: "line-li" }, - { selector: "Blockquote", class: "line-blockquote" }, - { selector: "CodeBlock", class: "line-code" }, - { selector: "FencedCode", class: "line-fenced-code" }, - ]), - keymap.of([ - ...closeBracketsKeymap, - ...standardKeymap, - ...searchKeymap, - ...historyKeymap, - ...completionKeymap, - indentWithTab, - { - key: "Ctrl-b", - mac: "Cmd-b", - run: commands.insertMarker("**"), - }, - { - key: "Ctrl-i", - mac: "Cmd-i", - run: commands.insertMarker("_"), - }, - { - key: "Ctrl-s", - mac: "Cmd-s", - run: (target) => { - Promise.resolve() - .then(async () => { - console.log("Saving"); - await this.save(); - }) - .catch((e) => console.error(e)); - return true; - }, - }, - ]), - EditorView.domEventHandlers({ - click: (event, view) => { - if (event.metaKey || event.ctrlKey) { - console.log("Navigate click"); - let coords = view.posAtCoords(event); - console.log("Coords", view.state.doc.sliceString(coords, coords + 1)); - return false; - } - }, - }), - markdown({ - base: customMarkDown, - }), - StateField.define({ - create: () => null, - update: (value, transaction) => { - if (transaction.docChanged) { - console.log("Something changed"); - } - return null; - }, - }), - ], - }); - } -} -export const App = () => { - const editorRef = useRef(); - useEffect(() => { - let editor = new Editor(editorRef.current, "", ""); - editor.focus(); - // @ts-ignore - window.editor = editor; - fs.readNote("start").then((text) => { - editor.load("start", text); - }); - }, []); - return (_jsxs(_Fragment, { children: [_jsx("div", { id: "top", children: "Hello" }, void 0), _jsx("div", { id: "editor", ref: editorRef }, void 0), _jsx("div", { id: "bottom", children: "Bottom" }, void 0)] }, void 0)); -}; -ReactDOM.render(_jsx(App, {}, void 0), document.body); diff --git a/webapp/src/app.tsx b/webapp/src/app.tsx index 54996cf..d05405d 100644 --- a/webapp/src/app.tsx +++ b/webapp/src/app.tsx @@ -24,19 +24,11 @@ import customMarkdownStyle from "./style"; import { FilterList } from "./components/filter"; +import { NoteMeta, AppViewState, Action } from "./types"; +import reducer from "./reducer"; + const fs = new HttpFileSystem("http://localhost:2222/fs"); -type NoteMeta = { - name: string; -}; - -type AppViewState = { - currentNote: string; - isSaved: boolean; - isFiltering: boolean; - allNotes: NoteMeta[]; -}; - const initialViewState = { currentNote: "", isSaved: false, @@ -44,50 +36,6 @@ const initialViewState = { allNotes: [], }; -type Action = - | { type: "loaded"; name: string } - | { type: "saved" } - | { type: "start-navigate" } - | { type: "stop-navigate" } - | { type: "updated" } - | { type: "notes-list"; notes: NoteMeta[] }; - -function reducer(state: AppViewState, action: Action): AppViewState { - switch (action.type) { - case "loaded": - return { - ...state, - currentNote: action.name, - isSaved: true, - }; - case "saved": - return { - ...state, - isSaved: true, - }; - case "updated": - return { - ...state, - isSaved: false, - }; - case "start-navigate": - return { - ...state, - isFiltering: true, - }; - case "stop-navigate": - return { - ...state, - isFiltering: false, - }; - case "notes-list": - return { - ...state, - allNotes: action.notes, - }; - } -} - class Editor { view: EditorView; currentNote: string; @@ -184,7 +132,6 @@ class Editor { update(value: null, transaction: Transaction): null { if (transaction.docChanged) { - console.log("Something changed"); this.dispatch({ type: "updated", }); @@ -215,6 +162,10 @@ class Editor { focus() { this.view.focus(); } + + navigate(name: string) { + location.hash = encodeURIComponent(name); + } } function TopBar({ @@ -223,28 +174,32 @@ function TopBar({ isFiltering, allNotes, onNavigate, + onClick, }: { currentNote: string; isSaved: boolean; isFiltering: boolean; allNotes: NoteMeta[]; - onNavigate: (note: string) => void; + onNavigate: (note: string | undefined) => void; + onClick: () => void; }) { return (