today 31 Oct 2017
access_time 12 minutes to read
It was a day like any other, scrolling through random tech articles while I
wait for support requests to come through. That’s how I stumbled across the
canvas tag new to HTML5. That’s when everything clicked, the gears started
turning faster and faster. I’d found an idea, and not just any idea, a great
After a couple days I had a prototype, you can check it out here. If you’re on a phone you may have noticed that it didn’t work at all! That’s because I developed this before I had a touch screen smart phone, I had a Nokia E72.
This was the first ever image I got to save to the filesystem using PHP to convert the base64 encoded image into a PNG.
After about a month I finally got my first smart phone with a touch screen, it was the beautiful HTC Incredible S and I got to work getting my software to work on it. Within a week I had it drawing on the phone, albeit way zoomed out and unusable, but the proof of concept had been completed!
With the proof of concept done I set about trying to come up with a name, now I admit, I ain’t the most creative person in the world so this will be a pretty short section.
Basically, I like ducks and I was building an oekaki. Yeah, I just combined quack and oekaki into oeQuacki because I like ducks. It’s just that simple.
I thought if it ever got popular my mascot would be some sort of duck artist because I thought that would be cute.
Now I’m going to spend the next few sections poking fun at my old code and demonstrating what not to do.
Now, I obviously didn’t realise I could dynamically add/remove classes because I have code like this for enabling and disabling transition effects.
God damn did I love whitespace too.
Although, very inconsistently because just below it is this.
The things I’m not so fond of would have to be the sheer amount of whitespace,
functions that do maybe a little too much, the fact that I didn’t use
DOMContentLoaded, and that it’s all in two files instead of only 1
class per file.
Here is where shit gets ugly, if you’re squeamish I’d suggest just skipping to the next section.
For instance, this is the how I save a single
Let me step you through this behemoth. The first thing I do is check whether or not this has already been favourited, this bit is fine, a bit verbose but fine since I’m not using an ORM of any kind.
Now things get a bit strange, I grab the image
one query, the next I grab the… hang on, what the hell. Do I pass in the
currently logged in user or the author of the image?
It really looks like in the first query I’m checking for my favourites, but
then I get the author using the same
UserID. Shit, it’s the logged in user.
So I guess I always save the logged in user as the author of the favourite, I guess I didn’t display that anywhere or I’d probably have noticed!
Alrighty, I guess I just found a bug for real! Ah whatever, it was supposed to
name of the author. Now we grab the thread and post
id. The last
query there saves it all into the database!
So what’s so bad about all that? Well, assuming I actually wanted a de-normalised database like that (spoilers, you don’t) I could have gotten all of that data with a single query using a couple of joins.
Which brings me to my next point, my database is terribly normalised, you saw
above how I save the author’s
name instead of their
id and using a join to
get all the data back out when viewing. If I had let users update their
I would have had to run two update queries, one for the user and one on the
favourites table. That’s very inefficient and error prone.
The rest of my SQL pretty much follows that pattern and lots of N+1. Pretty terrible and I could definitely have achieved much nicer even without an ORM.
Honestly it’s not great, but I’m not entirely sure how I’d make it better. I really never learnt PHP proper after this project, I moved onto Rails and my life was a lot better.
It’s filled with stuff like this though which I would definitely change to just take a parameter these days.
You can check out the finished product here here, just note that porting it into MaterializeCSS has broken how it works on mobiles, that’s not the fault of MaterializeCSS but of my janky phone code that relied on some very naive assumptions. It does work a treat on desktop though, so do give it a try there!
The last thing I’ll leave you with is my recording that shows off the features of oeQuacki that I put very little effort into. I really should have done a couple more takes, written a script, and cut it into logical segments.
But it gives you a good idea of how my site looked when I launched it and how it all worked in action. You honestly wouldn’t know how terribly it’s built from using it!