July 08, 2025
About an hour of this time was spent making a sidebar. This was harder than it might seem because of the way I made the TSX components, but it got done anyways.
The last half hour was spent in a slack huddle asking people to test the site out and updating it based on their changes, along with making notes. There's a simple bug that I'm going to fix in a couple days (I can't right now because I'm at an FRC competition) but it happens because the server doesn't index profiles if it hasn't seen a user make a file before.
Another thing is that the text input box for the username can have hidden characters, which causes issues with handle resolution. Also a pretty simple fix, just some string filtering.
You can now delete files. I imagine this is a pretty important thing to be able to do, especially for those who want to delete their files.
I also fixed a couple of goofy bugs on the server. One was an issue with unpacking JSON into objects and segfaulted whenever you deleted a file. The other one was an issue with not returning all the data (which took forever to debug).
This hour sucked so badly lol. I was trying to figure out why the only thing left on agent() was the session variable. I consulted Claude after two hours of back and forth with docs and it was because makePersisted (I was persisting the agent in local storage) only saved variables, not methods.
Through the fire and the flames, there's now the basics of an account page. The login page is also basically done, but I need to add a create account button at some point (that just goes to bsky).
Right now I'm dealing with the fact that authenticated clients are bound to certain URLs. There's probably a clever way to do it that I haven't found yet, but it needs to be able to rely on https://docs.bsky.app/docs/api/com-atproto-server-get-service-auth.
Spent some time filling in more auth stuff and loading file data! It's really close to working, but the Go package repo is once again my mortal enemy (See image attached - it's always at least 8 hours behind reality).
Tomorrow I'll be able to get the server compatible again once the go package refreshes though! :)
This is a really short devlog, but it's kind of embarrassing how simple the previous issue was. I was setting the file ID in the filekey records to always be zero because the file record itself hadn't been initialized in the DB yet. anyways, it works now!
I also finished up the business logic for the getUriFromSlug lexicon and am now just waiting on the (prohibitively slow) go package repo to update. This will probably take until tomorrow, but at least it doesn't need an account :).
Speaking of package managers, I should probably get around to creating an npm package for the TS generated types (which I also regenerated to include getUriFromSlug).
I've been working on a slug system which generates 6/7 character slugs based on the base58 encoding of the sha256 of some info about the file record. This means that people will be able to actually use it as a file sharing service and not have to type out like 150 characters lol.
I'm running into a db-related issue right now where only one slug is created, even if it gets multiple files from the firehose???
Made the upload UI nicer + now supports dropping files from all around the screen.
I'm probably going to take a short hiatus from this project to work on other things (a few days, maybe up to a week or two) or at the very least work less for a bit. Can't be burning out halfway in :).
Finished the file upload page! Attached picture is firefox's visualization of it on a horizontal iPad. (still haven't finished the file view page though, lol)
Also restructured Index.tsx to use router, so different pages come up.
A new challenge I hadn't thought of is converting DIDs/URIs to shorter slugs. I'm probably going to end up using something on the server side where I hash the did + rkey to get a slug, then add nonces if necessary. This would necessitate a new lexicon, but that's probably a worthy sacrifice to not make the links like 50 characters long.
Speaking of lexicons, I'm probably going to remove the getActorFiles lexicon because it reduces liability (I think?) with various online safety acts going around (cough cough britain).
From here on out, I expect the visuals to come together much faster as I've gotten the hang of tailwindcss more. The actual frontend glue (that necessitates atcute) is going to be annoying, but should also get smoother after the first bit. This might turn out to be a 15-20 hour project to get to first ship!
Started working on the website. I'm using TSX with solidjs and tailwindcss, and have just started creating a basic outline of what it will look like.
The image is Firefox's display of a generic iPad showing the site in its current state, which is entirely placeholder at the moment. I have removed the share button that was in the original design because there isn't much use for it and it would have been more work to add anyways.
Once I finish up the skeleton (list of pages is: home, file, profile, upload), I'm going to use atcute (https://github.com/mary-ext/atcute) to implement atproto/xrpc functionality. I've already generated typescript types from the lexicons using @atcute/lex-cli.
Today I finished up the server and cleaned it up a bunch! Println's have all been replaced by slog (go builtin logger) and getActorFiles is done. The only last change that needs to be made to the server is to update the skywell package, because I accidentally wrote what should've been files
as profiles
🫤. Maybe going to add a ratelimiter to the server in the future? (foreshadowing)
The server is mostly done, just need to finish the getActorFiles endpoint now! Because it uses Go, it's pretty darn quick + small (~24mb of ram usage while consuming from Jetstream). Had to learn GORM (go db manager) to do this, but it was way better than writing SQL by hand. Currently using sqlite, which probably won't change.
This was widely regarded as a great move by everyone.