Jason Leow

Indie hacker, solopreneur | Creating a diverse portfolio of products + services.

🚀 Launched basic notifications

FINALLY launched the highly-requested feature on Lifelog - notifications! It's just basic notifications for now - you get a notif when someone comments on your post. No @mentions, no notifs for comments you made on someone else's post...yet. Soon to come!

I must admit, this took me quite a while to figure out and get right. My initial idea of the solution was 10x more complex (involving web sockets, lifecycle hooks etc) than the simple one now which just uses a dumb CRUD API endpoint. But actual implementing and integrating both backend and frontend inflated the complexity back up again! Never had to make so many different components, pages talk to each other in realtime this way. Phew! So glad it's finally out!

Big shout-out to @yuyu helping me with the nitty gritty frontend stuff on Nuxt.js! Drinks on me next time! 🍻🍻🍻
Ilya Radchenko

I'm using EmberJS and no backend at this point. Using Firebase and isomorphic-git with the Github API, so far haven't needed a backend.

0 Likes
Jason Leow Author

Oh just checked out screenshots of Typelog… very nice! Love the dev focus, and ease of use, like a better alternative to Github Pages blogs. What's your stack on backend and frontend?

0 Likes

Added avatar img and username to notifications

Added robovatar img, and was lazy to add another column to db for the commentAuthor.username so used regex instead to extract first word out from body text (but might break if I change the phrasing structure of the body text in future).

{{ notif.body.replace(/ .*/, '') }}

Ref: https://stackoverflow.com/a/46999443

UPDATE: the regex did break the notif text body. Text was rendering weirdly in the username part of the notif. Changed to using a split() function.

{{ notif.body.split(' ')[0] }}

Ref: https://stackoverflow.com/a/19503397

😓 Changed db column name of users_permissions_user and added new commentAuthor column in notif table, and updated/added new fields to frontend

Changing anything about databases always stresses me out, don't know why...

FINALLY! Solved the read/unread styling issue for notifications ALL THANKS TO @yuyu 🍻🍻🍻

Added v-bind:class and watcher to update the style of read/unread notifs upon clicking.
Jason Leow Author

Cheers bro 🍻

0 Likes
Yuyu

Congrats 🍻

0 Likes

Day 27 - Just paywall it https://golifelog.com/posts/just-paywall-it-1611740640911

"...I noticed other product categories emerging on stuff which we probably considered too small or insignificant to paywall, like selling your Notion templates for managing your newsletters, selling tiny e-books and docs on Gumroad, selling access to view an Airtable full of resources.

In other words, if you can paywall, you can sell it. Anything. Everything. Having a sellable product no longer needs to conform to the image of a traditional product—be it digital or physical—with a high barrier to entry in terms of material substance, packaging, marketing, capital. "

😖 Got styling to work on :visited notifications after some pain, but realised I can't use it 😩

For security, browsers restrict styling of `a:visited`. On top of that, :visited doesn't work on nuxt-link. Was painful to debug as these 2 aspects just fail without errors. Finally managed to get it to work by switching nuxt-link to anchor tags with :href, but realised I can't use it because the :visited stylings will apply to same URL route, but the counter is based on database attribute. Back to the drawing board....

🎰🎰🎰🎰🎰🎰🎰 Lucky day! 🔥777 day streak

L U C K

0 Likes
Jason Leow Author

🍀🍀🍀🍀🍀🍀🍀

0 Likes

Added ability to use a method from another component in a page, to update the notif counter on Navbar component when on notif page

mounted() {
// to allow fetchNotifsCount() to be called from another page/component
this.$root.$on('fetchNotifsCount', () => {
this.fetchNotifsCount()
})
},

In the target page, use `this.$root.$emit('fetchNotifsCount')`


Ref:
https://stackoverflow.com/questions/53728386/vue-call-method-of-another-component

Solved the tricky issue of updating the read status of the notification

I wanted to update the read status of a notification upon clicking on it, by sending a PUT request on click. But a simple function using `@click` on a nuxt-link refused to work. Turned out, it's unique to nuxt-link &/or vue-router, that I need to access the native event in the browser instead of the Vue event, using `@click.native`. I would have NEVER found this if @yuyu had not pointed it out! So thank you bro!

