Multiple Queues Impact and Feature Mapping

Hi everyone! Saturday Keunes, ByteHamste and I meet and decided the beginning of a deep mapping of all changes needed to be done in order to implement Multiple Queues on AntennaPod.

So here we will begin to list the Features impacted by Multiple Queues or New Features/Behaviors needed to be considered for implementation. Disclaimer: We are going to begin the implementation by adding simple and “dumb” queues that need somehow have the be manually managed by the user.

In general, today AntennaPod expects the existence of an unique queue, all features based on this unique queue need to be changed to expect the existence of multiples queues and so, we need a rule to decide which queue to use.

I will start listing here what are those features that I have detected until now.

A brief context about my personal implementation: I have created the capability for queue creation, where all queues having a name. I have kept a default queue, so I didn’t touched any current behavior of AntennaPod regarding to queue. All failures on identifying a queue, fallback to the default queue usage. Even so, I have some unexpected bugs. I have created multiple queues in order to be able to specify a automatic/smart queue, so I don’t really use multiples queues, considering that, I haven’t explored all, if any, aspects of multiple queues. I don’t consider my fork code to be directly used for the final implementation. I will use it only as a reference to implement multiples queues from the scratch on a clean branch.

Queue Attributes: All queue should have a name specified by the user and an id for AntennaPod work with it. In case of a default queue should it have a name modifiable by the user? Where to place the feature to do Queue renaming? Are there any other attributes?

Queue creation: Today we have a default and unique queue. Should AntennaPod expect the existence of a default queue? So if the user don’t create any additional queue, all the existent behavior should be preserved. This way the Multiple Queue feature would be added without changing the usage complexity for current users that don’t feel this need. Where should be placed the commando for queue creation? Should it be able to create queues from the queue screen menu? If we start without any queue, should we automatically create one once users begin adding Podcasts? Should this first queue creation be transparent or explicitly to the user? Note: If we choose to keep a default queue we could cold install AntennaPod with this queue.

Queue deletion: Where to place the command for queue deletion? Once a queue is deleted, what to do with the play items added only to it? Should they be deleted? Should the user to be prompted to choose between the deletion or to move to another queue? Should user be prevented to delete all queues? So if the user try to delete the last existent queue, should we block the action and suggest the user to clear the queue instead?

Drawer Menu: Needed the definition if we will show the Queues directly in the drawer or just change the item name to indicated that now we are talking about QueueS instead of Queue. In case of listing all queues from the drawer, we need to specify what to list on a clean install (see queue creation). If we list the queues on the drawer should we show how many items there are for each list?

The Queue screen: Should it have a switch capability for changing between queues or should exists a intermediate screen listing all queues to be accessed by the user. In the case of a screen with switching capabilities, what is the rule to define the queue to be opened by default? Should it be the last used by the user? If the drawer has the capability to list the queues, it should send the parameter to the queue screen to open the requested queue for listing

Playback state: Today AntennaPod store its playback state without queue information. It should now begin to store this information to resume from the previous queue used by the user.

Android Notification Panel Item: Should we show the current queue for the user? Should we provide a way to switch between queues from there?

Cover Screen: Should we display the current queue also on this screen? That seems to make sense for me, so user know from which queue that item is being played, that way the user know what to expect after it.

Android Auto: All Android Auto screens and layouts need to be changed to comply with multiple queues.

Episodes Screen: Today we show an icon that communicate to the user that a episode is queued. Should we show the queue name? In case of a episode be placed on multiple queues, what should be displayed?

Episode Queuing: Should user specify the queue destination for an episode once the user click it to download? In case of existence of an unique queue, should we fallback to this queue, without asking any action to the user? Or should we prompt it with an option for creating a new queue or use the existent one? Once a Podcast have automatic download enabled, which queue should be used for the downloaded episodes? Or should we keep them in the inbox for the user to choose a destination queue? Here we are beginning to deal with a kind of smart configured queues aspects. This aspects should be considered when user hold click on any episode and then select “Add to Queue”.

Queue sorting: We should keep the current behavior, but the code now need to know which queue is being sorted. I haven’t changed the sorting capabilities so any time any sorting algorithm is triggered AntennaPod does update the Queue table by moving everything to default queue.

