modified: README.md

modified:   lib/class/audiostate.dart
	modified:   lib/episodes/episodedetail.dart
	modified:   lib/home/appbar/addpodcast.dart
	modified:   lib/home/audio_player.dart
	modified:   lib/home/home.dart
	modified:   pubspec.lock
	modified:   pubspec.yaml
This commit is contained in:
stonegate 2020-02-14 14:27:40 +08:00
parent a3cfb5ca7e
commit b868307c0d
8 changed files with 313 additions and 179 deletions

View File

@ -1,4 +1,5 @@
# Tsacdop
[![CircleCI](https://circleci.com/gh/stonega/tsacdop.svg?style=svg)](https://circleci.com/gh/stonega/workflows/tsacdop/)
## About
![logo](https://raw.githubusercontent.com/stonega/tsacdop/master/android/app/src/main/res/mipmap-hdpi/ic_launcher.png)

View File

@ -22,10 +22,10 @@ class Urlchange with ChangeNotifier {
_feedTitle = feed;
}
String _imageurl;
String get imageurl => _imageurl;
set imageUrl(String image){
_imageurl = image;
String _primaryColor;
String get primarycolor => _primaryColor;
set primaryColor(String c){
_primaryColor = c;
}
AudioState _audioState;

View File

@ -6,6 +6,7 @@ import 'package:flutter_html/flutter_html.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:path_provider/path_provider.dart';
import 'package:tsacdop/class/audiostate.dart';
import 'package:tsacdop/class/episodebrief.dart';
import 'package:tsacdop/class/sqflite_localpodcast.dart';
@ -26,7 +27,6 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
final textstyle = TextStyle(fontSize: 15.0, color: Colors.black);
double downloadProgress;
bool _loaddes;
Future getSDescription(String title) async {
var dbHelper = DBHelper();
widget.episodeItem.description = await dbHelper.getDescription(title);
@ -286,7 +286,8 @@ class _MenuBarState extends State<MenuBar> {
urlChange.audioUrl = widget.episodeItem.enclosureUrl;
urlChange.rssTitle = widget.episodeItem.title;
urlChange.feedTitle = widget.episodeItem.feedTitle;
urlChange.imageUrl = widget.episodeItem.imageUrl;
urlChange.primaryColor = widget.episodeItem.primaryColor;
print('Playing');
},
child: Container(
height: 50.0,
@ -355,7 +356,7 @@ class _LineLoaderState extends State<LineLoader>
void initState() {
super.initState();
controller = AnimationController(
vsync: this, duration: Duration(milliseconds: 1000));
vsync: this, duration: Duration(milliseconds: 500));
animation = Tween(begin: 0.0, end: 1.0).animate(controller)
..addListener(() {
if (mounted)
@ -492,6 +493,7 @@ class _ImageRotateState extends State<ImageRotate>
@override
void initState() {
super.initState();
_value = 0;
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 2000),

View File

@ -16,7 +16,9 @@ import 'package:tsacdop/class/podcastlocal.dart';
import 'package:tsacdop/class/sqflite_localpodcast.dart';
import 'package:tsacdop/home/home.dart';
import 'package:tsacdop/home/appbar/popupmenu.dart';
import 'package:tsacdop/util/pageroute.dart';
import 'package:tsacdop/webfeed/webfeed.dart';
import 'package:tsacdop/home/audiopanel.dart';
class MyHomePage extends StatefulWidget {
@override
@ -29,9 +31,7 @@ class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => ImportOmpl(),
child: Scaffold(
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
elevation: 0,
@ -56,7 +56,6 @@ class _MyHomePageState extends State<MyHomePage> {
],
),
body: Home(),
),
);
}
}

View File

@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:provider/provider.dart';
@ -11,6 +12,7 @@ import 'package:marquee/marquee.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:tsacdop/class/audiostate.dart';
import 'package:tsacdop/home/audiopanel.dart';
final Logger _logger = Logger('audiofileplayer');
@ -37,12 +39,15 @@ class _PlayerWidgetState extends State<PlayerWidget> {
String _title;
String _feedtitle;
bool _isLoading;
String _primaryColor;
Color _c;
@override
void initState() {
super.initState();
AudioSystem.instance.addMediaEventListener(_mediaEventListener);
_isLoading = false;
_remoteAudioLoading = true;
}
void _initbackgroundAudioPlayer(String url) {
@ -170,6 +175,12 @@ class _PlayerWidgetState extends State<PlayerWidget> {
this.url = url;
_title = Provider.of<Urlchange>(context).title;
_feedtitle = Provider.of<Urlchange>(context).feedtitle;
_primaryColor = Provider.of<Urlchange>(context).primarycolor;
var color = json.decode(_primaryColor);
(color[0] > 200 && color[1] > 200 && color[2] > 200)
? _c = Color.fromRGBO(
(255 - color[0]), 255 - color[1], 255 - color[2], 1.0)
: _c = Color.fromRGBO(color[0], color[1], color[2], 1.0);
_backgroundAudioPlaying = true;
_isLoading = true;
_getFile(url).then((result) {
@ -358,151 +369,255 @@ class _PlayerWidgetState extends State<PlayerWidget> {
AudioSystem.instance.setPlaybackState(true, forwardposition);
}
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => Urlchange(),
child: !_isLoading
? Center()
: Container(
padding: EdgeInsets.symmetric(horizontal: 10.0),
color: Colors.grey[100],
height: 120.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
Widget _expandedPanel() => Container(
height: 300,
color: Colors.grey[100],
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.all(30),
alignment: Alignment.center,
child: (_title.length > 50)
? Marquee(
text: _title,
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 35),
scrollAxis: Axis.horizontal,
crossAxisAlignment: CrossAxisAlignment.start,
blankSpace: 30.0,
velocity: 50.0,
pauseAfterRound: Duration(seconds: 1),
startPadding: 30.0,
accelerationDuration: Duration(seconds: 1),
accelerationCurve: Curves.linear,
decelerationDuration: Duration(milliseconds: 500),
decelerationCurve: Curves.easeOut,
)
: Text(
_title,
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 20),
),
),
Container(
padding: EdgeInsets.only(left: 40, right: 40, top: 20),
child: SliderTheme(
data: SliderTheme.of(context).copyWith(
activeTrackColor: Colors.blue[100],
inactiveTrackColor: Colors.grey[300],
trackHeight: 3.0,
thumbColor: Colors.blue[400],
thumbShape:
RoundSliderThumbShape(enabledThumbRadius: 6.0),
overlayColor: Colors.blue.withAlpha(32),
overlayShape:
RoundSliderOverlayShape(overlayRadius: 14.0),
),
child: Slider(
value: _seekSliderValue,
onChanged: (double val) {
setState(() => _seekSliderValue = val);
final double positionSeconds =
val * _backgroundAudioDurationSeconds;
_backgroundAudio.seek(positionSeconds);
AudioSystem.instance
.setPlaybackState(true, positionSeconds);
}),
),
),
Container(
height: 20.0,
padding: EdgeInsets.symmetric(horizontal: 50.0),
child: Row(
children: <Widget>[
Text(
_stringForSeconds(_backgroundAudioPositionSeconds) ??
'',
style: TextStyle(fontSize: 10),
),
Expanded(
child: Container(
alignment: Alignment.center,
child: _remoteErrorMessage != null
? Text(_remoteErrorMessage,
style: const TextStyle(
color: const Color(0xFFFF0000)))
: Text(
_remoteAudioLoading ? 'Buffring...' : '',
style: TextStyle(color: Colors.blue),
),
),
),
Text(
_stringForSeconds(_backgroundAudioDurationSeconds) ??
'',
style: TextStyle(fontSize: 10),
),
],
),
),
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
child: _remoteErrorMessage != null
? Text(_remoteErrorMessage,
style: const TextStyle(
color: const Color(0xFFFF0000)))
: Text(
_remoteAudioLoading ? 'Buffring...' : '',
style: TextStyle(color: Colors.blue),
),
),
SliderTheme(
data: SliderTheme.of(context).copyWith(
activeTrackColor: Colors.blue[100],
inactiveTrackColor: Colors.grey[300],
trackHeight: 2.0,
thumbColor: Colors.blue[400],
thumbShape:
RoundSliderThumbShape(enabledThumbRadius: 5.0),
overlayColor: Colors.blue.withAlpha(32),
overlayShape:
RoundSliderOverlayShape(overlayRadius: 14.0),
),
child: Slider(
value: _seekSliderValue,
onChanged: (double val) {
setState(() => _seekSliderValue = val);
final double positionSeconds =
val * _backgroundAudioDurationSeconds;
_backgroundAudio.seek(positionSeconds);
AudioSystem.instance
.setPlaybackState(true, positionSeconds);
}),
),
Container(
height: 20.0,
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: Row(
children: <Widget>[
Text(
_stringForSeconds(
_backgroundAudioPositionSeconds) ??
'',
style: TextStyle(fontSize: 10),
),
Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 30),
alignment: Alignment.center,
child: (_title.length > 50)
? Marquee(
text: _title,
style:
TextStyle(fontWeight: FontWeight.bold),
scrollAxis: Axis.horizontal,
crossAxisAlignment:
CrossAxisAlignment.start,
blankSpace: 30.0,
velocity: 50.0,
pauseAfterRound: Duration(seconds: 1),
startPadding: 30.0,
accelerationDuration: Duration(seconds: 1),
accelerationCurve: Curves.linear,
decelerationDuration:
Duration(milliseconds: 500),
decelerationCurve: Curves.easeOut,
)
: Text(
_title,
style:
TextStyle(fontWeight: FontWeight.bold),
),
)),
Text(
_stringForSeconds(
_backgroundAudioDurationSeconds) ??
'',
style: TextStyle(fontSize: 10),
),
],
),
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
children: [
IconButton(
padding: EdgeInsets.symmetric(horizontal: 30.0),
onPressed: _backgroundAudioPlaying
? () => _forwardBackgroundAudio(-10)
: null,
iconSize: 32.0,
icon: Icon(Icons.replay_10),
color: Colors.black),
_backgroundAudioPlaying
? IconButton(
padding: EdgeInsets.symmetric(horizontal: 30.0),
onPressed: _backgroundAudioPlaying
? () => _forwardBackgroundAudio(-10)
? () {
_pauseBackgroundAudio();
}
: null,
iconSize: 25.0,
icon: Icon(Icons.replay_10),
color: Colors.black),
_backgroundAudioPlaying
? IconButton(
padding: EdgeInsets.symmetric(horizontal: 30.0),
onPressed: _backgroundAudioPlaying
? () {
_pauseBackgroundAudio();
}
: null,
iconSize: 32.0,
icon: Icon(Icons.pause_circle_filled),
color: Colors.black)
: IconButton(
padding: EdgeInsets.symmetric(horizontal: 30.0),
onPressed: _backgroundAudioPlaying
? null
: () {
_resumeBackgroundAudio();
},
iconSize: 32.0,
icon: Icon(Icons.play_circle_filled),
color: Colors.black),
IconButton(
iconSize: 40.0,
icon: Icon(Icons.pause_circle_filled),
color: Colors.black)
: IconButton(
padding: EdgeInsets.symmetric(horizontal: 30.0),
onPressed: _backgroundAudioPlaying
? null
: () {
_resumeBackgroundAudio();
},
iconSize: 40.0,
icon: Icon(Icons.play_circle_filled),
color: Colors.black),
IconButton(
padding: EdgeInsets.symmetric(horizontal: 30.0),
onPressed: _backgroundAudioPlaying
? () => _forwardBackgroundAudio(30)
: null,
iconSize: 32.0,
icon: Icon(Icons.forward_30),
color: Colors.black),
],
),
]),
);
Widget _miniPanel() => Container(
height: 60,
color: Colors.grey[100],
child: Column(mainAxisAlignment: MainAxisAlignment.start, children: <
Widget>[
SizedBox(
height: 2,
child: LinearProgressIndicator(
value: _seekSliderValue,
backgroundColor: Colors.grey[100],
valueColor: AlwaysStoppedAnimation<Color>(_c),
)),
Expanded(
child: Container(
padding: EdgeInsets.only(left: 30.0, right: 10.0),
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 220,
child: (_title.length > 30)
? Marquee(
text: _title,
style: TextStyle(fontWeight: FontWeight.bold),
scrollAxis: Axis.horizontal,
crossAxisAlignment: CrossAxisAlignment.start,
blankSpace: 30.0,
velocity: 50.0,
pauseAfterRound: Duration(seconds: 1),
startPadding: 30.0,
accelerationDuration: Duration(seconds: 1),
accelerationCurve: Curves.linear,
decelerationDuration: Duration(milliseconds: 500),
decelerationCurve: Curves.easeOut,
)
: Text(
_title,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Spacer(),
Container(
padding: EdgeInsets.symmetric(horizontal: 20.0),
child: Row(
children: <Widget>[
Text(
_stringForSeconds(_backgroundAudioDurationSeconds -
_backgroundAudioPositionSeconds) ??
'',
style: TextStyle(color: _c),
),
Text(
' Left',
style: TextStyle(color: _c),
),
],
),
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
_backgroundAudioPlaying
? Material(
color: Colors.transparent,
child: IconButton(
padding:
EdgeInsets.symmetric(horizontal: 10.0),
onPressed: _backgroundAudioPlaying
? () {
_pauseBackgroundAudio();
}
: null,
iconSize: 28.0,
icon: Icon(Icons.pause_circle_filled),
color: Colors.black),
)
: Material(
color: Colors.transparent,
child: IconButton(
padding:
EdgeInsets.symmetric(horizontal: 10.0),
onPressed: _backgroundAudioPlaying
? null
: () {
_resumeBackgroundAudio();
},
iconSize: 25.0,
icon: Icon(Icons.play_circle_filled),
color: Colors.black),
),
Material(
color: Colors.transparent,
child: IconButton(
padding: EdgeInsets.symmetric(horizontal: 10.0),
onPressed: _backgroundAudioPlaying
? () => _forwardBackgroundAudio(30)
: null,
iconSize: 25.0,
icon: Icon(Icons.forward_30),
color: Colors.black),
/*IconButton(
onPressed: _isPlaying || _isPaused ? () => _stop() : null,
iconSize: 32.0,
icon: Icon(Icons.stop),
color: Colors.black), */
],
),
]),
),
],
),
],
),
),
);
),
]),
);
@override
Widget build(BuildContext context) {
return !_isLoading
? Center()
: AudioPanel(miniPanel: _miniPanel(), expandedPanel: _expandedPanel());
}
}

