Quick Add

You can download the plugin in the Plugin Directory page or use Amplecap to duplicate this page


name

Quick Add

icon

Playlist Add

description

A plugin to add information quickly into other notes, without leaving the current note

instructions


WIth this plugin, you can add content to specific notes in your system without leaving the current screen/note. For it, you need to:

Open Quick Open using Ctrl + O

Type one of the commands or the plugin name in the field

Fill out the information you want to add, the format it should have and the home note



Here are the current options you can choose, this list will grow as the plugin gets updated:

Insert content inside a note (Quick Open)

It will open a general alert, follow the previously described steps to use it

The content will be added to the top of the note

Add journal entry to today's jot (Quick Open)

It will open an alert, asking you for the content to add to the current day's jot

Additionally, there's an option to add the current time, only with the current hour and minutes, before the text to be added

The content will be added to the top of the note

Insert time now (Curly brackets)

Inserts the current time to the current note, with the same functionality as the default {now} function, but with a style similar to Logseq and Roam Research

Can be accessed using the curly brackets, for quick access, just type {now and choose the plugin option in the dropdown menu

Publish schedule to Jot (Jots mode)

Publishes all tasks schedule to today in the daily jot

P.S. - It will only get tasks scheduled today that are still incomplete. It won't get overdue tasks from before today, nor completed tasks for today


Known issues:

If you try to insert a task into any note and the text of that task is multi-lined, it will show an error

You need to type "*" after using the Insert time now function to make the time bolded, this happens due to limitations in the insertText function of the API

Changelog

December 28th, 2023

Bugfix: Insert time now now goes back to the original formatting after insertion, instead of keeping the cursor bold

October 5th, 2023

Bugfix: Function Publish schedule to jot button will now appear if note hasn't been created and if the note doesn't have content inside it

September 28th, 2023}

Now the Publish schedule to jotfunction caller only appears if there is no corresponding heading

September 17th, 2023

Hotfix: fixed error that caused the plugin to not work

September 14th, 2023

Calling the Publish schedule to Jot function will now get the tag from the jot it's called from

You can now change the format of the agenda to bullet points, by changing the value of the formatAsBullet constant to true

September 1st, 2023

Features:

New function Publish schedule to Jot (use in Jots mode): Publishes all tasks schedule to today in the daily jot
P.S. - It will only get tasks schedule today that are still incomplete. It won't get overdue tasks from before today, nor completed tasks for today

Bug fixes:

Fixed bug where bullet points wouldn't be added using Insert content inside a note and Add journal entry to today's jot

August 31st, 2023

Bug fixes:

Fixed bug when a daily jot was created, it would throw ReferenceError: day is not defined

Fixed bug where created daily jots would get a wrong suffix

August 17th, 2023

Features:

New function Insert time now: Inserts the current time to the note, similar to {now}, but with a style similar to Logseq and Roam Research

Added specifications to the instructions session

Bug fixes:

Now adding multi-lined tasks will return an error

Calling Add journal entry to today's jot before today's jot was created will automatically create it for you

August 5th, 2023

Published the first version to the public


