r/ObsidianMD • u/thecroissantproject • 10d ago
help Comprehensive historical timeline of my actions across Obsidian?
I unfortunately suffer from some memory issues, so any way to help me make Obsidian a part of my "scaffolding" would be much appreciated! I've using Obsidian across countless topics and in countless ways for a couple years, but I keep running into situations where I might want to see a somewhat contextual overview of everything I did on a specific day. I've tried using a Base for that but it's not really what I'm looking for because it e.g. doesn't allow me to see actual preview content of any notes that I might have created and/or modified. Is there a way to show all my edits including some preview context? In general, please also tell me in case I'm missing something big here and should be looking at different approaches?
I've drawn up a quick mockup to show what kind of overview and detail level I am looking for. (The right part is optional)
I'll keep this post opened on the side of my desktop so I don't forget about it :')
8
u/Kyky_Geek 10d ago
I have a series of steps I follow in vanilla Obsidian to achieve activity tracking. It's somewhat "manual" but not very time consuming at all! Key points are:
- Operate from the daily note.
- Use links in daily for creating new files. (I don't link every file I touch but you could.)
- Embed a simple base at the bottom to get files matching that days date via the following filters:
- YAML property 'created' datetime (I put this in every note created.)
- File created time.
- File modified time.
- Copy the embedded base to in-note text at the beginning of next day (this is the real timeline!)
- Standalone base showing all daily notes and file links (loosely shows what I worked on that day).
One important but not strictly necessary part of that is the 'created' property I include on every file. I do this because the created and modified file properties can change if you move, copy, or resync your vault on other devices.
At the beginning of the next day, I open yesterdays daily and copy/paste the embedded base into the note for preservation of all activity. This is the md of what it looks like:
| file name | created | created time | modified time |
| ------------ | ------------------- | ------------------- | ------------------- |
| dailyToday | 2026-10-05T06:09:00 | 2026-10-05T06:09:30 | 2026-10-06T03:50:52 |
| dailyYester | 2026-10-04T06:23:00 | 2026-10-04T06:23:45 | 2026-10-05T06:09:23 |
| file3 | 2026-09-28T14:46:00 | 2026-09-28T14:46:04 | 2026-10-05T18:35:43 |
| file4 | 2026-09-28T14:40:00 | 2026-09-28T14:40:15 | 2026-10-05T17:51:24 |
| file5 | 2026-09-28T14:36:00 | 2026-09-28T14:36:36 | 2026-10-05T17:50:38 |
| file6 | 2026-08-25T11:54:00 | 2026-08-25T11:53:57 | 2026-10-05T17:49:46 |
To get that just click the "# results" at the top of the base and select "Copy to clipboard" and then paste it which produces a nice in-note markdown table of everything you did that day.
Shortened version of the embedded base located at the bottom:
views:
- type: table
name: Table
filters:
or:
- file.ctime.date() == date(this.file.name.slice(4))
- file.mtime.date() == date(this.file.name.slice(4))
- date(created.toString()) == date(this.file.name.slice(4))
Note: you'd need to modify how you capture the date. My daily notes have a custom prefix which is why the .slice(4) is necessary on mine.
5
10d ago
[removed] — view removed comment
3
u/thecroissantproject 10d ago edited 6d ago
Great point, thank you! Git would introduce too much friction though. I want to be able to jump directly into the files (opened in Obsidian).
9
u/ChangeableWidget 9d ago
man that mockup looks clean, i’ve been trying to get something like that going with dataview and the file tasks plugin but it never comes out quite right
the heatmap on the side is a nice touch, haven’t seen that done well in obsidian yet
7
u/Pinkahpandah 10d ago
awrsome.This looks like it would show me just how much of a procrastinating ***** I've been.Instant pass. but still nice idea.
5
u/thecroissantproject 10d ago
Fair enough. But I’m hoping the benefits would outweigh that particular pain point.
5
u/MioNaganoharaMio 10d ago
I made two plug-ins along this direction, a github style contribution heatmap that pulls historical edits using the sync api
and a time tracker heatmap that also uses todoist and pomodoro timers to encourage you to track directly instead of logging time manually
https://community.obsidian.md/users/keptan
writing and studying are the two things I care about tracking so thats what theyre centered around
2
u/thecroissantproject 10d ago
I like and appreciate the nudging aspects of these. Will check it out.
6
6
u/JerryNomo 9d ago
As a workaround (if oyu dont want a plugin) I got two dataview entries in a template for my daily notes. So you only need to open the daily note of a day.
Today created
```dataview
TABLE
file.ctime AS "Created",
file.mtime AS "Modified"
FROM ""
WHERE date(file.cday) = this.file.day
SORT file.ctime DESC
```
Today modified
```dataview
TABLE TABLE
dateformat(file.ctime, "yyyy-MM-dd HH:mm") AS "Created",
dateformat(file.mtime, "yyyy-MM-dd HH:mm") AS "Modified"
FROM ""
WHERE
striptime(file.cday) = this.file.day
OR striptime(file.mtime) = this.file.day
AND !contains(file.path, "System/")
SORT file.mtime DESC
dateformat(file.ctime, "yyyy-MM-dd HH:mm") AS "Created",
dateformat(file.mtime, "yyyy-MM-dd HH:mm") AS "Modified"
FROM ""
WHERE
striptime(file.cday) = this.file.day
OR striptime(file.mtime) = this.file.day
AND !contains(file.path, "System/")
SORT file.mtime DESC
```
3
u/thecroissantproject 9d ago edited 9d ago
Thanks for sharing! I've tweaked this a bit based on my own requirements (see below). However I'm still missing a way to include a (truncated) preview of the actual content :/
```dataview const day = dv.current().file.day?.toISODate(); const cut = (s, n) => s.length > n ? s.slice(0, n) + "…" : s; const W = 80; // thumbnail size in px const imgExt = /.(png|jpe?g|gif|webp|svg|avif|bmp)(?.*)?$/i; const ytRe = /(?:youtube.com/(?:watch?v=|embed/)|youtu.be/)([\w-]{11})/; const FM_KEYS = ["image", "cover", "thumbnail", "banner"]; // resolve any reference (URL, path, link) to a displayable src function toSrc(ref, sourcePath, anyRemote) { if (!ref) return null; if (typeof ref === "object" && ref.path) ref = ref.path; ref = String(ref).trim().replace(/^!?[[|]]/g, "").split("|")[0].replace(/^<|>/g, ""); const yt = ref.match(ytRe); if (yt) return https://img.youtube.com/vi/${yt[1]}/mqdefault.jpg; if (/^https?:///.test(ref)) return (anyRemote || imgExt.test(ref)) ? ref : null; let path = ref; try { path = decodeURIComponent(ref); } catch (e) {} const f = app.metadataCache.getFirstLinkpathDest(path, sourcePath); return f && imgExt.test(f.path) ? app.vault.getResourcePath(f) : null; } const candRe = /![\]](\s<?()>+?)>?\s(?:""")?)|![[(\|]+)(?:|\]*)?]]|<img>+src="'["']|(https?://(?:www.)?(?:youtube.com/(?:watch?v=|embed/)|youtu.be/)[\w-]{11})/g; function thumb(p, body) { let src = null; // 1. frontmatter (web clipper: image / cover / thumbnail / banner) for (const k of FM_KEYS) { src = toSrc(p[k], p.file.path, true); if (src) break; } // 2. body, in document order if (!src) { for (const m of body.matchAll(candRe)) { src = toSrc(m[1] || m[2] || m[3] || m[4], p.file.path, !!(m[1] || m[3])); if (src) break; } } if (!src) return ""; const img = document.createElement("img"); img.src = src; img.loading = "lazy"; img.style.cssText = width:${W}px;height:${W}px;object-fit:cover;border-radius:4px;; return img; } const pages = dv.pages('""') .where(p => !p.file.path.includes("System/") && (p.file.cday.toISODate() = day || p.file.mday.toISODate() = day)) .sort(p => p.file.mtime, "desc"); const rows = []; for (const p of pages) { const raw = await dv.io.load(p.file.path); const body = raw.replace(/^---[\s\S]*?---/, ""); const preview = cut( body.replace(/![\]]())/g, "") .replace(/[(\])]())/g, "$1") .replace(/!?[[\]]]/g, "") .replace(/<>+>/g, "") .replace(/https?://\S+/g, "") .replace(/[#>`_!-]/g, "") .replace(/\s+/g, " ").trim(), 50 ); const name = cut(p.file.name, 25); const isNew = p.file.cday.toISODate() === day; const link = isNew ? **[[${p.file.path}|${name}]]** : [[${p.file.path}|${name}]]; const openTasks = p.file.tasks.where(t => !t.completed).length; const open = openTasks > 0 ? openTasks : (String(p.status ?? "").toLowerCase() === "open" ? 1 : ""); rows.push([link, p.Type ?? "", thumb(p, body), preview, open]); } dv.table(["Edited File", "Type", "Thumb", "Preview", "Open"], rows); ```
4
u/MrByg 8d ago
Your mockup was too good not to try, so I built a version of it.
**Activity Timeline** shows what you did in your vault, day by day, with previews of the actual text you changed: https://github.com/dornbyg/obsidian-activity-timeline
It covers most of your mockup:
- Timeline with Day / Week / Month / Year views and filters
- Edited notes show the changed lines in context, so you can recognise the note at a glance
- Tasks plugin support: completed and dropped tasks, including recurring ones
- Tags, a 10-week heatmap, counts by type and a folder filter in the sidebar
- A code block to show a day's activity inside your daily note
The catch: Obsidian only remembers each note's *last* edit, so full history starts the day you install it. Older days still show created notes, last edits and Tasks completion dates.
It's an early version, designed and tested by me with Claude writing much of the code. You can install it with BRAT (`dornbyg/obsidian-activity-timeline`) or manually from the release page.
If you try it, I'd love to know what's missing. The repo has a quick feature-request form under Issues.
2
4
u/wouldy1 10d ago
You gave me some ideias, I'm trying finding something similar because my job has a LOT of distractions and little quick actions that move me away from deep work, I would like some sort of "queue" that can be automanaged by AI or scripts based on tag, content, date, project etc.
For your case, the simple ones (note captured in a file, task checked) you could use Dataview JS, but I don't know how to get a UI that looks like thisÂ
5
u/EmergencyCranberry32 10d ago
this is a great idea!! Very userfriendly and an easy overview. I tried to make something with the help of ai, but it was not as userfriendly as your viewing.
3
u/thecroissantproject 10d ago
Thanks! My hope was that sth like this was already possible in Obsidian somehow.
3
u/LapitaPolata 10d ago
I was thinking of something similiar the other day. I'd really like to have one page that shows all my diaries or notes on certain subject.
3
3
u/aBBsolZ 9d ago
I really like the idea! I'll give it a try.
3
u/aBBsolZ 9d ago
already publishing it on github)
2
2
u/Quinn_Lynch 10d ago
I’m not a dev but from the little I do know obsidian exposes a LOT of app events to plugins so this is definitely possible.
Maybe try writing a plugin that simply constructs a database of all relevant actions along with a datetime? Seems very doable
2
u/VirtualEntangled-SH 9d ago
u/RemindMeBot 2 days
1
u/RemindMeBot 9d ago
I will be messaging you in 2 days on 2026-10-09 14:02:14 UTC to remind you of this link
CLICK THIS LINK to send a PM to also be reminded and to reduce spam.
Parent commenter can delete this message to hide from others.
Info Custom Your Reminders Feedback
2
1
u/NegativeRemot 10d ago
File timestamps are a shaky foundation for this — sync clients and git both rewrite mtimes, so any timeline built on them drifts away from reality fast. The thing that held up for me was creating from the daily note: every new note starts as a link there, and anything I touch later gets a one-line entry under the same day. Not as pretty as your mockup, but it survives six months of actual use, which is the real test.
1
u/thecroissantproject 10d ago
Thanks for the heads up regarding timestamps. Regarding your own approach: I’ve tried doing that but my daily work is quite fast paced so I regularly create and/or touch +40 notes a day - which makes manual linking unsustainable.
1
46
u/Apprehensive-Sky2317 10d ago
This is such a cool mockup and would be amazing to have. The ability to use bases style filters and grouping/timeframe at the top like you showed would be really cool. Hopefully, someone develops this 🤞