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:
parent
a3cfb5ca7e
commit
b868307c0d
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
14
pubspec.lock
14
pubspec.lock
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue