Automatically update frontmatter with Pomodoros

Things I have tried

Hi there,

I’m using the “Status Bar Pomodoro Timer” plugin, which writes the pomodoros I’ve done into a “Pomodoros.md” file in the following format:

:tomato: 11.02.2023 16:05
:tomato: 11.02.2023 16:35
:tomato: 12.02.2023 16:19

I want track my daily pomodoros in my daily note. The current workflow I follow is to use DataviewJS to calculate the pomodoros:

const page = dv.page("Pomodoros.md")
const pageContent = await dv.io.load(page.file.path) 
let indices = [];
let i = -1;
while ((i = pageContent.indexOf("🍅", i + 1)) >= 0) {
	indices.push(i)
}
let dates = [];
for (const idx of indices) {
	dates.push(pageContent.substring(idx + 2, idx + 13).trim())
}
let pomodorosToday = 0;
const currentDate = dv.current().file.name;
for (const date of dates) {
	if (date == currentDate) {
		pomodorosToday++;
	}
}
dv.paragraph("Pomodoros: " + pomodorosToday)

And afterwards put them manually in the frontmatter.

What I’m trying to do

Is there a (better) way to automate this?

Thank you!

I found a shorter, whether it’s better depends on the eyes that sees, but try the following:

```dataviewjs
const page = dv.page("Pomodoros.md")
const pageContent = await dv.io.load(page.file.path)
const currentDate = dv.current().file.name

const pomodoroCount = pageContent.split("\n")
  .filter( f => f.indexOf("🍅") >= 0 )
  .filter( f => f.substring(3, 13) === currentDate )
  .length

dv.paragraph("Pomodoros: " + pomodoroCount)
```

I utilise the possibility to filter out elements in a daisy chain. So it starts with all lines in the file, keeps only those having the tomato, and then only keeps lines having the correct date (in the correct place), and then take the length of this list, aka the pomodoroCount.

Thats, at least in my opinion, definitely a better way to achieve this! Thank you!

But I think I didn’t make myself clear enough in my initial post. I’m looking for a way to automatically update the frontmatter with the Pomodoros I’ve done today, without having to copy and paste to the frontmatter.

Ah… Read that, and forgot about it. This is sketchy stuff, as we might very well end up with some race conditions, but the following seems to work somewhat reliably:

```dataviewjs
const page = dv.page("Pomodoros.md")
const pageContent = await dv.io.load(page.file.path)
const currentDate = dv.current().file.name

const pomodoroCount = pageContent.split("\n")
  .filter( f => f.indexOf("🍅") >= 0 )
  .filter( f => f.substring(3, 13) === currentDate )
  .length

await setTimeout( async () => {

  const tFile = app.vault
    .getAbstractFileByPath(dv.current().file.path)
  
  await app.fileManager.processFrontMatter(
    tFile, 
    (fm) => fm["Pomodoros"] = pomodoroCount
  )}, 2000)
```

What happens here, is that it calculates the stuff, as before, but then it sets a timeout to execute a change to the frontmatter after 2000 milliseconds, aka 2 seconds. If it doesn’t work, you might need to change that factor up (or down) a little.

Disclaimer: I’m not sure how reliable this is when running live preview, or doing other changes almost at the same time. I don’t think it should be harmful, but I do feel like the need to mention this is kind of sketchy, so use at own risk.

1 Like

Thank you very much! This is exactly what I was looking for! I will definitely give it a try.

Have a great day! :slightly_smiling_face:

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.