A glance is not a reading
I added a little badge to the PopsicleBoat sidebar recently. It says something like All Posts · 13, and up top there’s a list of what those 13 things are. I built it because I kept losing track of my own new posts. If the guy who made the site can’t find the new stuff, nobody else has a chance.
The badge itself was easy. The hard part was one word: new. Took me three tries to get it right.
1 - The obvious idea. New means posted since you last visited. So you give each user a timestamp, stamp it when they open the board, and anything after that is new. Databases love this. It’s one column and one comparison, and it’s basically how half the software you use decides what to bold.
Then I actually used it. I opened the board, clicked the first new post, read it, came back, and the whole list was gone. All thirteen. The badge still said 13 but the list under it was empty. Turns out opening the board had stamped my timestamp, so by the time I came back nothing was “since your last visit” anymore. I read one post and the system decided I’d seen all thirteen.
That’s kind of funny when you look at it. Just showing up counted as reading everything.
2 - Next, sessions. Don’t let one visit wipe the list, hold it steady while you’re actually around and only move it forward after you’ve been gone a while. And it worked, sort of. The list survived a click and a return now. But then I opened a post, read it, came back, and the badge still said 13. And the post I just read was sitting right there in the list, still marked new, staring at me.
Of course it was. I’d made the line move a little more politely but “new” was still about time. The system knew when I was on the board, it just had no idea what I actually read. Both versions had the same problem underneath: they watched the clock when they should have been watching the posts.
3 - The one that stuck. A read is a fact about you and one post. Nothing more. So I made a little join table (this user read this post) and write a row the moment you open a thread. And suddenly everything just works. Open a post and the badge ticks down by one, right away. Go back to the board and that post is gone from the list, but the other twelve are still there waiting. Nothing you didn’t open gets checked off for you. I kept the old timestamp too, but only as a floor, so posts from before the feature even existed don’t clog up the count.
I also added a Mark all as read button, because every inbox turns into a chore eventually and sometimes you just want to wave the whole pile away. That one’s honest too. It’s you saying you’re done with them, not the system guessing because you happened to show up.
The thing that gets me looking back is that I already knew the right answer. Not as a programmer, as a user. Every notification thing that’s ever annoyed me annoyed me for this exact reason. They all confused me being there with me paying attention. I just never bothered to think about it for popsicleboat until during testing a badge refused to count down twice in a row.
Also, currently I’m basically the only user so I have to stress test it myself. I forgive me for missing it before. But, it’s fixed now!