Skip to content

Conversation

@escamoteur
Copy link
Member

No description provided.

escamoteur and others added 12 commits November 24, 2025 03:42
- Upgraded to command_it 9.4.1 for progress/cancellation support
- Each EpisodeMedia now owns its downloadCommand with built-in progress
- Added PodcastManager.activeDownloads (ListNotifier) to track active downloads
- Renamed DownloadManager → DownloadService (stateless operations only)
- Removed state tracking from DownloadService (no ChangeNotifier, no maps)
- Replaced messageStream with Command.globalErrors for error notifications
- Added isDownloaded getter based on command progress (progress == 1.0)
- Factory constructor pattern for EpisodeMedia (single getDownload call)
- Episodes automatically use local path when downloaded (no copyWithX needed)
- Simplified UI: watch command properties directly

Benefits:
- Commands own execution state (no separate registry)
- Single source of truth for download state
- Better type safety (all ValueListenable<T>)
- Cleaner UI code (no manual state management)
- Real-time progress updates and cancellation support
Move episode and description caching from PodcastService to PodcastManager
to align with architecture pattern where Services are stateless operations
and Managers handle state and caching.

Changes:
- PodcastService.findEpisodes() now returns record with episodes + description
- PodcastManager caches both episodes and descriptions
- Added PodcastManager.getPodcastDescription() method
- Updated UI to use new caching location
- Ensures same episode instances returned from cache for command state consistency

This completes the service/manager separation - all state is now in managers.
…ast card

Converts checkForUpdates() method to checkForUpdatesCommand to eliminate manual lock management and align with command pattern. Refactors podcast_card.dart to use fetchEpisodeMediaCommand with registerHandler for reactive loading dialog and auto-play, replacing direct service calls with proper watch_it observables.
Adds toggle commands for podcast subscriptions and radio favorites to eliminate direct async calls from UI. Inlines command initialization using immediately invoked functions instead of factory methods for consistency with command pattern conventions.

Changes:
- Add togglePodcastCommand to PodcastManager (passes Item object)
- Add toggleFavoriteStationCommand to RadioManager (passes station ID)
- Add deleteDownloadCommand to EpisodeMedia
- Inline downloadCommand and deleteDownloadCommand initialization
- Update all UI components to use .run() instead of direct async calls
- Consistent naming with getSubscribedPodcastsCommand
- Remove redundant undoOnExecutionFailure: true (default)
- Rename podcastsCommand to getSubscribedPodcastsCommand
- Rename togglePodcastCommand to togglePodcastSubscriptionCommand
- Make togglePodcastSubscriptionCommand undoable with optimistic updates
- Add error handler for subscription toggle in PodcastFavoriteButton
- Add optimistic delete for deleteDownloadCommand with rollback on error
- only play on play button
- fix registration
- fix linter
- callOnceAfterThisBuild to avoid marked dirty error
- fix infinite progress loop
Replace showFutureLoadingDialog with registerHandler pattern in
PodcastCardPlayButton. This scopes the auto-play behavior to the
button widget - when PodcastPageEpisodeList fetches episodes via the
same command, the play handler won't fire since the button is in a
different widget tree.

Also inline fetchEpisodes logic back into fetchEpisodeMediaCommand.
Regression fix: After refactoring to command-based downloads, finished
downloads were immediately removed from activeDownloads, causing them
to disappear from the Recent Downloads dialog.

Changes:
- episode_media.dart: Don't remove from activeDownloads on success
  (only remove on error)
- recent_downloads_button.dart: Distinguish between hasAnyDownloads
  (button visibility) and hasInProgressDownloads (animation)

This restores the original behavior where completed downloads remain
visible until the user deletes them or starts a new session.
Add registerActiveDownload/unregisterActiveDownload methods to
PodcastManager instead of letting EpisodeMedia directly manipulate
the list. This improves encapsulation and makes future changes easier.
- Add PodcastProxy class that wraps Item and owns fetchEpisodesCommand
  and playEpisodesCommand (fetch-if-needed then play)
- Replace two caches in PodcastManager with single proxy cache
- Move checkForUpdate logic from proxy to manager as async function
- Add mutable downloadPath to EpisodeMedia for proper download playback
- PlayerManager.setPlaylist now uses downloadPath when available
- Fix RecentDownloadsButton to properly watch ListNotifier
- Fix download button to show spinner immediately when isRunning
- Add error handling for malformed RSS feeds in podcast_service
@Feichtmeier Feichtmeier changed the title Latest oop version refactor: use commands for download progress, fetch episodes inside episodemedias and introduce podcastproxy Nov 27, 2025
@Feichtmeier Feichtmeier merged commit 26b36b6 into main Nov 27, 2025
3 checks passed
@Feichtmeier Feichtmeier deleted the latest-OOP-version branch November 27, 2025 13:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants