Side Project Stories #1 - Journal App
This article has been published a while ago.
If this is a technical article some information might be out of date. If something is terribly broken, let me know and I will update the article accordingly.
Recently I began writing a journal again. Not the regular way of writing with a pen and paper and also not writing in one of the many apps out there. No, I've written a little application which asks me a set of questions ever day and I try to answer them as good as I can.
The application is inspired by the Cortex podcast, especially episode 66 and 68, and by Basecamp (My team recently tested Basecamp as a replacement for Trello and the "Automatic Check-in"-Feature caught my eye) In the podcast episodes Myke and Grey go over a list of questions the author of Triggers asks him self every day. The questions all follow the same pattern: "Did I do my best to ...?" (eg.: "Did I do my best to be happy today?")
I really like the concept of those questions. In the past I struggled to write into my journal as I didn't follow a concept or guide. I just have written what went through my head at the moment the notification popped up on my phone. Most entries have been quite boring. I thought, that with predefined questions my entries would have a common theme and I could look back and see how I've evolved over the days and weeks.
As I enjoy creating new apps and concepts I quickly scaffolded a new Laravel application and over 3 evenings I had my first prototype ready. The projects code name is Medivh.
The structure is really simple. As a user I can create multiple journals to keep things organized. Each journal then has many questions and each question can have many answers. Here are some screenshots how the app currently looks like:
I have no intentions of open sourcing the app but I want to share a bit of code of one of the core features.
Scheduling Questions #
A question can be scheduled to send a notification at a specified time and day of week. Luckily David Piesse already wrote a great article on laravel-news.com how you can easily add a Schedulable
-Trait to your models.
The trait assumes that a model has a timezone
and expression
. The timezone
is currently stored on the User
model, therefore I just used the relationship to get the value. The expression
however is a tad more complex.
For each question there are 2 important columns which define the schedule: schedule_days
and schedule_time_of_day
. schedule_days
is an array of the selected weekdays (eg.: ["Monday", "Friday"]
). schedule_time_of_day
contains the time when the notification should be sent (eg.: 09:00
).
When the question is created or updated the cron expression is stored in an expression
column. The following mutator creates the expression.
public function setExpressionAttribute($value)
{
$time = Carbon::parse($this->schedule_time_of_day);
$hour = $time->format('G');
// Remove leading zeros from the minute string.
$minute = ltrim($time->format('i'), '0');
$minute = ($minute == '') ? '0' : $minute;
// Convert the Array of Weekday Strings to a String of Weekday Numbers
$dayOfWeek = collect($this->schedule_days)
->map(function($dayOfWeek) {
return date('N', strtotime($dayOfWeek));
})
->implode(',');
$this->attributes['expression'] = "{$minute} {$hour} * * {$dayOfWeek}";
}
Some examples how the cron expression looks like for different scenarios:
- Every Friday at 12:00:
0 12 * * 5
- Every Weekday at 20:00:
0 20 * * 1,2,3,4,5
Together with the Schedulable
-trait of the laravel-news.com article it's now really easy to schedule the notifications:
// app/Console/Kernel.php
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->call(function() {
Question::get()->filter->isDue()->each->sendNotification();
})->everyMinute();
}
I've already written around 50 answers in my little app and I still enjoy answering the questions and reading through past answers. During the development I had many feature ideas and I've written them all down but I will first use the app for another 1 to 3 months and then see if I still enjoy using it. Only then I will start adding more features to it.
The message I want to give to you with this article is simple: If you have an idea for an app and you have the tools to build it: just do it!