Listened episode (and mark as played): What to do when user listen to an episode listed in more than one queue (or hold press over it and selects mark as played)? Should we remove and/or mark as played from all queues? Should we remove/mark only from the current queue? If so, the automatic deletion needs to be aware of how many queue holds reference to an episode.

Episode deletion/removal: The same as above needs to be considered when user holds a episode and choose “Delete” or “Remove from queue” from any screen.

Reset Playback position (or even the track of current playback position): Should it be done for every queue or globally? So if an item if half played on a queue and its reached on another queue, should we start over or should we resume it? This one will be a kind of polemic since it depends on what user wants from multiple queues.

Queue lock: The lock behavior should be enable/disable by queue. Today if I enable it, AntennaPod locks all queues.

Queue Swipe Actions: Should also be configured by queue or should it be configured globally? Personally I think it makes sense to be a global configuration.

This is everything that I have found for now, and also that I can remember from our meeting. If I remember anything else, I will add.

Ps.:
Automatic Queuing: This is for future implementation. Should user be able to ask a Podcast to be always queued in a certain queue? Should it be possible to specify more than one queue? Where to place this configuration? Should it be related to the Podcast or should it be the queue? Consider the delete cascading: Podcast deletion will cascade the deletion of this configuration. While Queue deletion will cascade to this configuration, leaving Podcast without the configuration. My current implementation use the second approach and I haven’t implemented any treatment for what happens when a queue is deleted and a Podcast and up without any queue configured to use it. There are many other aspects to be considered on automatic queue so we will not dive into it for now.

Hi @igor,

As mentioned via email, many thanks for you initiative here!

Long overdue, but I’ve just uploaded the recording of the user research presentation, which I think is quite relevant. In case you want to watch it: AntennaPod Community Call 2022 10 22 (part 1) - UX research - YouTube

Tomorrow I’ll be working again on the mock-ups & flow.

Let me reply to some points that I’m not already covering in my UX work, or I think need additional information:

I’d say so, yes.

For now I can only think of the the ‘source’ podcasts. When queues might become ‘smart’, I’m sure there’ll be more attributes.

Yeah, I think this should be kept for consistency between versions.

I personally prefer to list all queues; I think it’s more transparent. But we can also make a mock-up for the other option (1 queue screen, with selector to determine queue).

Yes. Maybe that’ll make it easier to implement Continuous playback if initiated from podcast screen (+ reversed) · Issue #1533 · AntennaPod/AntennaPod · GitHub.

I think that’ll be a bit much. The notification is full enough already I think.

Hmm. Again, the full player screen is quite full already, especially on smaller form factors. But, something to reflect on.

Not sure what might be needed there. Should we expose the different queues? Or do we only expose the current queue? Might not be a bad idea from a security perspective (force user to pick a queue before departure). @tonytamsf any thoughts? (welcome back :tada:)

Again: I would keep current behaviour to not clutter the interface further. If there is a clear rationale for why this would be needed, we can think about this later.

In my mock-ups I’ve added a ‘source queue’ selection per queue. If a podcast is a source for multiple queues, an episode is/can be placed in multiple queues.

Yes, actions apply to the episode, whichever queue it is in. I think this is the most predictable, and avoids having to apply the same action multiple times. Also, generally (known exception: langauge learning) you’ll want to listen to an episode only once - regardless the queue it is in.

Hmm, as ‘Remove from queue’ is an action to an episode in the context of a queue, I think it should apply to the current environment (queue) only. If it should be removed from all queues, the user can use workarounds in the beginning - dedicated functionality could be added later.

I think that indeed this should be queue-specific. Also because there is a link with Sorting (in case ‘keep sorted’ is active) and this may differ between queues.

Agreed - global configuration.

Allright, my prototype is pretty much ready. I think I might need to fix some flow mistakes, but all the screens are ready to show. @igor, @ByteHamster; would you be up for a meeting where I showcase the screens & design? If yes, would next weekend Saturday work for you?

Thanks for pointing me to this recording Keunes! I’ve just watched it and it was very enriching. I found myself on many behaviors maped by Howard’s research!

I have availability for the next Saturday. It could be on my early morning like last time or a bit latter (skipping my lunch time for sure), if you have any other scheduling preference.

Since we are almost at the weekend, I suggest to schedule a meeting to the next one.

@igor when can we expect an update with the ability to have multiple queues?

