Reckoner Update April 2023

Happy April Fools’ Day 🎭! As you can tell by my writing this is a strictly serious blog with no fun at all 🧐! However, I won’t further inundate you with a joke post about a product that isn’t going to ship. This 🚆 is chugging along and there’s quite a bit to cover, so let’s get into it!

🐛 Fixes

So you know that issue with web forms logging in? Turns out async code behaves differently on different platforms 😲(act shocked). I tried doing the save of credential on the form validation step which runs synchronously. However, the actual saving of the credentials happens asynchronously (to secured storage). There were two ways to get around this: 1. force async code to run synchronously, 2. Do the save earlier. I opted for #2 as #1 might cause stuttering in the application since the main thread would be in a busy wait.

I also fixed a longstanding bug in the report display. There was an issue with loading the correct account sum for all transactions preceding the report display range and another bug related to adding transactions at the start and end of the display range.

Finally, a bug that happened during saving a report edit was fixed. This was a bit obscure, but basically I was modifying a widget’s state during the save action which then followed with popping the route from the router. This caused the widget to redraw twice on being popped which caused it to render the page twice and build widgets with the same key. That error is very bad and can cause Flutter apps to crash (web was most sensitive to it). I couldn’t find any documentation about the way I encountere this issue, but this shows I was doing some bad things 🤦.

🥧 Charts are Here!

I’ve added the ability to specify and display pie charts! I thought I would knock this out quickly, but it required a bit of finagling with the graphic library. I really need to improve the labels on the charts as the defaults seem to be just too small with poor contrast (see above image).

Screen Lock 📱

A screen lock is now added! This uses secure local storage to store an unlock code and then requires the user to enter it in every 30 min of use. Right now that is hard coded and is definitely something that should make it into a user setting. I originally considered using some of the packages from, but I have tried to limit my use of dependencies when I found that other packages I used would have breaking changes or didn’t keep up with new Dart/Flutter release and would cause dependency issues. Actually the form inputs package I am using does not support the latest intl package dependency and caused me to figure out how to do dependency overrides to compile with Flutter 3. I found that I could easily make the lock screen code and save myself a dependency. It’s not fancy looking, but does work. I also made the timeout 3x longer on every 3 failed login attempts. So the first timeout is 1 minute, then 3, then 9, etc.

I have also added a security page in the options. This currently allows you to set the app passcode. Future plans are to allow setting of the local database encryption and encryption for the synchronization service.

Database Encryption 🔒

After waffling around it forever, I went ahead and looked into adding local database encryption. It turned out to be easier than I thought with Drift. The only issue is that Drift seems to only have complete documentation for mobile platforms and desktop platforms require you to look at the supporting libraries like sqlcipher_flutter to understand what you actually need to do.

I have added the ability to change the database encrytion and use a random cryptographic string or specify a key. Changing the encryption of the database requires destroying and recreating the database. I figured out how to properly dump AND reload the database. Thus I need to add a way to dump the database to a separate file encrypted or otherwise independent of the other encryption settings.

What’s Next

Going over the previous list of items, I have the following left.

That’s more than I expected to get done this month. Some of the items were easier than I thought they would be. I expect those last two items to take a significant amount of time.

The other issue is that I was tempted to start another application. Noticed a nice FOSS workout tracker on FDroid which was only Android. I thought I could do the same thing as this app, but in Flutter to deploy to all platforms. Then I could use Supabase to host workouts and do a social component. But I fought this feeling and stayed focused. I think this desire to keep creating new things is why FOSS applications tend to have a limited feature set as the developer loses focus or decides to just start a new project. It’s a tendency I’ve seen as pretty prevalent. But the real gems are those which have taken the time to get past the dip and build something of greater value, which is what I hope I am doing! No promises though 🤞!

Until next time!