A fancy pants atproto OAuth login screen
In the interest of procrastinating on building out the actual features I have left, I decided to tackle the login page. I had started with a DeadView, aka a classic Phoenix controller. Very simple, it's just an input field and a submit button. But the actual login flow takes a second or two, there's a back and forth involved and not every PDS is going to be very fast, you gotta validate everyone is who they say they are, etc. So the result was an awkward wait on submit.
I made a small optimization on the backend OAuth code, on the way back from the permissions screen, but that didn't really do anything for the initial frozen page when clicking submit. So I added a spinner. Just a few lines of JS, very simple. It immediately made the page feel more responsive and improved the experience a lot.
I sat back and admired my work. For a second. Then I remembered all the other versions of this page I had seen. On pckt.blog, on Offprint, on marque.at. They all have fancy pants interactive handle pickers, with typeahead search, avatar images, and clear selected states. Surely we can do better than just a spinner!
Step one is the typeahead search. Bluesky offer an endpoint that uses their indexed data, at https://public.api.bsky.app/xrpc/app.bsky.actor.searchActorsTypeahead, with the docs here. It allows any origin through CORS, so you can easily just hit it from the frontend if you want, although with LiveView it was just easier to do it from the backend. I set it up with a little combobox that rendered rows for each suggestion with handles, display names, and avatars. Already much better!
But I noticed something very small but incredibly annoying. When I typed my own handle, I had to type the whole thing to actually get me as a result. That's weird! I tried it on pckt.blog and it immediately found me after adding the dot after jola, jola.. I opened up pckt.blog's login page in the dev tools and started snooping. Turns out, they're using https://typeahead.waow.tech/, an alternative typeahead service. Switching over made it work much better. I'm not sure if it's just because it's a better service, or if Bluesky's endpoint actually has a bug. Bluesky just seems to crap out whenever a query ends with .. So as you're typing, j, jo, jol, jola, you're getting results, but when you get to jola. there's nothing. Then with jola.d we're back to results again.
Ok, so we've got typeahead, suggestions, and pretty rows with avatars. The part that's still missing is that when I select an option it still just shows as plain text. I noticed that several of the sites I've been comparing with show a special "card" when you click an option in the dropdown, which is very nice and qualifies as fancy pants, but I didn't love that the behavior was inconsistent between typing the handle out yourself and selecting it from the dropdown.
I settled on using the pattern that marque.at does. Have an avatar placeholder in the input field, and whenever the typed handle matches an existing avatar, show it. It's surprisingly effective and consistent.
I'm pretty happy with the results. Feel free to play around with it at annot.at or dig into the code at https://tangled.org/jola.dev/annot.at.
Sign in to leave a note.