View File

@ -18,41 +18,43 @@ class Home extends StatefulWidget {
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => Urlchange(),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Import(),
Container(
height: 30,
padding: EdgeInsets.symmetric(horizontal: 15),
alignment: Alignment.bottomRight,
child: GestureDetector(
onTap: () {
Navigator.push(
context,
SlideLeftRoute(page: Podcast()),
);
},
child: Container(
height: 30,
padding: EdgeInsets.all(5.0),
child: Text('See All',
style: TextStyle(
color: Colors.red[300],
fontWeight: FontWeight.bold,
)),
),
return Stack(children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Import(),
Container(
height: 30,
padding: EdgeInsets.symmetric(horizontal: 15),
alignment: Alignment.bottomRight,
child: GestureDetector(
onTap: () {
Navigator.push(
context,
SlideLeftRoute(page: Podcast()),
);
},
child: Container(
height: 30,
padding: EdgeInsets.all(5.0),
child: Text('See All',
style: TextStyle(
color: Colors.red[300],
fontWeight: FontWeight.bold,
)),
),
),
Container(child: ScrollPodcasts()),
Expanded(
child: MainTab(),
),
PlayerWidget(),
],
));
),
Container(child: ScrollPodcasts()),
Expanded(
child: MainTab(),
),
],
),
Container(
alignment: Alignment.bottomCenter,
child: PlayerWidget()),
]);
}
}

View File

@ -1,6 +1,13 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
after_layout:
dependency: transitive
description:
name: after_layout
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.7+2"
archive:
dependency: transitive
description:
@ -317,6 +324,13 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.5"
rubber:
dependency: "direct dev"
description:
name: rubber
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.4.0"
sky_engine:
dependency: transitive
description: flutter

View File

@ -49,6 +49,7 @@ dev_dependencies:
intl: ^0.16.1
url_launcher: ^5.4.1
image: ^2.1.4
rubber: ^0.4.0
# For information on the generic Dart part of this file, see the