Automated Spaced repetition schedule with Dataview/Dataviewjs + Metadata Menu

I created an automated spaced repetition schedule using Dataview and Dataviewjs + Metadata Menu. It shows the level you are at, last reviewed date and based on those parameters when you need to review it next.

YAML

Level:: πŸŸ₯  / *I am using the emojis for level metadata.*/
LastReview:: 2023-07-27

With Dataview

Table
Level,
LastReview as "Reviewed On",
choice(
	Level= "🟧", date(LastReview) + dur(3 day), choice(
	Level= "🟨", date(LastReview) + dur(7 day), choice(
	Level= "🟩", date(LastReview) + dur(14 day), choice(
	Level= "πŸŸͺ", date(LastReview) + dur(30 day), choice(
	Level= "🟦", date(LastReview) + dur(20 day), choice(
	Level= "πŸ…", date(LastReview) + dur(45 day), choice(
	Level= "πŸŽ–οΈ", date(LastReview) + dur(60 day), choice(
	Level= "🌟", date(LastReview) + dur(75 day), choice(
	Level= "πŸ†", date(LastReview) + dur(90 day), date(LastReview) + dur(1 day))))))))) 
) as Next-review
from "Test Folder/Test Notes"

This should result in something like this

With Dataviewjs

I have been using the above code for quite long. It has served me quite well. But recently I got to know about Metadata menu plugin. Its ability to make the dataview table interactive and change metadata from the table itself is quite amazing. Following code will give the same result as above but uses javascript as the plugin can be implemented in dataviewjs only.

dataviewjs
const {fieldModifier: f} = this.app.plugins.plugins["metadata-menu"].api 
 /*for using Metadata Menu plugin*/

/* function to determine next review date*/
function nextreview(rev, last){
	let next;
	if(rev == "πŸŽ–οΈ"){
		next = moment(dv.date(last) + dv.duration('60 days')).format('MMM Do YYYY');
		}
	else if(rev == "🟩"){
		next = moment(dv.date(last) + dv.duration('14 days')).format('MMM Do YYYY');
		}
	else if(rev == "🟦"){
		next = moment(dv.date(last) + dv.duration('20 days')).format('MMM Do YYYY');
		}
	return next;
}
dv.table(
	["Notes", "Level", "Last Reviewed On", "Next Review"],
dv.pages('"Test Folder/Test Notes"').map(p => [
	p.file.link,
	f(dv, p, "Level"), /*pass dv (dataview api instance), p (the page), and the field name to fieldModifier (: "f")*/
	p.LastReview,
	nextreview(p.Level, p.LastReview)
])
)

Here I have made the β€œLevel” metadata interactive.
This should result in something like this

4 Likes

Thanks for sharing,
can someone help me add a β€œsort” function for the Next review session?
Thanks

@digvj you can simplify your nextreview function by defining an object that relates emojis to times, and then using that to turn the rev value into a time:

function nextreview (rev, last) {
  const schedule = {
    'πŸŽ–': 60,
    '🟦': 20,
    '🟩': 14
  }
  return moment(dv.date(last) + dv.duration(schedule[rev] + ' days')).format('MMM Do YYYY');
}

The incoming rev value (which is an emoji) is used as a key in the schedule object like this: schedule[rev], which will return the time value.