Skip to content
Draft

Nrw #40

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
157 changes: 146 additions & 11 deletions background.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,160 @@
// add context menu on select
function setupContextMenu(){
/** Helpful type definitions
* @typedef {Object} Note
* @property {string|number} noteID - Unique ID identifying the note
* @property {string} title - Title of the note
* @property {string} content - Content of the note
* @property {Date} createdDate - The date the note was created
* @property {number} folderID - unique ID of the folder
*
* @typedef {Object} Folder
* @property {string} folderName
* @property {number} folderID
*
* @typedef AppData
* @property {Note[]} notes
* @property {number[]} folders
* @property {{theme: number}} settings
*/

/** @type AppData - Stores the app's state */
const appData = {
notes: [],
folders: [],
settings: {
theme: "light"
}
}


// appData.settings.theme

const saveStorage = async () => chrome.storage.local.set(appData);
const getStorage = async () => chrome.storage.local.get(appData);

chrome.runtime.onInstalled.addListener(async () => {
// setup chrome context menus
chrome.contextMenus.create({
id: "addnote",
title: "Add to Harbor",
contexts: ["selection"]
})
}
chrome.runtime.onInstalled.addListener(() => { setupContextMenu() })

// initialize storage
const initAppData = await getStorage();
Object.assign(appData, initAppData);
chrome.storage.local.set(appData);
});

// handle context menu click
chrome.contextMenus.onClicked.addListener((info, tab) => {
console.log(info, tab);
if (info.menuItemId === "addnote") {
console.log(`Adding the note "${info.selectionText}"`);

// we don't need a response, don't bother waiting for one
chrome.runtime.sendMessage({content: info.selectionText});
processCommand({
command: "addNote",
data: { /** @type Note */
title: "",
content: info.selectionText,
createdDate: Date.now(),
folderID: -1
}
});
}
})
});

// open panel onclick
chrome.sidePanel
.setPanelBehavior({ openPanelOnActionClick: true })
.catch((error) => console.error(error))
.catch((error) => console.error(error))

/** Usage
* chrome.runtime.sendMessage({command: "getData"})
* chrome.runtime.sendMessage({command: "addNote", data: {title: "test", content: "hello world"}})
**/
chrome.runtime.onMessage.addListener(processCommand);

/**
* The core event loop for the extension
* @param {{command: string, data?: Object}} message
* @param {chrome.runtime.MessageSender} sender
* @param {(response?: any) => void} sendResponse
*/
function processCommand(message, sender, sendResponse) {
if (message === null || message.command === null) return;
const command = message.command;
const data = message.data;

switch (command) {
case "getData": {
sendResponse(appData);
break;
}
case "getNotes": {
sendResponse(appData.notes);
break;
}
case "getStructure": {
sendResponse(appData.folders);
break;
}
case "getTheme": {
sendResponse(appData.settings.theme);
break;
}

case "setTheme": {
appData.settings.theme = data.theme;
chrome.runtime.sendMessage({command: "setThemeUI", data: {theme: data.theme}});
saveStorage();
break;
}

case "addNote": {
const { title, content, createdDate, folderID } = data;
// you can replace the noteID with whatever you want, as long as it's a unique string/number
let noteObject = {
noteID: (Math.random()+"").slice(2) + (Math.random()+"").slice(2),
title: title || "",
content: content || "",
createdDate: createdDate || Date.now(),
folderID: folderID || -1
}

if (noteObject.title === "" && noteObject.content === "") {
console.error("WARNING, TRYING TO ADD EMPTY NOTE!", noteObject);
return;
}

appData.notes.push(noteObject);
chrome.runtime.sendMessage({command: "addNoteUI", data: noteObject});
saveStorage();
break;
}

case "deleteNote": {
const noteID = data.noteID;

let deletedNoteIndex = appData.notes.findIndex(note => note.noteID === noteID);
console.log(`deleting note index ${deletedNoteIndex}`);
if (deletedNoteIndex !== -1) {
let noteObject = appData.notes.splice(deletedNoteIndex, 1)[0];
chrome.runtime.sendMessage({command: "deleteNoteUI", data: noteObject});
saveStorage();
} else {
console.error(`Trying to delete note ${noteID}, which can't be found`);
}

break;
}

case "deleteAllNotes": {
appData.notes = [];
chrome.runtime.sendMessage({command: "deleteAllNotesUI"});
saveStorage();
break;
}

default: {
sendResponse("I DONT KNOW WHAT YOU WANT ME TO DO");
break;
}
}
}
25 changes: 25 additions & 0 deletions js/_main_.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
(async _ => {
// notes are stored as an object
// key: Date.now()
// value: {content: string, tags: string[], title: string}
// this lets us sort the notes by date, and delete by some ID
let notes = {};

await loadSettings();
await loadNotes();
//insertTag();
//formatBar.append(createFormatBar());

add.addEventListener("click", _ => { addNote(""); });
document.addEventListener("DOMContentLoaded", _ => { reloadNoteHTML(); loadFolders(); });
document.addEventListener("visibilitychange", _ => { saveNotesOrder(); saveFolders(); });

// context menu --> add new note
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
const content = request.content;

// make that new message if it's non-empty
if (content) addNote(content);
});
})()

2 changes: 1 addition & 1 deletion js/formatBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Generates "bottom bar" below note boxes to hold text formating buttons
* @returns {object} bottomBar
*/
function createFormatBar() {
export default function createFormatBar() {
const bottomBar = document.createElement("div");
bottomBar.className = "bottom-bar";

Expand Down
Loading