Skip to content

Commit

Permalink
adding missing files. Thanks for the notice, @zaprogrammer!
Browse files Browse the repository at this point in the history
  • Loading branch information
Fitz committed May 6, 2020
1 parent f9ebe07 commit fbb8aa1
Show file tree
Hide file tree
Showing 2 changed files with 243 additions and 0 deletions.
90 changes: 90 additions & 0 deletions lib/notifiers.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import 'dart:async';
import 'dart:io';

import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:webfeed/domain/rss_feed.dart';
import 'package:webfeed/domain/rss_item.dart';

import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
import 'package:webfeed/webfeed.dart';

class Podcast with ChangeNotifier {
EpisodeFeed _feed;
Episode _selectedItem;

EpisodeFeed get feed => _feed;
void parse(String url) async {
final res = await http.get(url);
final xmlStr = res.body;
_feed = EpisodeFeed.parse(xmlStr);
notifyListeners();
}

Episode get selectedItem => _selectedItem;
set selectedItem(Episode value) {
_selectedItem = value;
notifyListeners();
}
}

class EpisodeFeed extends RssFeed {
final RssFeed _feed;
List<Episode> items;

EpisodeFeed(this._feed) {
items = _feed.items.map((i) => Episode(i)).toList();
}

RssImage get image => _feed.image;

static EpisodeFeed parse(xmlStr) {
return EpisodeFeed(RssFeed.parse(xmlStr));
}
}

class Episode extends RssItem with ChangeNotifier {
String downloadLocation;
RssItem _item;

Episode(this._item);

String get title => _item.title;
String get description => _item.description;
String get guid => _item.guid;

void download([Function(double) updates]) async {
final req = http.Request('GET', Uri.parse(_item.guid));
final res = await req.send();
if (res.statusCode != 200)
throw Exception('Unexpected HTTP code: ${res.statusCode}');

final contentLength = res.contentLength;
var downloadedLength = 0;

String filePath = await _getDownloadPath(path.split(_item.guid).last);
final file = File(filePath);
res.stream
.map((chunk) {
downloadedLength += chunk.length;
if (updates != null) updates(downloadedLength / contentLength);
return chunk;
})
.pipe(file.openWrite())
.whenComplete(() {
// TODO save this to sharedprefs or similar.
downloadLocation = filePath;
notifyListeners();
})
.catchError((e) => print('An Error has occurred!!!: $e'));
}

Future<String> _getDownloadPath(String filename) async {
final dir = await getApplicationDocumentsDirectory();
final prefix = dir.path;
final absolutePath = path.join(prefix, filename);
print(absolutePath);
return absolutePath;
}
}
153 changes: 153 additions & 0 deletions lib/player.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:provider/provider.dart';

import 'package:dashcast/notifiers.dart';

class PlayerPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
Provider.of<Podcast>(context).selectedItem.title,
),
),
body: SafeArea(child: Player()),
);
}
}

class Player extends StatelessWidget {
@override
Widget build(BuildContext context) {
final podcast = Provider.of<Podcast>(context);
return Column(
children: [
Flexible(
flex: 8,
child: SingleChildScrollView(
child: Column(children: [
Image.network(podcast.feed.image.url),
Padding(
padding: const EdgeInsets.all(10),
child: Text(
podcast.selectedItem.description.trim(),
),
),
]),
)),
Flexible(
flex: 2,
child: Material(
elevation: 12,
child: AudioControls(),
),
),
],
);
}
}

class AudioControls extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
PlaybackButtons(),
],
);
}
}

class PlaybackButtons extends StatefulWidget {
@override
_PlaybackButtonState createState() => _PlaybackButtonState();
}

class _PlaybackButtonState extends State<PlaybackButtons> {
bool _isPlaying = false;
FlutterSound _sound;
double _playPosition;
StreamSubscription<PlayStatus> _playerSubscription;

@override
void initState() {
super.initState();
_sound = FlutterSound();
_playPosition = 0;
}

@override
void dispose() {
_cleanup();
super.dispose();
}

void _cleanup() async {
if (_sound.audioState == t_AUDIO_STATE.IS_PLAYING)
await _sound.stopPlayer();
// TODO somehow this gets called from episode list and breaks everything.
_playerSubscription.cancel();
}

void _stop() async {
await _sound.stopPlayer();
setState(() => _isPlaying = false);
}

void _play(String url) async {
await _sound.startPlayer(url);
_playerSubscription = _sound.onPlayerStateChanged.listen((e) {
if (e != null) {
// print(e.currentPosition);
setState(() => _playPosition = (e.currentPosition / e.duration));
}
});
setState(() => _isPlaying = true);
}

void _fastForward() {}

void _rewind() {}

@override
Widget build(BuildContext context) {
final podcast = Provider.of<Podcast>(context);
final item = podcast.selectedItem;

return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Slider(
value: _playPosition,
onChanged: null,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
IconButton(icon: Icon(Icons.fast_rewind), onPressed: null),
IconButton(
icon: _isPlaying ? Icon(Icons.stop) : Icon(Icons.play_arrow),
onPressed: () {
if (_isPlaying) {
_stop();
} else {
var url = item.downloadLocation ?? item.guid;
print('Playing url: $url');
_play(url);
}
},
),
IconButton(
icon: Icon(Icons.fast_forward),
onPressed: null,
),
],
),
],
);
}
}

0 comments on commit fbb8aa1

Please sign in to comment.