diff --git a/frontend/fakenoteprovider.js b/frontend/fakenoteprovider.js new file mode 100644 index 0000000..19e14e3 --- /dev/null +++ b/frontend/fakenoteprovider.js @@ -0,0 +1,86 @@ +import { NoteProvider } from "./noteprovider"; + +class Note { + name; + content; + tags; + + constructor(name) { + this.name = name; + this.content = ""; + this.tags = []; + } +} + +class FakeNoteProvider extends NoteProvider { + + #notes; + + constructor() { + super(); + this.#notes = new Map([ + ["Sample", new Note("Sample")] + ]); + } + + #get_note(name) { + const note = this.#notes.get(name); + if (!note) { throw new Error(`unknown note \"${name}\"`); } + return note; + } + + async list() { + return [...this.#notes.keys()]; + } + + async read(name) { + const note = this.#get_note(name); + return note.name; + } + + async create() { + let name = "Untitled"; + let count = 0; + while (this.#notes.has(name)) { + count++; + name = `Untitled ${count}`; + } + + this.#notes.set(name, new Note(name)); + return name; + } + + async rename(old_name, new_name) { + const note = this.#get_note(old_name); + if (this.#notes.has(new_name)) { + throw new Error(`failed to rename to an existing note \"${new_name}\"`); + } + + this.#notes.delete(old_name); + note.name = new_name; + this.#notes.set(note.name, note); + } + + async write(name, content) { + const note = this.#get_note(name); + note.content = content; + } + + async remove(name) { + if (this.#notes.has(name)) { + this.#notes.delete(name); + } + } + + async read_tags(name) { + const note = this.#get_note(name); + return note.tags; + } + + async write_tags(name, tags) { + const note = this.#get_note(name); + note.tags = tags; + } +} + +export { FakeNoteProvider } \ No newline at end of file diff --git a/frontend/main.js b/frontend/main.js index 145a3b5..b3057f7 100644 --- a/frontend/main.js +++ b/frontend/main.js @@ -8,11 +8,19 @@ import { marked } from "marked" import { slider_attach } from "./slider.js" import { init_titlebar } from "./titlebar.js" import { init_settings } from "./settings.js" +import { FakeNoteProvider } from "./fakenoteprovider.js" +import { NoteList } from "./notelist.js" init_titlebar(); init_settings(); slider_attach(document.querySelector("#slider")); +const noteProvider = new FakeNoteProvider(); +const notelist_element = document.querySelector("#notelist"); +const notelist = new NoteList(noteProvider, notelist_element); +document.querySelector("#add-note").addEventListener("click", async () => { + notelist.add_new(); +}) const language = new Compartment(); const editor_element = document.querySelector("#editor"); diff --git a/frontend/note.js b/frontend/note.js new file mode 100644 index 0000000..ad61f64 --- /dev/null +++ b/frontend/note.js @@ -0,0 +1,26 @@ +class Note { + #name; + #list_item; + + constructor(name, notelist) { + this.#name = name; + this.#create_listentry(notelist); + } + + + get name() { + return this.#name; + } + + #create_listentry(notelist) { + this.#list_item = document.createElement("li"); + notelist.element.appendChild(this.#list_item); + + this.#list_item.textContent = this.#name; + this.#list_item.addEventListener('click', async () => { + console.log("ToDo: activate"); + }, false); + } +} + +export { Note } diff --git a/frontend/notelist.js b/frontend/notelist.js new file mode 100644 index 0000000..21f6c11 --- /dev/null +++ b/frontend/notelist.js @@ -0,0 +1,42 @@ +import { Note } from "./note.js" + +class NoteList { + + #provider + #element; + #notes; + + constructor(provider, element) { + this.#provider = provider; + this.#element = element; + + this.#update(); + } + + async #update() { + this.#element.innerHTML = ""; + this.#notes = new Map(); + + const notes = await this.#provider.list(); + for (const name of notes) { + await this.#add(name); + } + } + + async #add(name) { + const text = await this.#provider.read(name); + const tags = await this.#provider.read_tags(name); + const note = new Note(name, this); + } + + get element() { + return this.#element; + } + + async add_new() { + const name = await this.#provider.create(); + this.#add(name); + } +} + +export { NoteList } diff --git a/frontend/noteprovider.js b/frontend/noteprovider.js new file mode 100644 index 0000000..f73de23 --- /dev/null +++ b/frontend/noteprovider.js @@ -0,0 +1,117 @@ + +/** + * This class documents the NoteProvider interface. + */ +class NoteProvider { + + /** + * Returns a list of the names of all notes. + * + * @returns {String[]} List containing the names of all notes. + */ + async list() { + throw new Error("Not implementd"); + } + + /** + * Returns the contents of a note. + * + * @param {String} name Name of the the note. + * @returns {String} contents of the note + * @throws {Error} unknown note + */ + async read(name) { + throw new Error("Not implementd"); + } + + /** + * Creates a new note and returns it's name. + * + * @returns {String} Name of the newly created note. + */ + async create() { + throw new Error("Not implementd"); + } + + /** + * Renames an existing note. + * + * @param {String} old_name Name of an existing note + * @param {String} new_name New name of the note + * @throws {Error} unknown note + * @throws {Error} there is already a note with the new name + */ + async rename(old_name, new_name) { + throw new Error("Not implementd"); + } + + /** + * Writes the contents of an existing note. + * + * @param {String} name Name of the note + * @param {String} content New contents of the note + * @throws {Error} unknown note + */ + async write(name, content) { + throw new Error("Not implementd"); + } + + /** + * Removes an existing note. + * + * Note that this method does not fail, if + * the note does not exist. + * + * @param {String} name + */ + async remove(name) { + throw new Error("Not implementd"); + } + + /** + * Returns all tags of an existing note. + * + * @param {String} name name of then note + * @returns {String[]} tags of the note + * @throws {Error} unknown note + */ + async read_tags(name) { + throw new Error("Not implementd"); + } + + /** + * Writes (replaces) tht tags of an existing note + * + * @param {String} name name of the note + * @param {String[]} tags tags of the note + * @throws {Error} unknown note + */ + async write_tags(name, tags) { + throw new Error("Not implementd"); + } + + /** + * Takes a screenshot and returns its filename. + * + * @param {String} name name of the note associated with the screenshot + * @returns {String} filename of the screenshot (relative to the note's directory) + * @throws {Error} unknown note + * @throws {Error} screenshot command failed + */ + async take_screenshot(name) { + throw new Error("Not implemented"); + } + + /** + * Opens the note directory in a file browser. + * + * @param {String} name name of the note associated with the screenshot + * @throws {Error} unknown note + */ + async open_note_directory(name) { + throw new Error("Not implemented"); + } +} + + +export { NoteProvider } \ No newline at end of file