{
 
constants: {
formatAsBullet: true, // Change to "true" if you want to format your agenda as bullet points
},
/*
* This part only shows calls from the options amd error handling,
* the real implementation happens in the functions
*/
appOption: {
// Inserts text inside a note
"Insert content inside a note": async function (app) {
try {
await this._insertContentPrompt(app);
} catch (err) {
console.log(err);
app.alert(err);
}
},
 
//Creates a journal entry in today's jot
"Add journal entry to today's jot": async function (app) {
try {
await this._addJournalEntry(app);
} catch (err) {
console.log(err);
app.alert(err);
}
},
},
 
insertText: {
//Has the same functionality as the {now} calculation, but with a cleaner look
"Insert time now": async function (app) {
try {
const text = await this._calculateCurrentTime();
const replacedText = await app.context.replaceSelection(`**${text}** | `);
 
if (replacedText) return null;
else return text;
} catch (err) {
console.log(err);
app.alert(err);
}
}
},
 
dailyJotOption: {
"Publish schedule to Jot": {
run: async function (app, noteHandle) {
try {
console.log(noteHandle);
 
//Verify if note exists, if not, create a new note
let note = await app.findNote({ name: noteHandle.name, tags: noteHandle.tags});
 
if (!note) {
const uuid = await app.createNote(noteHandle.name, noteHandle.tags);
note = await app.findNote({ uuid: uuid});
}
 
console.log(note);
 
await this._publishSchedule(app, note.uuid);
} catch (err) {
console.log(err);
app.alert(err);
}
},
 
check: async function(app, noteHandle) {
try {
const note = await app.findNote({ name: noteHandle.name, tags: noteHandle.tags});
const sections = await app.getNoteSections({ uuid: note.uuid })
 
console.log(sections);
 
if (sections[0].heading.text == 'Agenda') return false;
return true;
 
} catch(err) {
console.log('The first section is null, showing the button anyway');
return true
}
}
}
},
 
 
/**
* Opens a prompt to add content inside the note
*/
async _insertContentPrompt(app) {
console.log("Starting insertContentPrompt...");
const noteHandles = await app.filterNotes();
 
//Main alert option
const result = await app.prompt("Insert content inside a note", {
inputs: [
{ label: "Text to add", type: "text" },
{
label: "Format as", type: "select", options: [
{ label: "Plain text", value: "plain" },
{ label: "Bullet point", value: "bullet" },
{ label: "Task", value: "task" },
]
},
{ label: "Select a note", type: "note", options: noteHandles }
]
})
 
//Adds the text inside the note
const [text, textFormat, noteResult] = result; //Destructures result array to get all of the prompt inputs
 
console.log("Calling _insertContent function");
await this._insertContent(app, text, textFormat, noteResult.uuid);
console.log("Content added successfully!");
app.alert("Content added successfully!");
},
 
//Adds a journal entry to today's jot
async _addJournalEntry(app) {
console.log("Starting addJournalEntry function...");
 
const todayTimestamp = Math.floor(Date.now() / 1000);
let dailyJot = await app.notes.dailyJot(todayTimestamp);
dailyJot = dailyJot.uuid;
 
//If today's jot doesn't exist, create a new daily jot
if (dailyJot == null) {
console.log("No Daily Jot for today, creating a new jot...");
dailyJot = await this._createDailyJot(app);
}
 
//Main prompt
const result = await app.prompt("Add journal entry to today's jot", {
inputs: [
{ label: "Text to add", type: "text" },
{ label: "Add current time before the text", type: "checkbox" },
]
})
 
const [text, timeStampCheckbox] = result; //Destructuring result array to get all of the prompt inputs
 
//Calculates the current time if the user marks the checkbox and adds to the text variable
if (timeStampCheckbox) {
const loggedText = "**" + await this._calculateCurrentTime() + "** | " + text;
 
await this._insertContent(app, loggedText, "bullet", dailyJot);
} else await this._insertContent(app, text, "bullet", dailyJot);
},
 
/**
* Calculates and returns the current time in the 24 hour format
* @return "markdown" of the current hour and minute as a String
*/
async _calculateCurrentTime() {
console.log("Calculating current time...");
 
const date = new Date();
date.setTime(Date.now());
let minutes = date.getMinutes();
 
if (minutes < 10) minutes = '0' + minutes.toString(); //Pads the minutes with a 0 if it's smaller than 10
 
const logTime = date.getHours() + ":" + minutes;
 
console.log("Current time logged:" + logTime);
 
return logTime;
},
 
/**
* Creates a new daily jot note
* @return String of the newly created jot's UUID
*/
async _createDailyJot(app) {
const dt = new Date();
const options = { month: 'long', day: 'numeric', year: 'numeric' }
 
//Calculates the cardinal suffix
let suffix;
 
if (dt.getDate() > 3 && dt.getDate() < 21) suffix = 'th';
else {
switch (dt.getDate() % 10) {
case 1: suffix = 'st'; break;
case 2: suffix = 'nd'; break;
case 2: suffix = 'rd'; break;
case 3: suffix = 'th'; break;
}
}
 
let today = dt.toLocaleDateString('en', options);
 
today = today.split(',');
 
today[0] += suffix;
 
today = today.join();
 
 
return await app.createNote(today, ['daily-jots']);
 
},
 
/**
* Publishes the current day's schedule to the daily jot
* @param {*} app
* @param {String} noteUIID
*/
async _publishSchedule(app, noteUUID) {
console.log("Starting publish schedule function...");
 
const noteHandles = await app.filterNotes({ group: 'taskLists' });
 
console.log("Filtering notes for tasks due today...");
console.log(`Total notes to filter: ${noteHandles.length}`);
 
const taskArray = await Promise.all(noteHandles.map(async note => {
return await this._getTasksDueToday(app, note.uuid);
}))
 
const filteredArray = taskArray.filter(el => el.length !== 0);
 
console.log('Tasks filtered successfully!');
 
let todayTasks = [];
 
filteredArray.forEach(array => {
todayTasks = todayTasks.concat(array);
})
 
todayTasks.sort((a, b) => a.startTime - b.startTime);
 
console.log('Sorting tasks by startTime and transforming it into AM/PM format');
 
todayTasks.map(task => {
const timeFormat = { hour: 'numeric', minute: '2-digit'};
task.startTime = new Date(task.startTime * 1000).toLocaleTimeString('en-US', timeFormat);
})
 
console.log(todayTasks);
 
console.log('Printing tasks to todays jot...');
 
console.log(noteUUID);
 
await Promise.all(todayTasks.reverse().map(async task => {
const text = '**' + task.startTime + '** ' + task.content;
const format = (this.constants.formatAsBullet) ? 'bullet' : 'task';
 
await this._insertContent(app, text, format, noteUUID);
}));
await this._insertContent(app, '# Agenda\n', null, noteUUID);
},
 
async _getTasksDueToday(app, noteUUID) {
const taskList = await app.getNoteTasks({ uuid: noteUUID });
const dateFormat = { month: 'long', day: 'numeric', year: 'numeric' };
 
let tasksDueToday = taskList.filter(task => {
 
//Verifies if the start date of the task is the same as
const todayDate = new Date().toLocaleDateString(dateFormat);
const startDate = new Date((task.startAt * 1000)).toLocaleDateString(dateFormat);
 
if (todayDate !== startDate) {
return false
}
return task;
});
 
tasksDueToday = tasksDueToday.map(task => {
const timeFormat = { hour: 'numeric', minute: '2-digit', hour12: true };
const obj = {
content: task.content,
startTime: task.startAt
}
return obj;
})
 
return tasksDueToday;
},
 
/**
* General function to insert content inside the note
* @param {*} app
* @param {String} text
* @param {String} textFormat - Formatting type of the text
* @param {String} noteUUID
* @returns void
*/
async _insertContent(app, text, textFormat, noteUUID) {
/**
* For some reason, the plugin API doesn't like it when you use the filterNotes function,
* making it throw exceptions when you directly use a note filtered from it.
* To circumvent this, use app.notes.find(noteHandle.uuid)
*/
 
console.log("Starting insertContent function...");
 
const note = await app.notes.find(noteUUID);
console.log("text format:" + textFormat)
console.log(`Text to add: ${text}\nNote to add: ${note.name}`);
 
if (textFormat === "bullet") text = "- " + text;
if (textFormat === "task") {
await note.insertTask({ content: text });
} else await note.insertContent(text); //This will work, even when textFormat comes as null
 
console.log("Content added successfully!");
},
}