mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-22 14:39:34 +01:00
feat: implement fluent api
This commit is contained in:
@@ -12,7 +12,7 @@ beforeEach(async () => {
|
||||
test("add a notebook", () =>
|
||||
notebookTest().then(({ db, id }) => {
|
||||
expect(id).toBeDefined();
|
||||
let notebook = db.notebooks.get(id);
|
||||
let notebook = db.notebooks.notebook(id);
|
||||
expect(notebook).toBeDefined();
|
||||
expect(notebook.title).toBe(TEST_NOTEBOOK.title);
|
||||
}));
|
||||
@@ -34,42 +34,46 @@ test("search all notebooks", () =>
|
||||
|
||||
test("pin a notebook", () =>
|
||||
notebookTest().then(async ({ db, id }) => {
|
||||
await db.notebooks.pin(id);
|
||||
let notebook = db.notebooks.get(id);
|
||||
expect(notebook.pinned).toBe(true);
|
||||
let notebook = db.notebooks.notebook(id);
|
||||
await notebook.pin();
|
||||
expect(notebook.data.pinned).toBe(true);
|
||||
}));
|
||||
|
||||
test("unpin a notebook", () =>
|
||||
notebookTest().then(async ({ db, id }) => {
|
||||
await db.notebooks.unpin(id);
|
||||
let notebook = db.notebooks.get(id);
|
||||
expect(notebook.pinned).toBe(false);
|
||||
let notebook = db.notebooks.notebook(id);
|
||||
await notebook.pin();
|
||||
expect(notebook.data.pinned).toBe(true);
|
||||
await notebook.pin();
|
||||
expect(notebook.data.pinned).toBe(false);
|
||||
}));
|
||||
|
||||
test("favorite a notebook", () =>
|
||||
notebookTest().then(async ({ db, id }) => {
|
||||
await db.notebooks.favorite(id);
|
||||
let notebook = db.notebooks.get(id);
|
||||
expect(notebook.favorite).toBe(true);
|
||||
let notebook = db.notebooks.notebook(id);
|
||||
await notebook.favorite();
|
||||
expect(notebook.data.favorite).toBe(true);
|
||||
}));
|
||||
|
||||
test("unfavorite a notebook", () =>
|
||||
notebookTest().then(async ({ db, id }) => {
|
||||
await db.notebooks.unfavorite(id);
|
||||
let notebook = db.notebooks.get(id);
|
||||
expect(notebook.favorite).toBe(false);
|
||||
let notebook = db.notebooks.notebook(id);
|
||||
await notebook.favorite();
|
||||
expect(notebook.data.favorite).toBe(true);
|
||||
await notebook.favorite();
|
||||
expect(notebook.data.favorite).toBe(false);
|
||||
}));
|
||||
|
||||
test("delete a notebook", () =>
|
||||
notebookTest().then(async ({ db, id }) => {
|
||||
let noteId = await db.notes.add(TEST_NOTE);
|
||||
await db.notebooks
|
||||
.topics(id)
|
||||
.topic("General")
|
||||
.notebook(id)
|
||||
.topics.topic("General")
|
||||
.add(noteId);
|
||||
let note = await db.notes.get(noteId);
|
||||
let note = db.notes.note(noteId);
|
||||
expect(note.notebook.id).toBe(id);
|
||||
await db.notebooks.delete(id);
|
||||
note = await db.notes.get(noteId);
|
||||
note = db.notes.note(noteId);
|
||||
expect(note.notebook.id).toBeUndefined();
|
||||
}));
|
||||
|
||||
@@ -24,14 +24,14 @@ test("add invalid note", () =>
|
||||
|
||||
test("add note", () =>
|
||||
noteTest().then(async ({ db, id }) => {
|
||||
let note = db.notes.get(id);
|
||||
expect(note).toBeDefined();
|
||||
expect(note.content.text).toStrictEqual(TEST_NOTE.content.text);
|
||||
let note = db.notes.note(id);
|
||||
expect(note.data).toBeDefined();
|
||||
expect(note.text).toStrictEqual(TEST_NOTE.content.text);
|
||||
}));
|
||||
|
||||
test("get delta of note", () =>
|
||||
noteTest().then(async ({ db, id }) => {
|
||||
let delta = await db.notes.delta(id);
|
||||
let delta = await db.notes.note(id).delta();
|
||||
expect(delta).toStrictEqual(TEST_NOTE.content.delta);
|
||||
}));
|
||||
|
||||
@@ -39,14 +39,12 @@ test("delete note", () =>
|
||||
noteTest().then(async ({ db, id }) => {
|
||||
let notebookId = await db.notebooks.add(TEST_NOTEBOOK);
|
||||
let topic = await db.notebooks
|
||||
.topics(notebookId)
|
||||
.topic("General")
|
||||
.notebook(notebookId)
|
||||
.topics.topic("General")
|
||||
.add(id);
|
||||
expect(topic.all.findIndex(v => v.id === id)).toBeGreaterThan(-1);
|
||||
await db.notes.delete(id);
|
||||
let note = db.notes.get(id);
|
||||
expect(await db.notes.delta(id)).toBeUndefined();
|
||||
expect(note).toBeUndefined();
|
||||
expect(db.notes.note(id)).toBeUndefined();
|
||||
expect(topic.all.findIndex(v => v.id === id)).toBe(-1);
|
||||
}));
|
||||
|
||||
@@ -65,7 +63,7 @@ test("search all notes", () =>
|
||||
|
||||
test("note without a title should get title from content", () =>
|
||||
noteTest().then(async ({ db, id }) => {
|
||||
let note = db.notes.get(id);
|
||||
let note = db.notes.note(id);
|
||||
expect(note.title).toBe("I am a");
|
||||
}));
|
||||
|
||||
@@ -83,11 +81,11 @@ test("update note", () =>
|
||||
// colors: ["red", "blue"]
|
||||
};
|
||||
id = await db.notes.add(noteData);
|
||||
let note = db.notes.get(id);
|
||||
let note = db.notes.note(id);
|
||||
expect(note.title).toBe(noteData.title);
|
||||
expect(note.content.text).toStrictEqual(noteData.content.text);
|
||||
expect(note.pinned).toBe(true);
|
||||
expect(note.favorite).toBe(true);
|
||||
expect(note.text).toStrictEqual(noteData.content.text);
|
||||
expect(note.data.pinned).toBe(true);
|
||||
expect(note.data.favorite).toBe(true);
|
||||
}));
|
||||
|
||||
test("updating empty note should delete it", () =>
|
||||
@@ -101,24 +99,26 @@ test("updating empty note should delete it", () =>
|
||||
}
|
||||
});
|
||||
expect(id).toBeUndefined();
|
||||
let note = db.notes.get(id);
|
||||
let note = db.notes.note(id);
|
||||
expect(note).toBeUndefined();
|
||||
}));
|
||||
|
||||
test("add tag to note", () =>
|
||||
noteTest().then(async ({ db, id }) => {
|
||||
await db.notes.tag(id, "hello");
|
||||
expect(db.notes.get(id).tags[0]).toBe("hello");
|
||||
let note = db.notes.note(id);
|
||||
await note.tag("hello");
|
||||
expect(note.tags[0]).toBe("hello");
|
||||
expect(db.notes.tags[0].title).toBe("hello");
|
||||
}));
|
||||
|
||||
test("remove tag from note", () =>
|
||||
noteTest().then(async ({ db, id }) => {
|
||||
await db.notes.tag(id, "hello");
|
||||
expect(db.notes.get(id).tags[0]).toBe("hello");
|
||||
let note = db.notes.note(id);
|
||||
await note.tag("hello");
|
||||
expect(note.tags[0]).toBe("hello");
|
||||
expect(db.notes.tags[0].title).toBe("hello");
|
||||
await db.notes.untag(id, "hello");
|
||||
expect(db.notes.get(id).tags.length).toBe(0);
|
||||
await note.untag("hello");
|
||||
expect(note.tags.length).toBe(0);
|
||||
expect(db.notes.tags.length).toBe(0);
|
||||
}));
|
||||
|
||||
@@ -129,7 +129,7 @@ test("note with text longer than 150 characters should have ... in the headline"
|
||||
delta: []
|
||||
}
|
||||
}).then(({ db, id }) => {
|
||||
let note = db.notes.get(id);
|
||||
let note = db.notes.note(id);
|
||||
expect(note.headline.includes("...")).toBe(true);
|
||||
}));
|
||||
|
||||
@@ -192,45 +192,48 @@ test("get grouped notes default (special)", () => groupedTest("", true));
|
||||
|
||||
test("pin note", () =>
|
||||
noteTest().then(async ({ db, id }) => {
|
||||
await db.notes.pin(id);
|
||||
expect(db.notes.get(id).pinned).toBe(true);
|
||||
let note = db.notes.note(id);
|
||||
await note.pin();
|
||||
expect(note.data.pinned).toBe(true);
|
||||
}));
|
||||
|
||||
test("favorite note", () =>
|
||||
noteTest().then(async ({ db, id }) => {
|
||||
await db.notes.favorite(id);
|
||||
expect(db.notes.get(id).favorite).toBe(true);
|
||||
let note = db.notes.note(id);
|
||||
await note.favorite();
|
||||
expect(note.data.favorite).toBe(true);
|
||||
}));
|
||||
|
||||
test("lock and unlock note", () =>
|
||||
noteTest().then(async ({ db, id }) => {
|
||||
expect(await db.notes.lock(id, "password123")).toBe(true);
|
||||
let note = db.notes.get(id);
|
||||
expect(note.locked).toBe(true);
|
||||
expect(note.content.iv).toBeDefined();
|
||||
note = await db.notes.unlock(id, "password123");
|
||||
let note = db.notes.note(id);
|
||||
await note.lock("password123");
|
||||
expect(note.data.locked).toBe(true);
|
||||
expect(note.data.content.iv).toBeDefined();
|
||||
note = await note.unlock("password123");
|
||||
expect(note.id).toBe(id);
|
||||
expect(note.content.text).toBe(TEST_NOTE.content.text);
|
||||
await db.notes.unlock(id, "password123", true);
|
||||
note = db.notes.get(id);
|
||||
expect(note.locked).toBe(false);
|
||||
note = db.notes.note(id);
|
||||
await note.unlock("password123", true);
|
||||
note = db.notes.note(id);
|
||||
expect(note.data.locked).toBe(false);
|
||||
}));
|
||||
|
||||
test("add note to topic", () =>
|
||||
noteTest().then(async ({ db, id }) => {
|
||||
let notebookId = await db.notebooks.add({ title: "Hello" });
|
||||
let topics = db.notebooks.topics(notebookId);
|
||||
let topics = db.notebooks.notebook(notebookId).topics;
|
||||
let topic = await topics.add("Home");
|
||||
await topic.add(id);
|
||||
expect(topic.all.length).toBe(1);
|
||||
let note = db.notes.get(id);
|
||||
let note = db.notes.note(id);
|
||||
expect(note.notebook.id).toBe(notebookId);
|
||||
}));
|
||||
|
||||
test("duplicate note to topic should not be added", () =>
|
||||
noteTest().then(async ({ db, id }) => {
|
||||
let notebookId = await db.notebooks.add({ title: "Hello" });
|
||||
let topics = db.notebooks.topics(notebookId);
|
||||
let topics = db.notebooks.notebook(notebookId).topics;
|
||||
let topic = await topics.add("Home");
|
||||
await topic.add(id);
|
||||
expect(topic.all.length).toBe(1);
|
||||
@@ -239,14 +242,14 @@ test("duplicate note to topic should not be added", () =>
|
||||
test("move note", () =>
|
||||
noteTest().then(async ({ db, id }) => {
|
||||
let notebookId = await db.notebooks.add({ title: "Hello" });
|
||||
let topics = db.notebooks.topics(notebookId);
|
||||
let topics = db.notebooks.notebook(notebookId).topics;
|
||||
let topic = await topics.add("Home");
|
||||
await topic.add(id);
|
||||
setTimeout(async () => {
|
||||
let notebookId2 = await db.notebooks.add({ title: "Hello2" });
|
||||
await db.notebooks.topics(notebookId2).add("Home2");
|
||||
await db.notebooks.notebook(notebookId2).topics.add("Home2");
|
||||
await db.notes.move({ id: notebookId2, topic: "Home2" }, id);
|
||||
let note = db.notes.get(id);
|
||||
let note = db.notes.note(id);
|
||||
expect(note.notebook.id).toBe(notebookId2);
|
||||
}, 1000);
|
||||
}));
|
||||
@@ -254,10 +257,10 @@ test("move note", () =>
|
||||
test("moving note to same notebook and topic should do nothing", () =>
|
||||
noteTest().then(async ({ db, id }) => {
|
||||
let notebookId = await db.notebooks.add({ title: "Hello" });
|
||||
let topics = db.notebooks.topics(notebookId);
|
||||
let topics = db.notebooks.notebook(notebookId).topics;
|
||||
let topic = await topics.add("Home");
|
||||
await topic.add(id);
|
||||
await db.notes.move({ id: notebookId, topic: "Home" }, id);
|
||||
let note = db.notes.get(id);
|
||||
let note = db.notes.note(id);
|
||||
expect(note.notebook.id).toBe(notebookId);
|
||||
}));
|
||||
|
||||
@@ -4,7 +4,7 @@ beforeEach(() => StorageInterface.clear());
|
||||
|
||||
test("get empty topic", () =>
|
||||
notebookTest().then(({ db, id }) => {
|
||||
let topic = db.notebooks.topics(id).topic("General");
|
||||
let topic = db.notebooks.notebook(id).topics.topic("General");
|
||||
expect(topic.all.length).toBe(0);
|
||||
}));
|
||||
|
||||
@@ -15,7 +15,7 @@ test("getting invalid topic should throw", () =>
|
||||
|
||||
test("add topic to notebook", () =>
|
||||
notebookTest().then(async ({ db, id }) => {
|
||||
let topics = db.notebooks.topics(id);
|
||||
let topics = db.notebooks.notebook(id).topics;
|
||||
await topics.add("Home");
|
||||
expect(topics.all.length).toBeGreaterThan(1);
|
||||
expect(topics.all.findIndex(v => v.title === "Home")).toBeGreaterThan(-1);
|
||||
@@ -23,7 +23,7 @@ test("add topic to notebook", () =>
|
||||
|
||||
test("duplicate topic to notebook should not be added", () =>
|
||||
notebookTest().then(async ({ db, id }) => {
|
||||
let topics = db.notebooks.topics(id);
|
||||
let topics = db.notebooks.notebook(id).topics;
|
||||
await topics.add("Home");
|
||||
let len = topics.all.length;
|
||||
await topics.add("Home");
|
||||
@@ -32,7 +32,7 @@ test("duplicate topic to notebook should not be added", () =>
|
||||
|
||||
test("get topic", () =>
|
||||
notebookTest().then(async ({ db, id }) => {
|
||||
let topics = db.notebooks.topics(id);
|
||||
let topics = db.notebooks.notebook(id).topics;
|
||||
let topic = await topics.add("Home");
|
||||
let noteId = await db.notes.add({ content: { text: "Hello", delta: [] } });
|
||||
await topic.add(noteId);
|
||||
@@ -41,7 +41,7 @@ test("get topic", () =>
|
||||
|
||||
test("delete a topic", () =>
|
||||
notebookTest().then(async ({ db, id }) => {
|
||||
let topics = db.notebooks.topics(id);
|
||||
let topics = db.notebooks.notebook(id).topics;
|
||||
await topics.add("Home");
|
||||
await topics.delete("Home");
|
||||
expect(topics.all.findIndex(v => v.title === "Home")).toBe(-1);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import CachedCollection from "../database/cached-collection";
|
||||
import fuzzysearch from "fuzzysearch";
|
||||
import Topics from "./topics";
|
||||
import Notebook from "../models/notebook";
|
||||
var tfun = require("transfun/transfun.js").tfun;
|
||||
if (!tfun) {
|
||||
tfun = global.tfun;
|
||||
@@ -82,16 +82,18 @@ export default class Notebooks {
|
||||
return this.collection.getAllItems();
|
||||
}
|
||||
|
||||
get(id) {
|
||||
return this.collection.getItem(id);
|
||||
notebook(id) {
|
||||
let notebook = this.collection.getItem(id);
|
||||
if (!notebook) return;
|
||||
return new Notebook(this, notebook);
|
||||
}
|
||||
|
||||
async delete(...ids) {
|
||||
for (let id of ids) {
|
||||
let notebook = this.get(id);
|
||||
let notebook = this.notebook(id);
|
||||
if (!notebook) continue;
|
||||
await this.collection.transaction(() =>
|
||||
this.topics(id).delete(...notebook.topics)
|
||||
notebook.topics.delete(...notebook.topics.all)
|
||||
);
|
||||
await this.collection.removeItem(id);
|
||||
}
|
||||
@@ -103,23 +105,6 @@ export default class Notebooks {
|
||||
this.all
|
||||
);
|
||||
}
|
||||
|
||||
topics(id) {
|
||||
return new Topics(this, this.notes, id);
|
||||
}
|
||||
|
||||
pin(id) {
|
||||
return this.add({ id, pinned: true });
|
||||
}
|
||||
unpin(id) {
|
||||
return this.add({ id, pinned: false });
|
||||
}
|
||||
favorite(id) {
|
||||
return this.add({ id, favorite: true });
|
||||
}
|
||||
unfavorite(id) {
|
||||
return this.add({ id, favorite: false });
|
||||
}
|
||||
}
|
||||
|
||||
function makeTopic(topic, notebookId) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
} from "../utils/date";
|
||||
import Storage from "../database/storage";
|
||||
import Notebooks from "./notebooks";
|
||||
import Note from "../models/note";
|
||||
var tfun = require("transfun/transfun.js").tfun;
|
||||
if (!tfun) {
|
||||
tfun = global.tfun;
|
||||
@@ -36,7 +37,7 @@ export default class Notes {
|
||||
if (!noteArg) return;
|
||||
|
||||
let id = noteArg.id || Date.now().toString() + "_note";
|
||||
let oldNote = this.get(id);
|
||||
let oldNote = this.collection.getItem(id);
|
||||
let note = {
|
||||
...oldNote,
|
||||
...noteArg
|
||||
@@ -77,12 +78,10 @@ export default class Notes {
|
||||
return note.id;
|
||||
}
|
||||
|
||||
async delta(id) {
|
||||
return await this.deltaStorage.read(id + "_delta");
|
||||
}
|
||||
|
||||
get(id) {
|
||||
return this.collection.getItem(id);
|
||||
note(id) {
|
||||
let note = this.collection.getItem(id);
|
||||
if (!note) return undefined;
|
||||
return new Note(this, note);
|
||||
}
|
||||
|
||||
get all() {
|
||||
@@ -162,13 +161,13 @@ export default class Notes {
|
||||
|
||||
async delete(...ids) {
|
||||
for (let id of ids) {
|
||||
let item = this.get(id);
|
||||
if (!id) continue;
|
||||
let item = this.note(id);
|
||||
if (!item) continue;
|
||||
if (item.notebook && item.notebook.id && item.notebook.topic) {
|
||||
await this.collection.transaction(() =>
|
||||
this.notebooks
|
||||
.topics(item.notebook.id)
|
||||
.topic(item.notebook.topic)
|
||||
.notebook(item.notebook.id)
|
||||
.topics.topic(item.notebook.topic)
|
||||
.delete(id)
|
||||
);
|
||||
}
|
||||
@@ -184,83 +183,18 @@ export default class Notes {
|
||||
return this.tagsCollection.all();
|
||||
}
|
||||
|
||||
async tag(id, tag) {
|
||||
let note = await this.get(id);
|
||||
if (!note)
|
||||
throw new Error(`Couldn't add tag. No note found with id: ${id}.`);
|
||||
note.tags.push(tag);
|
||||
await this.tagsCollection.add(tag);
|
||||
await this.collection.addItem(note);
|
||||
}
|
||||
|
||||
async untag(id, tag) {
|
||||
let note = await this.get(id);
|
||||
if (!note)
|
||||
throw new Error(`Couldn't add tag. No note found with id: ${id}.`);
|
||||
if (note.tags.indexOf(tag) <= -1)
|
||||
throw new Error("This note is not tagged by the specified tag.");
|
||||
note.tags.splice(note.tags.indexOf(tag), 1);
|
||||
await this.tagsCollection.remove(tag);
|
||||
await this.collection.addItem(note);
|
||||
}
|
||||
|
||||
async move(to, ...noteIds) {
|
||||
if (!to) throw new Error("The destination notebook cannot be undefined.");
|
||||
if (!to.id || !to.topic)
|
||||
throw new Error(
|
||||
"The destination notebook must contain notebookId and topic."
|
||||
);
|
||||
let topic = this.notebooks.topics(to.id).topic(to.topic);
|
||||
let topic = this.notebooks.notebook(to.id).topics.topic(to.topic);
|
||||
if (!topic) throw new Error("No such topic exists.");
|
||||
await topic.transaction(async () => {
|
||||
await topic.add(...noteIds);
|
||||
});
|
||||
}
|
||||
|
||||
async favorite(id) {
|
||||
await this.add({ id, favorite: true });
|
||||
}
|
||||
|
||||
async unfavorite(id) {
|
||||
await this.add({ id, favorite: false });
|
||||
}
|
||||
|
||||
async pin(id) {
|
||||
await this.add({ id, pinned: true });
|
||||
}
|
||||
|
||||
async unpin(id) {
|
||||
await this.add({ id, pinned: false });
|
||||
}
|
||||
|
||||
async lock(id, password) {
|
||||
let note = await this.get(id);
|
||||
if (!note)
|
||||
throw new Error(`Couldn't lock note. No note found with id: ${id}.`);
|
||||
note.content = await this.collection.indexer.encrypt(
|
||||
password,
|
||||
JSON.stringify(note.content)
|
||||
);
|
||||
note.locked = true;
|
||||
await this.collection.addItem(note);
|
||||
return true;
|
||||
}
|
||||
|
||||
async unlock(id, password, perm = false) {
|
||||
let note = await this.get(id);
|
||||
if (!note)
|
||||
throw new Error(`Couldn't unlock note. No note found with id: ${id}.`);
|
||||
let decrypted = await this.collection.indexer.decrypt(
|
||||
password,
|
||||
note.content
|
||||
);
|
||||
if (perm) {
|
||||
note.locked = false;
|
||||
note.content = JSON.parse(decrypted);
|
||||
await this.collection.addItem(note);
|
||||
}
|
||||
return { ...note, content: JSON.parse(decrypted) };
|
||||
}
|
||||
}
|
||||
|
||||
function isNoteEmpty(note) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Notebooks from "./notebooks";
|
||||
import Notes from "./notes";
|
||||
import Topic from "../models/topic";
|
||||
|
||||
export default class Topics {
|
||||
/**
|
||||
@@ -23,7 +24,7 @@ export default class Topics {
|
||||
}
|
||||
|
||||
get all() {
|
||||
return this.notebooks.get(this.notebookId).topics;
|
||||
return this.notebooks.notebook(this.notebookId).data.topics;
|
||||
}
|
||||
|
||||
topic(topic) {
|
||||
@@ -35,7 +36,9 @@ export default class Topics {
|
||||
}
|
||||
|
||||
async delete(...topics) {
|
||||
let notebook = this.notebooks.get(this.notebookId);
|
||||
let notebook = this.notebooks.notebook(this.notebookId);
|
||||
if (!notebook) return;
|
||||
notebook = notebook.data;
|
||||
for (let topic of topics) {
|
||||
if (!topic) continue;
|
||||
let index = notebook.topics.findIndex(
|
||||
@@ -53,77 +56,3 @@ export default class Topics {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class Topic {
|
||||
/**
|
||||
*
|
||||
* @param {Topics} topics
|
||||
* @param {Object} topic
|
||||
*/
|
||||
constructor(topics, topic) {
|
||||
this.topic = topic;
|
||||
this.topics = topics;
|
||||
this.transactionOpen = false;
|
||||
}
|
||||
|
||||
transaction(ops, saveAfter = true) {
|
||||
this.transactionOpen = true;
|
||||
ops().then(() => {
|
||||
this.transactionOpen = false;
|
||||
});
|
||||
if (!saveAfter) return this;
|
||||
return this.save();
|
||||
}
|
||||
|
||||
has(noteId) {
|
||||
return this.topic.notes.findIndex(n => n === noteId) > -1;
|
||||
}
|
||||
|
||||
async add(...noteIds) {
|
||||
for (let noteId of noteIds) {
|
||||
let note = this.topics.notes.get(noteId);
|
||||
if (this.has(noteId) || !note) return this;
|
||||
|
||||
this.topic.notes.push(noteId);
|
||||
|
||||
if (note.notebook && note.notebook.id && note.notebook.topic) {
|
||||
if (
|
||||
note.notebook.id === this.topics.notebookId &&
|
||||
note.notebook.topic === this.topic.title
|
||||
)
|
||||
return this;
|
||||
await this.topics.notebooks
|
||||
.topics(note.notebook.id)
|
||||
.topic(note.notebook.topic)
|
||||
.delete(note.id);
|
||||
}
|
||||
await this.topics.notes.add({
|
||||
id: noteId,
|
||||
notebook: { id: this.topics.notebookId, topic: this.topic.title }
|
||||
});
|
||||
}
|
||||
return await this.save();
|
||||
}
|
||||
|
||||
async delete(...noteIds) {
|
||||
for (let noteId of noteIds) {
|
||||
if (!this.has(noteId)) return this;
|
||||
let index = this.topic.notes.findIndex(n => n === noteId);
|
||||
this.topic.notes.splice(index, 1);
|
||||
await this.topics.notes.add({
|
||||
id: noteId,
|
||||
notebook: {}
|
||||
});
|
||||
}
|
||||
return await this.save();
|
||||
}
|
||||
|
||||
save() {
|
||||
if (this.transactionOpen) return this;
|
||||
return this.topics.add(this.topic);
|
||||
}
|
||||
|
||||
get all() {
|
||||
return this.topic.notes.map(note => this.topics.notes.get(note));
|
||||
}
|
||||
}
|
||||
|
||||
101
packages/core/models/note.js
Normal file
101
packages/core/models/note.js
Normal file
@@ -0,0 +1,101 @@
|
||||
import Notes from "../collections/notes";
|
||||
|
||||
export default class Note {
|
||||
/**
|
||||
*
|
||||
* @param {Notes} notes
|
||||
* @param {Object} note
|
||||
*/
|
||||
constructor(notes, note) {
|
||||
this.note = note;
|
||||
this.notes = notes;
|
||||
}
|
||||
|
||||
get data() {
|
||||
return this.note;
|
||||
}
|
||||
|
||||
get headline() {
|
||||
return this.note.headline;
|
||||
}
|
||||
|
||||
get title() {
|
||||
return this.note.title;
|
||||
}
|
||||
|
||||
get tags() {
|
||||
return this.note.tags;
|
||||
}
|
||||
|
||||
get id() {
|
||||
return this.note.id;
|
||||
}
|
||||
|
||||
get notebook() {
|
||||
return this.note.notebook;
|
||||
}
|
||||
|
||||
get text() {
|
||||
return this.note.content.text;
|
||||
}
|
||||
|
||||
delta() {
|
||||
return this.notes.deltaStorage.read(this.note.id + "_delta");
|
||||
}
|
||||
|
||||
async tag(tag) {
|
||||
if (this.note.tags.indexOf(tag) > -1)
|
||||
throw new Error("Cannot add a duplicate tag.");
|
||||
this.note.tags.push(tag);
|
||||
await this.notes.tagsCollection.add(tag);
|
||||
await this.notes.collection.addItem(this.note);
|
||||
}
|
||||
|
||||
async untag(tag) {
|
||||
if (this.note.tags.indexOf(tag) <= -1)
|
||||
throw new Error("This note is not tagged by the specified tag.");
|
||||
this.note.tags.splice(this.note.tags.indexOf(tag), 1);
|
||||
await this.notes.tagsCollection.remove(tag);
|
||||
await this.notes.collection.addItem(this.note);
|
||||
}
|
||||
|
||||
async save() {
|
||||
await this.notes.add(this.note);
|
||||
return this;
|
||||
}
|
||||
|
||||
toggle(prop) {
|
||||
this.note[prop] = !this.note[prop];
|
||||
return this.save();
|
||||
}
|
||||
|
||||
favorite() {
|
||||
return this.toggle("favorite");
|
||||
}
|
||||
|
||||
pin() {
|
||||
return this.toggle("pinned");
|
||||
}
|
||||
|
||||
async lock(password) {
|
||||
this.note.content = await this.notes.collection.indexer.encrypt(
|
||||
password,
|
||||
JSON.stringify(this.note.content)
|
||||
);
|
||||
this.note.locked = true;
|
||||
return await this.notes.collection.addItem(this.note);
|
||||
}
|
||||
|
||||
async unlock(password, perm = false) {
|
||||
let decrypted = await this.notes.collection.indexer.decrypt(
|
||||
password,
|
||||
this.note.content
|
||||
);
|
||||
if (perm) {
|
||||
this.note.locked = false;
|
||||
this.note.content = JSON.parse(decrypted);
|
||||
await this.notes.collection.addItem(this.note);
|
||||
}
|
||||
return { ...this.note, content: JSON.parse(decrypted) };
|
||||
}
|
||||
}
|
||||
39
packages/core/models/notebook.js
Normal file
39
packages/core/models/notebook.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import Notebooks from "../collections/notebooks";
|
||||
import Topics from "../collections/topics";
|
||||
|
||||
export default class Notebook {
|
||||
/**
|
||||
*
|
||||
* @param {Notebooks} notebooks
|
||||
* @param {Object} notebook
|
||||
*/
|
||||
constructor(notebooks, notebook) {
|
||||
this.notebook = notebook;
|
||||
this.notebooks = notebooks;
|
||||
}
|
||||
|
||||
get title() {
|
||||
return this.notebook.title;
|
||||
}
|
||||
|
||||
get data() {
|
||||
return this.notebook;
|
||||
}
|
||||
|
||||
get topics() {
|
||||
return new Topics(this.notebooks, this.notebooks.notes, this.notebook.id);
|
||||
}
|
||||
|
||||
toggle(prop) {
|
||||
this.notebook[prop] = !this.notebook[prop];
|
||||
return this.notebooks.add(this.notebook);
|
||||
}
|
||||
|
||||
pin() {
|
||||
return this.toggle("pinned");
|
||||
}
|
||||
|
||||
favorite() {
|
||||
return this.toggle("favorite");
|
||||
}
|
||||
}
|
||||
75
packages/core/models/topic.js
Normal file
75
packages/core/models/topic.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import Topics from "../collections/topics";
|
||||
|
||||
export default class Topic {
|
||||
/**
|
||||
*
|
||||
* @param {Topics} topics
|
||||
* @param {Object} topic
|
||||
*/
|
||||
constructor(topics, topic) {
|
||||
this.topic = topic;
|
||||
this.topics = topics;
|
||||
this.transactionOpen = false;
|
||||
}
|
||||
|
||||
transaction(ops, saveAfter = true) {
|
||||
this.transactionOpen = true;
|
||||
ops().then(() => {
|
||||
this.transactionOpen = false;
|
||||
});
|
||||
if (!saveAfter) return this;
|
||||
return this.save();
|
||||
}
|
||||
|
||||
has(noteId) {
|
||||
return this.topic.notes.findIndex(n => n === noteId) > -1;
|
||||
}
|
||||
|
||||
async add(...noteIds) {
|
||||
for (let noteId of noteIds) {
|
||||
let note = this.topics.notes.note(noteId);
|
||||
if (this.has(noteId) || !note) return this;
|
||||
|
||||
this.topic.notes.push(noteId);
|
||||
|
||||
if (note.notebook && note.notebook.id && note.notebook.topic) {
|
||||
if (
|
||||
note.notebook.id === this.topics.notebookId &&
|
||||
note.notebook.topic === this.topic.title
|
||||
)
|
||||
return this;
|
||||
await this.topics.notebooks
|
||||
.topics(note.notebook.id)
|
||||
.topic(note.notebook.topic)
|
||||
.delete(note.id);
|
||||
}
|
||||
await this.topics.notes.add({
|
||||
id: noteId,
|
||||
notebook: { id: this.topics.notebookId, topic: this.topic.title }
|
||||
});
|
||||
}
|
||||
return await this.save();
|
||||
}
|
||||
|
||||
async delete(...noteIds) {
|
||||
for (let noteId of noteIds) {
|
||||
if (!this.has(noteId)) return this;
|
||||
let index = this.topic.notes.findIndex(n => n === noteId);
|
||||
this.topic.notes.splice(index, 1);
|
||||
await this.topics.notes.add({
|
||||
id: noteId,
|
||||
notebook: {}
|
||||
});
|
||||
}
|
||||
return await this.save();
|
||||
}
|
||||
|
||||
save() {
|
||||
if (this.transactionOpen) return this;
|
||||
return this.topics.add(this.topic);
|
||||
}
|
||||
|
||||
get all() {
|
||||
return this.topic.notes.map(note => this.topics.notes.note(note).note);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user