@anon45685503; @igor, @ByteHamster and myself had a meeting two weeks ago, where I presented the mock-ups (designs for all the changes in the user interface). They gave some valuable feedback that I need to follow up on (adapting the mock-ups). Unfortunately I haven’t found the time to do so yet, as I was busy with personal stuf and needed to prioritise work on the 3.0 release (changelos, press release).
There are many different parts & pieces that together make the multiple queues feature, which all need to be developed. In our meeting, Igor and ByteHamster said that as I’m updating the mock-ups they could start thinking about the order in which the code for all these different pieces could be written and reviewed. I guess that like me they haven’t found the time to work on it.

Once AntennaPod 3.0 is fully released I think we’ll have more time to work on the multiple queues again. However, to get back to your actual question: it’s a big project and it’s impossible when or in which version this will become available.

@ByteHamster When you’re back from holiday, would you be interested in picking this up again? @igor, are you still up for working on this if we put our shoulders behind it from our side?

Multiple queues is an interesting idea, but what I really miss is playlists. “What’s the difference?”, you ask. It’s this: episodes don’t get removed from a playlist after having being listened to. Perhaps this is just a matter of setting a flag for each queue/playlist whether to remove played episodes or not, and the rest is semantics.

Hey guys, I’ve been using AntennaPod since Jan/26 and I can honestly say it is the best podcast player/manager out there, no doubt. I’m coming from PocketCast and CastBox and, aside from the web sync, I feel there ain’t nothing we had over those other players that we don’t have on this one, plus the added bonus of not having ads from the platform itself.

I’m a media hoarder, I consume a lot of YouTube and multiple news/tech/documentaries podcasts, and one thing that I had on YT that I missed here, a lot, was the option to manage multiple themed playlists/queues.

I’m no Java developer, I mostly work with JS and PHP (web based projects), but I decided to dig through the multi-queue status on the project, and found that we had multiple PRs not merged due to inconsistency, AI and lots of other issues.

As a new user I can’t post more than 2 links, sorry, but here are some of the things I’ve found:

  • Multiple / User Definable Queues. Issue #2648
  • (Very) WIP: Enable Multi-Queue support. PR #8070
  • WIP: Multiple Named Queues - DO NOT USE - branch was dumped and reimplemented PR #8066
  • WIP start dialog on multiple queues PR #3221
  • Enqueue location by podcast PR #8215
  • Improve database indexes for large libraries PR #8718
  • Multiple queues. Conclusions: we like the UX approach of the agentic PR but should probably be implemented by a (skilled) human (to minimise the review overhead). Forum: needs-decision call #4169/34 @keunes

I know this has been a most asked feature and I’m sure it’s not up yet because there are a lot of problems to follow through before being able to deliver it, but out of curiosity I gave the task to Claude (I know, I’m sorry, hear me out though) with the following requirements:

  • Keep all development work within code style and structure according to AntennaPod contribution docs: Code structure & Code style
  • Respect what moderators have pointed out before, on other Issues and PRs, so that we have the best shot and least overhead on reviewing anything, including:
    • Scope: @ByteHamster asked for a “dumb”, manual queues first (v1), then an MVP: no automation, no icon or color pickers, no experimental on/off switch. The objective is to build the groundwork to merge it without impacting current users, database, legacy apps and all else.
    • Architecture: instead of building out database tables, extend the existing queue table, for ease of maintenance and compatibility. On PR #8066 he specifically asked for the existing DBReader/DBWriter to be used instead of a new repository layer (this was actually the reason PR #8070 was declined, from what I understood).
    • UX: On PR #8070 switching queues is done on the same Queue screen users are already used to, and is stored in memory. “Add to queue” goes straight to the active queue, with no picker dialog. This works great because if the user never creates a new queue, nothing changes, and if users manage multiple queues, there is no extra step on adding an episode to the current “in use/active” queue.
    • AI code: PR #8066 form seefood (great avatar, btw, love the show) was rejected largely because it looked AI-written without regard for the existing code, hard to read and thus lacking maintainability (I’m with you guys on this one, that’s why I asked Claude very nicely to keep within code style/structure and reviewed each phase manually).
  • Documentation is key, every part of the implementation should be planned out on a ./Docs folder, documented and revisited once the phase was done, so any findings, issues or changes were to be documented, reasoned, reviewed and revisited as well.
  • Do as minimal diff as possible to be able to keep up with the main AntennaPod repo’s future updates (in case this endeavor has the same fate as the others before it):
    • New branch for each phase of the implementation, so that if it is partially accepted, we won’t loose all the work done, and easier to review as well.
    • In each phase look for security issues, performance improvements and opportunities (reuse, simplify, etc), and design deviation (check for any previous implementations of classes, functions and styling from the Code Structure e Style guide).

