Dashboard for healthier content consumption

Howdy! I think that algorithmic feeds that are designed to keep you scrolling are pretty harmful, but RSS, which is often touted as the healthier alternative, creates its own problems by treating incoming items as if they’re to do items that must be read or dismissed. I want to design an app that can show things that are ephemeral/urgent as well as save evergreen items to be read later, and I think solid is a good framework to use for data ownership and allowing this project to only focus on the dashboard while letting people choose e.g. what RSS reader or read-later service to use.

I like fraidycat, which is similar but hasn’t been updated in awhile and doesn’t handle the evergreen content well, which is important for feeds/people who post rare but high effort/quality posts.

So my vision for the app would be a dashboard like home assistant, where the user can specify cards that would display data like “which twitch streamers that I follow are streaming” or “show recent items from feeds I follow tagged ‘tech‘“ or even “show discord channels I follow where there’s an ongoing discussion". The sources should be varied like that, and ideally have some mechanism to turn any data the app has read permission on into a card. In theory a user could also have multiple dashboards, perhaps one for evergreen content, and a card could specify like a url to open the items in, so it could be read in your read it later service (or a twitch privacy frontend) or w/e.

But you’ll notice the things that I’d want to show here are basically all notifications about activity happening elsewhere on the internet. And if I load up the app and it suddenly has to fetch data from a hundred different sources, it can take awhile for it to actually build the UI to display to the user. So I’d really like for the data to be updated by some background service(s) and written to the pod. I noticed there is an old rss reader for solid, but it looked like it just fetches items locally via a cors proxy. I was wondering if there’s any advice or feedback on how this “ought” to look like. Honestly I’m considering just forking Miniflux so instead of a DB for accounts and feeds and stuff, it just stores an access token to read the list of feeds (and their settings) and write the list of entries, and logging in it just shows buttons to save or delete that token from the list. And I guess do something similar for any other source like twitch.

Actually rather than a Miniflux fork it’d probably make more sense to write a small service that takes Miniflux’ webhook calls and adds entities to the users pod.

I have a question on what best practice would be for automatically deleting stale posts so they don’t use up storage indefinitely, which would be important for rapidly updating feeds.

You posted a lot of text so I am going to drill down to the parts I think you want answered.

But you’ll notice the things that I’d want to show here are basically all notifications about activity happening elsewhere on the internet. And if I load up the app and it suddenly has to fetch data from a hundred different sources, it can take awhile for it to actually build the UI to display to the user. So I’d really like for the data to be updated by some background service(s) and written to the pod. I noticed there is an old rss reader for solid, but it looked like it just fetches items locally via a cors proxy. I was wondering if there’s any advice or feedback on how this “ought” to look like.

You may want to look into ActivityPub/ActivityPods for this. They are working on integrating Solid Pods with the federated notifications used by the ActivityPub protocol.
For your use case, there is no way to get past the “first heavy load”. However, there is the possibility to index these contents for static resources and listen to dynamic resources. This listening mechanism could be ActivityPub, some sort of “heartbeat” protocol, a WebPush mechanism, or some other custom push/socket-based solution.

I have a question on what best practice would be for automatically deleting stale posts so they don’t use up storage indefinitely, which would be important for rapidly updating feeds.

If you are controlling your own posts - include a timestamp and when they load, delete ones dynamically that are older than whatever date, or auto-archive them. If these are posts which are on a trusted service, have a timestamp and a signature. If these posts are out of your control - replicate them locally with a hash (of the content and/or uri) including a timestamp on first load and match it up when the user opens the page where you delete any that fail the validation or exceed your saved timestamp.

I think I didn’t describe my use case well enough, because I don’t think the solution would be requiring an activitypub server.

RSS is already decentralized. It’s something a lot of sites already support. RSS readers today will have a server that polls the feeds a user is subscribed to in a regular interval. So when the user opens the reader, it already has the new articles populated. I would want my dashboard to work like that.

I think this is feasible through solid by having a service that you log into with a pod, and it reads your subscribed feeds and polls them and writes the articles back to your pod, all server side. Or, for convenience as a developer, I can let an existint reader like Miniflux do that and write a small service that syncs the data from Miniflux into my pod.

Then my dashboard can read that data immediately when it opens up! And it can filter to only show the recent unread content, like I want. I can likely setup similar services to poll stuff like twitch streams and write them to the pod as well.

My question is if this is how solid apps are “supposed” to work. The idea of setting up a service that does this regular polling indefinitely, and only stops once the user logs back in and tells it to stop (or revokes access to their pod I suppose). Additionally, if I wanted to auto delete expired content so they don’t fill up my storage, would that be the kind of thing the dashboard handles? The rss reader? A completely separate service from those two?

I’ve been thinking about this still, and would like to make an iteration on the idea.

We could have a RDF schema for a block-based document (like notion). The types of each block would be themselves IDs for schemas describing the block. The app for viewing the document would then implement that schema in order to support displaying or editing that block.

A block could be a paragraph, a bullet list, a heading, etc. But importantly, some would be really generic to allow complex behaviors: blocks that contain arbitrary code.

This is similar to Jupyter or Observable, where the block can contain code that gets executed and either emits data for use elsewhere in the document or even a HTML widget to display (e.g. of a graph).

This could allow the dashboard idea to be implemented as a block that runs code to find the data (RSS, discussions, etc.) inside the user’s pod and display them in the way the user wants. How the data gets there could be through various means, like a separate service automatically saving articles from miniflux or something.

The code blocks could also expose commands/actions for the user to do. For instance, perhaps instead of using a separate service for automatically saving miniflux articles, a code block could create a command that fetches the data itself and saves them to the pod. The app could pick up on the registered command and display it to the user, perhaps through a command palette or similar.

The hardest part, I believe, would be speccing out a sort of sandboxed environment for the arbitrary JS to be run in. Any rendered widgets would be in a shadow DOM. Stuff like registering commands would have to be done via a context global or something the code could access and check for capabilities on.

Also I use js as the example here since it’s very powerful, but if this were actually implemented it might be useful to consider code blocks that actually use a visual programming language. In fact, maybe the code blocks aren’t actually blocks living inside a document, but there own entirely separate RDF schemas that anyone could build an editor for, and then the actual block type would just be something like “render a button that runs the code in this file on click” or “run the code in this file and render its output in a shadow DOM”.