isaacschemm: A cartoon of myself as a snail (snail8)
[personal profile] isaacschemm posting in [community profile] snailsharp

Pandacap

This has been my hobby project for the better part of the past year, and it's something I've been wanting to make a series of blog posts about for a while. Pandacap is my personal Swiss Army knife web app; it hosts my art gallery and microblog and collects incoming posts and notifications across five different sites and protocols.

The code for Pandacap is open-source (AGPL v3). I don't imagine it will be that useful to many people; trying to ask a non-Microsoft-stack developer to make tweaks to it would be like asking me to contribute to, well, anything in Python. (Plus, the code itself is not very robust, and not at all scalable.) But I've made some very deliberate decisions in the UI of this app, with an eye towards my own psychological well-being. The context collapse of traditional social media kept me away from it for years, and this app (and one of its predecessors, Artwork Inbox) is the reason I can follow artists on Bluesky and Mastodon without giving up in frustration. I'm hoping that someday, these design principles could be useful to other people who find themselves in the same situation.

The application itself is split into a set of public pages - the subject of this post - and a collection of features that are only accessible once I've logged in with my own Microsoft account. I'll cover authorization, crossposting, inboxes and notifications, and ActivityPub support in future blog posts, and perhaps some of the internal architecture and design decisions as well.

The main design considerations of Pandacap are:

  • Keep idle resource usage and cost as low as possible
    • Uses Azure PaaS offerings (App Service, Cosmos DB, Functions) instead of virtual machines
    • Absent any manual intervention from myself, the site going down is better than the cost going up
  • No infinite scrolling - limit the number of posts shown per click
  • Different kinds of posts are not mixed together in the inbox
    • Artwork and text posts are separated
    • Original posts and boosts (retweets) are separated
    • Within each page, posts are grouped by their author (or by who boosted them)
  • All content shown to the public is put there manually by the instance owner
    • Posts, favorites, and follows are public
    • Followers and comments are hidden

By the way, I'm writing this blog post here instead of on Pandacap itself for two reasons: it's not particularly applicable to the persona I use for my art, and since Pandacap is something I host on my own Azure account, it's hard to say how long I'll keep it around, and I'm quite confident that Dreamwidth will outlast it.

Profile

Ascreenshot of Pandacap's main page, with the user's avatar andname, links to other sites and protocols, a search box, 8artwork thumbnails, and 5 status updates (2 with their ownthumbnails)

This is the root page of my Pandacap instance at https://pandacap.azurewebsites.net. (Normally I'd feel a bit weird about posting a link, unprompted, to what's essentially my own art profile, but it's clearly visible in the screenshot, so it'd be odd not to mention it here.) Those of you who have done ASP.NET development will probably recognize its roots in the default Bootstrap template.

First of all, note the navigation links at the top: Gallery, Journals, and Status Updates. Unlike general-purpose blogs and microblogs, Pandacap splits local posts into these three categories. Artwork posts in the gallery have a title and an attached image; journal entries lack the title but are expected to have a longer body / description; status updates can have an image (or not) but always lack a title.

(Another separate post type exists - an "addressed post" - which is used for ActivityPub replies; these text-only posts are public but are not listed on the profile.)

Under my avatar and username, you'll see a handful of links. First is the ActivityPub card, with a handle which allows Mastodon and Pixelfed users to follow the Pandacap server directly. You can also see ActivityPub users I'm following, ActivityPub posts I've added to my "favorites" (this is sent to other servers as a "like"), and Lemmy communities I've bookmarked.

Next to the ActivityPub card, you'll see Atom and RSS links: feeds are made available for each post type, or combined into a single feed. (These URLs are actually the same as the ones in the header, just with a format= parameter). If you want to see what these feeds look like, try loading them up in Edge and then switching to Internet Explorer mode.

Finally, there are cards for my DeviantArt, Bluesky, and Weasyl accounts. For each of these, there's a link to my profile there (Bluesky uses the DID, just because I haven't yet implemented Bluesky handle lookup). There are also links to who I'm following and my favorites list on each of those sites (the Bluesky web app's "liked" list is part of the profile page; it doesn't have its own URL).

Below that ersatz linktree is a search box, and then a set of my most recent artwork posts - eight of them, with thumbnails. The five most recent status updates are shown as well; in this case, the two with images first, and then the three without. Journal entries would be shown too, if there were any recent enough; however, for non-artwork posts, Pandacap won't show it on the homepage if it considers it "too old". (It'll still be in the appropriate list and on the feed, though.)

Gallery

Ascreenshot of Pandacap's gallery page, with 20 thumbnails anda Next Page button

My gallery page looks something like this (but with my drawings, of course). Just like on the main page, image posts are shown as thumbnails with their titles as captions. This screenshot also shows the "next page" button. When setting up my Pandacap instance, I imported my DeviantArt post history going back more than a decade, so you could be clicking "next page" for quite a while.

Journals / Status Updates


The Status Updates and Journals pages are almost identical - the main difference is that journal entries have a title, while status updates lack one. (Journals also cannot have images, at least not right now.)

Note that status updates are grouped first by whether they have an image attached, then sorted by date. This isn't something I feel strongly about - it's more an artifact of this page sharing most of its display code with the favorites and gallery sections.

View Post

Ascreenshot of Pandacap's "view post" page with atitle and timestamp above the drawing and a description and"View on" links below it

Finally, there's the page for the post itself. Each element of the post is laid out in order:

  • My avatar, username, and handle
  • The post title (if any)
  • The timestamp
  • The attached image (if any), maximum 640x640
  • The post body / description (if any)
  • The tags for the post (if any)
  • "View on" buttons for the accounts this post has been crossposted to

Note that this page's URL is also the ActivityPub ID for this post - you can copy and paste it into Mastodon, Pixelfed, or some other ActivityPub server and find it that way.

Snail#

A programming blog where the gimmick is that I pretend to be a snail.

Expand Cut Tags

No cut tags

Style Credit

Page generated Jun. 20th, 2025 07:50 pm
Powered by Dreamwidth Studios