From this, I forked the AntennaPod repo to my personal GitHub profile, Claude came up with a plan with 6 phases of implementation (I did actually create links for each phase docs and branch, but with the limitation I had to remove them…):

  1. Phase 1 - Storage layer: No user visible changes. App still behaves the same as previous versions and upstream, only the default queue still exists, but we do the groundwork to use multiple queues on the database, adding a small new table only to hold the new queues’ names.
    1. Each episode can live in only one queue, and the chosen queue is recorded in memory (as there are no UI changes, “default” queue is the chosen one, always).
    2. All compatible with main app and exported databases.
  2. Phase 2 - UI: added interface options to enable users to interact with database changes made on Phase 1:
    1. When clicking 3 dots and clicking to add a new queue on the Queue screen, a new chips row is added, showing available queues, and allowing users to select the active queue they want. Menu options are: “New”, “Rename” and “Delete” queue.
    2. Queue names should be, at most, 30 chars, and can’t be stored empty to avoid errors.
    3. Android Auto queue count and swipe actions for episodes in different queues.
  3. Phase 3 - Release builds: In order not to interfere with the main “develop” branch, created a “multiple-queues” branch to live as default on fork only.
    1. Every merge int to the branch builds an APK signed with my key and creates a release on the GitHub repo.
    2. This is supposed to help me use the app while not merged upstream to AntennaPod (which I know might never happen)
  4. Phase 4 - Upstream Sync: to keep up with AntennaPod upstream repo, a workflow fetches and merges (if no issues present) changes. If any conflicts, a PR is created labeled “upstream-sync” to list them and never merges automatically.
  5. Phase 5 - A queue per podcast: Here we branch out from the main PRs and issues known so far, and add an extra menu entry on podcast’s config menu, to allow user to select a default desired queue:
    1. New episodes add to that queue by default.
    2. Episodes queued, when finish their downloads, go to that queue.
    3. “Add to queue” manual action still lead the episode to the active queue, not the podcast’s config.
  6. Phase 6 - Queue picker: When selecting multiple episodes the user is presented with new option entries on the menu: “Add to queue” and “Move to queue”. These are only shown when more than one queue exists. It also enables the user to send episodes to any queue they want before switching to it and going to each podcasts feed first, which is specially helpful when coming from AntennaPod’s single queue and a large episode list (which is my case as well, I’m guilty).

Granted that phases #3 and #4 are only intended for this fork’s maintenance, and the Docs folder only exists to help anyone reviewing the code understand the reasoning behind any of the decisions implemented, but phases #1 and #2 are straight out of the research done, as asked by moderators and nothing else.

The fork has it’s own needs met to be able to co-exist with upstream, but they are minor and detached from functionality, going beyond the MVP (./Docs folder and changes on the interface on #5 and #6), or creating changes that may impact merging, such as database versioning. These changes could be introduced later as their own PRs, no need to keep them all together.

I’m currently running this on my phone, testing it out and anyone is welcome to join me on this test, but so far everything seems to be working great, no bugs, no issues, none I could see, at least. All in all seems like this could be a candidate for this feature, but I’ll leave it to you guys, specially those who came before me, to test it out and see if it makes sense to us to create a new PR with it.

Hope to hear from you soon, I’m actually quite happy with the result.

The important part here is not writing the code, but doing usability testing and interaction design. How we indicate what the next episode will be, to what playlist something gets added, how to switch between playlists, etc., are quite subtle decisions that can make the app much harder to use when done wrong. Claude can write the code in a couple of minutes, and asking it myself means that I do not have to wait for you to copy my review feedback back into Claude. Feel free to use Claude to write code and get a feeling of the feature, but the first result to discuss should be UX design and a couple of sentences of architecture (not a huge wall of AI generated plans that nobody wants to read). Once we have the design, we need to find some users and do something like a think-aloud study. That kind of stuff is what takes most time, and it is one of the reasons why we didn’t just let Claude add the feature months ago.

Usability tests are a fair point, the very reason I’m reaching out to other users here and to you (moderators) as well.

To add some context: before IT I worked in design and marketing, with companies across tourism, finance, real estate and more, designing UX flows for both internal and external audiences. I know the strategies and tools for gathering information and iterating on it, so that’s where I can actually help. What I can’t do (yet) is write Java myself, so I won’t push code or a PR. The goal has always been to test the feature and see if my reading of years of issues, PRs and discussions points in the right direction, that’s what I meant as “could be candidate”.

UX was a very important part of the implementation in this fork, and using the app with the work Claude did feels right to me, but that’s only one opinion, which is exactly why testing matters. I understand you’re probably dealing with tons of AI PRs that create overhead and waste time, and the intention was never to add another one with a “huge wall of AI generated” anything. The documentation was for me, it’s how I work, and it was never meant for a PR. The fork is a prototype people can actually use, and it stays in sync with upstream: Releases · fogolin/AntennaPod · GitHub. If it doesn’t work out, that’s ok: you can go back to the official app with a database export. Episodes and history are kept, and the queues just get merged into one. This is a starting point, not the destination.

This feature has been discussed over and over for years. For those who don’t want it, the fork shows it’s possible not to impact their flow at all. For those who do (and have been waiting for years), we can find out whether we’re heading in the right direction.

What I can do:

  1. A full UX proposal here: the screens, where episodes get added, and how switching works, building on the impact map @igor posted at the start of this thread.
  2. Suggesting answers to the open questions this fork doesn’t aknowledge yet, mainly how to show what plays next and which queue something was added to, individual settings per queue (sorting and lock). These have been discussed a lot over the years, with multiple suggestions, but no definitive answer, and is yet to be adressed as well.

To test it further, maybe it’d be good to call a town hall to further discuss it?

Would that be a good restarting point for this feature? If you feel like that’s something that might be in the right direction, we can keep talking, testing and iterating on it. That’s all.

Sorry for being a bit harsh there. As you wrote, we are currently flooded with low quality AI generated PRs, and reviewing those is kind of a pain. We also had hours of calls with people already who wanted to work on large features like this, and all ended up disappearing.

I think this goes in the right direction.

When playing an episode, how do you know which one will be next? Eg, can you somehow see which queue is currently active? Is it enough to just mark the active one with some icon? Do we need an indicator on the player screen?

About the design of the queue screen, my first association was that these are filters, not independent queues. In other locations (per podcasts search screen, tags on subscriptions screen) we use those chips for filters, not independent lists. I don’t have a better idea right now, but maybe you have?

I have another open problem. If you look at an episode and see the queue icon, how do you know which queue it is in?

I have the full implementation of multiple queues, plus automatic refill of queues by sets of rules (inspired by my former favourite, BeyondPod). I worked thoroughly on sticking to code reuse, smart use of the storage, migrations and everything. I actually submitted two different implementations but was rejected, so I am the only user of it on my own phone, and nobody else gets to enjoy it.

what I could do is use the latest models (I think I originally implemented with Sonnet 4), ask them to put extra attention to issues like code style, and maybe this time it will be a good one.

If I did submit it again I would start with submitting just the changes to the DB layer, conveting all the functions to support multiple queues but defaulting to queue 1, thn adding the UI in a second PR, then adding the storage changes for the automatic refilling rules, and finally a PR for that UI as well. 4 PRs instead of the 2 I tried to submit.

and yes, it had unit tests. lots of them, maybe too many, and like all y’all hate reviewing those (I usually do it on Python, Terraform and bash code as I’m a DevOps guy, and Java isn’t my bread and butter).

I didn’t write any ADR (today I would), but I can either give you my implementation to reverse engineer or the SDD docs to work with (I use spec-kit). the choices I made are a bit different than yours, for instance I allow adding the same episode to two queues, but if it is 100% played in one, it’s removed from all queues, which is a single SQL query because they are all managed in one table.

If you ask Claude to write it, that causes significantly more work for me than just asking it myself because I always have to wait for you to paste my feedback back into Claude. Or I have to read pages and pages of AI slop plans.

Before we look at any code, we have to look at UX design. AI prototypes might help to get ideas for UX design, but code is not what we are interested in here. Writing code is almost instant now, you don’t help by writing code.

Feel free to contribute to the UX discussion above or share screenshots and ideas behind the UX design of your prototype if you want to help.