Day 26 - Focus on energy https://golifelog.com/posts/focus-on-energy-1611650597671

"...from the trifecta of sleep, food and exercise, to the singularity that is energy, where sleep, food and exercise become ways to provide, restore and expand energy respectively."

Day 25 - The trifecta of sleep, food & exercise https://golifelog.com/posts/the-trifecta-of-sleep-food-and-exercise-1611568673199

🛌🥩🏋🏻‍♀️ "...If I can do these three things well, I’ll be unstoppable."

Just got my first organic customer (who's not a direct friend nor ex-200wordsaday alumni) on a $10/m monthly subscription! Thanks @Via_Benjamin for taking the leap to try

📈 Total one-off revenue: $600
📊 MRR: $40

💪 Yes!! Got basic comment notification system working on local, without annoying notifications to self when user comments on own post

Integrated API endpoints into frontend by making the form submission send 2 `POST` requests, one to create the comment and the other to create the notification. No lifecycle hooks/methods needed, just a plain ol' POST request! Didn't know why I couldn't see this before and went down the rabbit hole of over-thinking and complexity...

Managed to add an if statement to prevent user from sending comment notifications to self:

`if (this.post.author.username !== this.$auth.user.username) { ... }`

Next up: how to reduce notif count on click event of each notification.

Day 24 - Following a plan vs your curiosity https://golifelog.com/posts/following-a-plan-vs-your-curiosity-1611476451985

"...Can one approach ‘normal’ work as an artist or wanderer does? 80% spontaneity, 20% structure? I wonder if these categories are in fact getting in the way. Because as the tweet eludes, curiosity leads to flow, flow leads to deep work, and deep work is, in fact, the ultimate form of productivity. It’s the best of both worlds. But flow cannot be forced nor planned nor structured into existence. It has to be allowed to happen. Like gardening. You till the soil, add fertilizers, allow just the right amount of water and light, and let the plant do the rest. You can’t force the plant to grow, but we can create the conditions for it to thrive. Same with flow. Perhaps that’s then the intricate dance of structure and spontaneity.

Structure to steward just the right conditions on the outside, but relinquishing all control beyond that. Everything else is left to spontaneity to sprout.

The plan to follow is to follow curiosity."

Made rudimentary first version of Notifications system in frontend

Added Notifications counter on Navbar, added a notifications-page.vue, listed out all notifications using v-for, nuxt-link them all using v-bind:to their respective urls.

Next up, to count all the user’s notifications with Read:false and display a badge with the count in frontend. When user clicks on a notifications you make a call to API and set Read: true, if the call was successful then you subtract -1 from counts.

Created API endpoints for notification system

Created a collection type called Notifications, with fields: type [Enumeration: Mention, Reply], relation with User [User has many Notifications], read [Boolean], body [Text], url [Text].

Day 23 - Minimize productivity, maximize optionality https://golifelog.com/posts/minimize-productivity-maximize-optionality-1611391257935

"Is trying to maximize productivity actually—in effect—achieving the opposite?"

Day 22 - Apply code directly to where it hurts https://golifelog.com/posts/apply-code-directly-to-where-it-hurts-1611306118454

"......The irony was how hard I fought against coding in the initial days. But now it’s like a balm. Ahhhh. Apply code directly where it hurts."

😴 Added lazy loading for posts on home page feed

Optimize page load performance for home page by lazy loading the posts feed. Currently it loads all 200+ posts. To set to ?_limit=30.

🎉 Received another $10/m subscription customer today! Thank you @atsaotsao for your support!

📈 Total one-off revenue: $600
📊 MRR: $30
Jason Leow Author

Thanks for all the likes guys! 🙌

0 Likes

Day 21 - Compete with fax machines https://golifelog.com/posts/compete-with-fax-machines-1611211166542

"Find an industry that still uses fax machines, and build a high tech, digital business there to compete with them..."

Day 20 - Building a business can be hard and lonely https://golifelog.com/posts/building-a-business-can-be-hard-and-lonely-1611134541299

"It’s difficult to say that it’s difficult. I think it’s typically not easy to be open and vulnerable in public, and even harder to do so in front of your peers, customers and competitors...."

Day 19 - A mosquito can be your teacher too https://golifelog.com/posts/a-mosquito-can-be-your-teacher-too-1611038010764