Forum photo uploads

posted by Jeff | Sunday, July 3, 2022, 11:27 PM | comments: 0

A legitimate complaint about the forums for years is that you can't just upload photos into it. To be sure, that's not exactly a hard thing, since I've been uploading photos for roller coasters and into my blog for well over a decade. But as with everything in that app, I've generally been motivated by what I need or want for my sites, and I didn't really want to be hosting images. I've softened on that stance, but I am going to be annoyed if people just use it to post stupid memes instead of linking to them.

The bigger thing that has changed over the years though is that cloud stuff is easy, which is to say I can put the images in cheap storage and even serve them via a global CDN for relatively little money. It's like 2 cents per gigabyte per month, and another 8 cents for the CDN, plus the bandwidth which is free for the first 100 gigs. It just doesn't cost much.

But because it's open source and I've always wanted it to run self-contained or using the cloud goodies, I had to write code to store the images in the database, and in the storage/CDN, configurable for one or the other. I also had to write a clean-up service, to nuke the images that the user ends up deleting or not posting, and run it in the self-hosted context of the web app or in serverless functions. It has always felt icky, but the self-hosted thing surprisingly works, and I ran it that way for a very long time. It was a performance hog because things like indexing a topic for search is expensive.

The UI meant learning more about TinyMCE, the open source text editor that I reluctantly depend on. It's just not something worth trying to write myself, although the very earliest versions of the forums had this as an Internet Explorer-only function before the standards were established, and I like to think I had the first forum to embrace that. Anyway, I had to figure out how to add a button to Tiny and run my own code to do the upload. It's super seamless, because you click/touch the upload button, choose your image, and it uploads and sits in your post.

What I didn't want to do was try to figure out what the editor was doing if you happened to delete the photo before you posted, because I already resized it and stored it. I thought of a few different cumbersome ways to do that, but ended up making it more simple. When you upload, it sends back an ID that it also temporarily saves with a time stamp to the database. When you post, it sends the ID's with the post, the post processor looks at each ID from the post and deletes the temp record. The clean up processor looks at those records once an hour, and any that it finds that are older than some number of hours, it deletes the corresponding image file in storage and then that record. So I'm not storing a bunch of images that aren't actually found in any post.

The only compromise I made was using the web app to resize and store the image. It's surprisingly not that computationally expensive, but it's certainly more expensive than serving up text. Ideally I'd make this another serverless function as well, but then I have to figure out some kind of auth scheme so random shit on the Internet isn't using my free image resizer. In the web app that's easy, because I can see if the user is logged in or not. I may yet revisit this, but it would be another thing with more setup configuration.

I cranked all this out in less than 48 hours, and I spent a bunch of time just trying to figure out how I could modify Tiny through configuration only. This comes on top of the post quoting that I'm already excited about, the browser UTC time adjustments and text, client-side localization and other stuff people won't notice. Now I'm thinking about all of the UI stuff I previously contemplated. I think the activity feed will go away, and that top nav will have a person icon for the user, a clock for recent topics, then the PM and notification icons, and finally the search. Then there's no menu to responsively compress. The Q&A style forums need help, and I'm surprised at how little people understand how to use them.

The last big swing I might make is to replace the PM stuff with outright chat. That's going to be fairly easy, but I imagine I'll have to eventually follow it up with blocking and reporting tools. I also don't want to emphasize it, in part because it's a forum, but also I'm not going to do pop up windows at the bottom of the screen. I hate that UI, and it doesn't translate well to mobile.

Adopting web components and TypeScript has generally improved my client game, but only to a degree. It's somewhat easier to follow, but it's not well encapsulated since it often involves a bunch of stuff spread around the page (topic state is like this). It feels brittle and it's not unit tested. It is in some cases reactive though, and I'm happy with that considering I used no libraries. Some day I'll have to refactor it so it's less confusing.


No comments yet.

Post your comment: