October 12
Hi everyone! Hope you're doing well :)
I actually meant to write an update a few days ago, but since getting two vaccines in the space of two days (COVID booster and flu jab) I've been feeling slightly off for the last day or two and didn't get much done.
Anyway, aside from that, updates are below.
NSFW content warnings
Individual warnings on artworks are done already, but it's also important that unregistered users and users who are not of age can't view adult content on the site without logging in. I've mostly finished implementing this, but I need to change it slightly; I originally made it so that they couldn't view said content at all without logging in, but in hindsight it might be more practical and useful to have a prompt that asks for DOB before allowing viewing of NSFW content (rather than forcing users to have an account, as it really doesn't provide any better age verification). I'll think on that a bit, but the actual functionality is pretty much done, so I can decide which approach to take later.
Minor gallery bug fix
While doing some cross-browser testing, I noticed the gallery code seemed to fail on Firefox in very fringe edge cases where Chrome didn't. Turns out Chrome and Firefox do rounding a little differently... in Chrome, if you have an element 739.017 pixels wide trying to fit inside a 739 pixel element, it fits it inside by rounding down. Firefox doesn't, so gallery images were being thrown into separate lines in rare cases, making the gallery layout code look very off if you happened to adjust the browser to just the right size for a given gallery. That's fixed now by doing the rounding in JavaScript to make sure that the total content width is never bigger than the container by any amount.
SQL optimisation
Optimising SQL (database queries) is really one of those rabbit holes you can go too far down, especially for a website that isn't running yet. I was talking to some people on this subject, and realised that some of the queries I've written aren't as efficient as they should be, due to using subqueries instead of joins where they weren't needed. I've changed the relevant queries now so they should be better.
Redis configuration
In simple terms, a Redis server is like a cache: you can use it to store key-value combinations, with very fast retrieval speeds. Implementing this is absolutely essential for the site's search bar and many other database queries, because many of them will return the same result each time (and unlike Redis, database queries can be very computationally expensive).
I've gotten Redis running, both via AWS and on my own PC for testing. Next is actually changing the code to work with it - not all database queries can or will want to use Redis (for example, redis isn't any use for inserts/updates/deletes, and some queries should not be cached). I therefore need to make some changes to some of the database functions, and also to some database update functions.
The reason you have to change database update functions, even though Redis can't "cache" an update command, is that you need the website to be up to date. Say you upload an artwork; when people view your artwork, Redis gets the previous database result from its cache and serves it to users. But what if a user changes their artwork, by e.g. changing the image or the description?
Redis doesn't know you have changed anything; it will continue to serve the old cached result. There's two ways to handle this, depending on the specific use case:
- Invalidate the cached result in Redis, forcing it to get new information from the database the next time someone asks for that information. This is perfect for times when you know the data will only change occasionally; using this method, Redis will continue to serve a cached result until the user updates their artwork, at which point it will get the new data next time someone tries to view it. This means the website always looks up to date, but doesn't have to do a database search every time someone tries to view something.
- Set the cached result in Redis to expire in a given timeframe. This means that users will still see the old result for a while until the cached result expires, but this is perfect for e.g. search results. This is because actual search results are liable to change very often, so invalidating the cached result every time it changes is completely impractical (and would negate the benefits of using a cache in the first place).
As a result, some update/insert/delete functions have to be changed to invalidate specific Redis information after they are called, and some Redis insert functions have to use expiry dates. The real difficulty with this isn't so much the actual invalidation of data, but figuring out exactly which data needs to be invalidated and deciding on a formal name structure. I'm going to have a make a sort of formal backend 'rule' for myself about how database functions are described, or some other list, so that it's always clear which functions must have their Redis keys invalidated on certain updates and all that stuff. Spent the last few days wrapping my mind in circles about it.
As part of that, a curious side effect was that I ended up commenting all of my database code properly, to aid me in figuring out how to implement the Redis stuff. I haven't yet finished with the Redis stuff, but it's getting there.
Patreon/Stripe queries
Just to be certain, I asked Patreon and Stripe about ArtCentral's use case. Patreon's more or less given the green light (their support response was wonderfully unhelpful, it just regurgitated the rules pretty much) but that's enough in this case. Stripe said it's fine, when I asked for more info about specific things they said they'd get back to me, no news on that yet. I think Stripe's position is that they never give any final information until you have a registered business and working website or anything, so I'll likely have to wait until then. Patreon is fine to start with, and for e.g. people who like updates, but Stripe is a nice alternative for those who don't want Patreon emails (and it takes a smaller cut of the payments).
Badges (supporter badge, etc)
I've designed a kind of basic CSS element to do this - both for supporter badges, admin badges, that sort of thing. I haven't yet put any fancy animations on them - something to give them a bit of shine - but I think they'll more or less stay in the form they are now, barring some minor appearance changes. You can see an example of them in the cover image for this post.
Getting into the correct position was a slight challenge, so that it doesn't push the text around. I also added a gradient to banners - you can see that the banner image gets darker as you go from top to bottom. I noticed that with this banner image, it's quite bright at the bottom, and that was making the text showing the username hard to read, so the gradient helps with that.
Website logo
I've started the process of getting a logo for the site. I've talked to an artist friend who is skilled at that, and now I need to figure out a concept for it. Should be fun!
Next steps
Next on the list for ArtCentral is sorting out redis for some database queries, implementing artwork tags (partially done) and then implementing search queries and search results pages.
There's also a fair bit left to do in the Settings area - some settings sections need populating. I also need to create a main homepage sort of thing, which I'll wait to do until the Redis features are done.