added cargo files
This commit is contained in:
125
PinePods-0.8.2/mobile/lib/bloc/podcast/episode_bloc.dart
Normal file
125
PinePods-0.8.2/mobile/lib/bloc/podcast/episode_bloc.dart
Normal file
@@ -0,0 +1,125 @@
|
||||
// Copyright 2020 Ben Hills and the project contributors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:pinepods_mobile/bloc/bloc.dart';
|
||||
import 'package:pinepods_mobile/entities/episode.dart';
|
||||
import 'package:pinepods_mobile/services/audio/audio_player_service.dart';
|
||||
import 'package:pinepods_mobile/services/podcast/podcast_service.dart';
|
||||
import 'package:pinepods_mobile/state/bloc_state.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
|
||||
/// The BLoC provides access to [Episode] details outside the direct scope
|
||||
/// of a [Podcast].
|
||||
class EpisodeBloc extends Bloc {
|
||||
final log = Logger('EpisodeBloc');
|
||||
final PodcastService podcastService;
|
||||
final AudioPlayerService audioPlayerService;
|
||||
|
||||
/// Add to sink to fetch list of current downloaded episodes.
|
||||
final BehaviorSubject<bool> _downloadsInput = BehaviorSubject<bool>();
|
||||
|
||||
/// Add to sink to fetch list of current episodes.
|
||||
final BehaviorSubject<bool> _episodesInput = BehaviorSubject<bool>();
|
||||
|
||||
/// Add to sink to delete the passed [Episode] from storage.
|
||||
final PublishSubject<Episode?> _deleteDownload = PublishSubject<Episode>();
|
||||
|
||||
/// Add to sink to toggle played status of the [Episode].
|
||||
final PublishSubject<Episode?> _togglePlayed = PublishSubject<Episode>();
|
||||
|
||||
/// Stream of currently downloaded episodes
|
||||
Stream<BlocState<List<Episode>>>? _downloadsOutput;
|
||||
|
||||
/// Stream of current episodes
|
||||
Stream<BlocState<List<Episode>>>? _episodesOutput;
|
||||
|
||||
/// Cache of our currently downloaded episodes.
|
||||
List<Episode>? _episodes;
|
||||
|
||||
EpisodeBloc({
|
||||
required this.podcastService,
|
||||
required this.audioPlayerService,
|
||||
}) {
|
||||
_init();
|
||||
}
|
||||
|
||||
void _init() {
|
||||
_downloadsOutput = _downloadsInput.switchMap<BlocState<List<Episode>>>((bool silent) => _loadDownloads(silent));
|
||||
_episodesOutput = _episodesInput.switchMap<BlocState<List<Episode>>>((bool silent) => _loadEpisodes(silent));
|
||||
|
||||
_handleDeleteDownloads();
|
||||
_handleMarkAsPlayed();
|
||||
_listenEpisodeEvents();
|
||||
}
|
||||
|
||||
void _handleDeleteDownloads() async {
|
||||
_deleteDownload.stream.listen((episode) async {
|
||||
var nowPlaying = audioPlayerService.nowPlaying?.guid == episode?.guid;
|
||||
|
||||
/// If we are attempting to delete the episode we are currently playing, we need to stop the audio.
|
||||
if (nowPlaying) {
|
||||
await audioPlayerService.stop();
|
||||
}
|
||||
|
||||
await podcastService.deleteDownload(episode!);
|
||||
|
||||
fetchDownloads(true);
|
||||
});
|
||||
}
|
||||
|
||||
void _handleMarkAsPlayed() async {
|
||||
_togglePlayed.stream.listen((episode) async {
|
||||
await podcastService.toggleEpisodePlayed(episode!);
|
||||
|
||||
fetchDownloads(true);
|
||||
});
|
||||
}
|
||||
|
||||
void _listenEpisodeEvents() {
|
||||
// Listen for episode updates. If the episode is downloaded, we need to update.
|
||||
podcastService.episodeListener!.where((event) => event.episode.downloaded || event.episode.played).listen((event) => fetchDownloads(true));
|
||||
}
|
||||
|
||||
Stream<BlocState<List<Episode>>> _loadDownloads(bool silent) async* {
|
||||
if (!silent) {
|
||||
yield BlocLoadingState();
|
||||
}
|
||||
|
||||
_episodes = await podcastService.loadDownloads();
|
||||
|
||||
yield BlocPopulatedState<List<Episode>>(results: _episodes);
|
||||
}
|
||||
|
||||
Stream<BlocState<List<Episode>>> _loadEpisodes(bool silent) async* {
|
||||
if (!silent) {
|
||||
yield BlocLoadingState();
|
||||
}
|
||||
|
||||
_episodes = await podcastService.loadEpisodes();
|
||||
|
||||
yield BlocPopulatedState<List<Episode>>(results: _episodes);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_downloadsInput.close();
|
||||
_deleteDownload.close();
|
||||
_togglePlayed.close();
|
||||
}
|
||||
|
||||
void Function(bool) get fetchDownloads => _downloadsInput.add;
|
||||
|
||||
void Function(bool) get fetchEpisodes => _episodesInput.add;
|
||||
|
||||
Stream<BlocState<List<Episode>>>? get downloads => _downloadsOutput;
|
||||
|
||||
Stream<BlocState<List<Episode>>>? get episodes => _episodesOutput;
|
||||
|
||||
void Function(Episode?) get deleteDownload => _deleteDownload.add;
|
||||
|
||||
void Function(Episode?) get togglePlayed => _togglePlayed.add;
|
||||
}
|
||||
Reference in New Issue
Block a user