Add feed titile in episode page, tap avatar to open podcast page.
This commit is contained in:
parent
e62c222efe
commit
06ec6ee5a1
|
@ -1,28 +0,0 @@
|
|||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: cirrusci/flutter:stable
|
||||
|
||||
branches:
|
||||
only: master
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Run Flutter doctor
|
||||
command: flutter doctor
|
||||
- run:
|
||||
name: Update package
|
||||
command: flutter pub upgrade
|
||||
- run: echo $ENCODED_KEYSTORE | base64 -di > ${HOME}/keystore.jks
|
||||
- run: echo 'export KEYSTORE=${HOME}/keystore.jks' >> $BASH_ENV
|
||||
- run: dart tool/env.dart
|
||||
- run:
|
||||
name: Build the Android apk
|
||||
command: flutter build apk --split-per-abi --obfuscate --split-debug-info=debug/
|
||||
- run:
|
||||
name: Build the Android version
|
||||
command: flutter build appbundle --obfuscate --split-debug-info=debug/
|
||||
- store_artifacts:
|
||||
path: build/app/outputs/
|
|
@ -114,7 +114,13 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
|
|||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)
|
||||
: Center(),
|
||||
: Text(
|
||||
widget.episodeItem.feedTitle,
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
color: context.textColor.withOpacity(0.7)),
|
||||
),
|
||||
leading: CustomBackButton(),
|
||||
elevation: _showTitle ? 1 : 0,
|
||||
//actions: [
|
||||
|
@ -175,6 +181,7 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
|
|||
scrollDirection: Axis.vertical,
|
||||
controller: _controller,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.0),
|
||||
|
@ -187,30 +194,28 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
|
|||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: EdgeInsets.only(
|
||||
left: 20.0, right: 20, top: 10, bottom: 10),
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(20, 10, 20, 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
s.published(DateFormat.yMMMd().format(
|
||||
DateTime.fromMillisecondsSinceEpoch(
|
||||
widget.episodeItem.pubDate))),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).accentColor)),
|
||||
style: TextStyle(color: context.accentColor)),
|
||||
SizedBox(width: 10),
|
||||
if (widget.episodeItem.explicit == 1)
|
||||
Text('E',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.red))
|
||||
color: Colors.red)),
|
||||
Spacer(),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: 20.0, right: 20, top: 5, bottom: 5),
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: 20, vertical: 5),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
if (widget.episodeItem.duration != 0)
|
||||
|
|
|
@ -8,6 +8,8 @@ import 'package:flutter/services.dart';
|
|||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:line_icons/line_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tsacdop/podcasts/podcast_detail.dart';
|
||||
import 'package:tsacdop/util/pageroute.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
import '../local_storage/key_value_storage.dart';
|
||||
|
@ -975,74 +977,6 @@ class _RecentUpdateState extends State<_RecentUpdate>
|
|||
SliverToBoxAdapter(
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
// color: context.primaryColor,
|
||||
// child: Material(
|
||||
// color: Colors.transparent,
|
||||
// child: Row(
|
||||
// children: <Widget>[
|
||||
// _switchGroupButton(),
|
||||
// Spacer(),
|
||||
// _addNewButton(),
|
||||
// Material(
|
||||
// color: Colors.transparent,
|
||||
// child: IconButton(
|
||||
// tooltip: s
|
||||
// .hideListenedSetting,
|
||||
// icon: SizedBox(
|
||||
// width: 30,
|
||||
// height: 15,
|
||||
// child: HideListened(
|
||||
// hideListened:
|
||||
// _hideListened ??
|
||||
// false,
|
||||
// ),
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// setState(() =>
|
||||
// _hideListened =
|
||||
// !_hideListened);
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// Material(
|
||||
// color: Colors.transparent,
|
||||
// child: LayoutButton(
|
||||
// layout: _layout,
|
||||
// onPressed: (layout) =>
|
||||
// setState(() {
|
||||
// _layout = layout;
|
||||
// }),
|
||||
// ),
|
||||
// ),
|
||||
// Material(
|
||||
// color:
|
||||
// Colors.transparent,
|
||||
// clipBehavior:
|
||||
// Clip.hardEdge,
|
||||
// borderRadius:
|
||||
// BorderRadius
|
||||
// .circular(100),
|
||||
// child: IconButton(
|
||||
// icon: SizedBox(
|
||||
// width: 20,
|
||||
// height: 10,
|
||||
// child: CustomPaint(
|
||||
// painter: MultiSelectPainter(
|
||||
// color: context
|
||||
// .accentColor)),
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// setState(() {
|
||||
// _selectedEpisodes =
|
||||
// [];
|
||||
// _multiSelect =
|
||||
// true;
|
||||
// });
|
||||
// },
|
||||
// )),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
),
|
||||
),
|
||||
EpisodeGrid(
|
||||
|
@ -1050,6 +984,7 @@ class _RecentUpdateState extends State<_RecentUpdate>
|
|||
layout: _layout,
|
||||
initNum: _scroll ? 0 : 12,
|
||||
multiSelect: _multiSelect,
|
||||
openPodcast: true,
|
||||
selectedList:
|
||||
_selectedEpisodes ?? [],
|
||||
onSelect: (value) => setState(() {
|
||||
|
@ -1272,6 +1207,7 @@ class _MyFavoriteState extends State<_MyFavorite>
|
|||
episodes: snapshot.data,
|
||||
layout: _layout,
|
||||
initNum: 0,
|
||||
openPodcast: true,
|
||||
multiSelect: _multiSelect,
|
||||
selectedList: _selectedEpisodes ?? [],
|
||||
onSelect: (value) => setState(() {
|
||||
|
@ -1549,6 +1485,7 @@ class _MyDownloadState extends State<_MyDownload>
|
|||
: EpisodeGrid(
|
||||
episodes: episodes,
|
||||
layout: _layout,
|
||||
openPodcast: true,
|
||||
initNum: 0,
|
||||
),
|
||||
],
|
||||
|
|
|
@ -91,7 +91,7 @@ class DBHelper {
|
|||
list = await dbClient.rawQuery(
|
||||
"""SELECT id, title, imageUrl, rssUrl, primaryColor, author, imagePath , provider,
|
||||
link ,update_count, episode_count FROM PodcastLocal WHERE id = ? AND
|
||||
never_update = 0""", [s]);
|
||||
never_update = 1""", [s]);
|
||||
} else {
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT id, title, imageUrl, rssUrl, primaryColor, author, imagePath , provider,
|
||||
|
@ -149,6 +149,29 @@ class DBHelper {
|
|||
return podcastLocal;
|
||||
}
|
||||
|
||||
Future<PodcastLocal> getPodcastWithUrl(String url) async {
|
||||
var dbClient = await database;
|
||||
List<Map> list = await dbClient.rawQuery(
|
||||
"""SELECT P.id, P.title, P.imageUrl, P.rssUrl, P.primaryColor, P.author, P.imagePath,
|
||||
P.provider, P.link ,P.update_count, P.episode_count FROM PodcastLocal P INNER JOIN
|
||||
Episodes E ON P.id = E.feed_id WHERE E.enclosure_url = ?""", [url]);
|
||||
if (list.isNotEmpty) {
|
||||
return PodcastLocal(
|
||||
list.first['title'],
|
||||
list.first['imageUrl'],
|
||||
list.first['rssUrl'],
|
||||
list.first['primaryColor'],
|
||||
list.first['author'],
|
||||
list.first['id'],
|
||||
list.first['imagePath'],
|
||||
list.first['provider'],
|
||||
list.first['link'],
|
||||
upateCount: list.first['update_count'],
|
||||
episodeCount: list.first['episode_count']);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<int> getPodcastCounts(String id) async {
|
||||
var dbClient = await database;
|
||||
List<Map> list = await dbClient
|
||||
|
|
|
@ -16,14 +16,17 @@ import '../episodes/episode_detail.dart';
|
|||
import '../home/audioplayer.dart';
|
||||
import '../local_storage/key_value_storage.dart';
|
||||
import '../local_storage/sqflite_localpodcast.dart';
|
||||
import '../podcasts/podcast_detail.dart';
|
||||
import '../state/audio_state.dart';
|
||||
import '../state/download_state.dart';
|
||||
import '../type/episodebrief.dart';
|
||||
import '../type/play_histroy.dart';
|
||||
import '../type/podcastlocal.dart';
|
||||
import 'custom_widget.dart';
|
||||
import 'extension_helper.dart';
|
||||
import 'general_dialog.dart';
|
||||
import 'open_container.dart';
|
||||
import 'pageroute.dart';
|
||||
|
||||
enum Layout { three, two, one }
|
||||
|
||||
|
@ -38,6 +41,7 @@ class EpisodeGrid extends StatelessWidget {
|
|||
final bool reverse;
|
||||
final bool multiSelect;
|
||||
final ValueChanged<List<EpisodeBrief>> onSelect;
|
||||
final bool openPodcast;
|
||||
final List<EpisodeBrief> selectedList;
|
||||
|
||||
/// Count of animation items.
|
||||
|
@ -53,16 +57,17 @@ class EpisodeGrid extends StatelessWidget {
|
|||
this.episodeCount = 0,
|
||||
this.layout = Layout.three,
|
||||
this.reverse,
|
||||
this.openPodcast = false,
|
||||
this.multiSelect = false,
|
||||
this.onSelect,
|
||||
this.selectedList})
|
||||
: super(key: key);
|
||||
|
||||
List<EpisodeBrief> _selectedList = [];
|
||||
final _dbHelper = DBHelper();
|
||||
|
||||
Future<int> _isListened(EpisodeBrief episode) async {
|
||||
var dbHelper = DBHelper();
|
||||
return await dbHelper.isListened(episode.enclosureUrl);
|
||||
return await _dbHelper.isListened(episode.enclosureUrl);
|
||||
}
|
||||
|
||||
Future<Tuple5<int, bool, bool, bool, List<int>>> _initData(
|
||||
|
@ -76,8 +81,7 @@ class EpisodeGrid extends StatelessWidget {
|
|||
}
|
||||
|
||||
Future<bool> _isLiked(EpisodeBrief episode) async {
|
||||
var dbHelper = DBHelper();
|
||||
return await dbHelper.isLiked(episode.enclosureUrl);
|
||||
return await _dbHelper.isLiked(episode.enclosureUrl);
|
||||
}
|
||||
|
||||
Future<List<int>> _getEpisodeMenu() async {
|
||||
|
@ -87,8 +91,7 @@ class EpisodeGrid extends StatelessWidget {
|
|||
}
|
||||
|
||||
Future<bool> _isDownloaded(EpisodeBrief episode) async {
|
||||
var dbHelper = DBHelper();
|
||||
return await dbHelper.isDownloaded(episode.enclosureUrl);
|
||||
return await _dbHelper.isDownloaded(episode.enclosureUrl);
|
||||
}
|
||||
|
||||
Future<bool> _getTapToOpenPopupMenu() async {
|
||||
|
@ -98,24 +101,20 @@ class EpisodeGrid extends StatelessWidget {
|
|||
}
|
||||
|
||||
Future<void> _markListened(EpisodeBrief episode) async {
|
||||
var dbHelper = DBHelper();
|
||||
final history = PlayHistory(episode.title, episode.enclosureUrl, 0, 1);
|
||||
await dbHelper.saveHistory(history);
|
||||
await _dbHelper.saveHistory(history);
|
||||
}
|
||||
|
||||
Future<void> _markNotListened(String url) async {
|
||||
var dbHelper = DBHelper();
|
||||
await dbHelper.markNotListened(url);
|
||||
await _dbHelper.markNotListened(url);
|
||||
}
|
||||
|
||||
Future<void> _saveLiked(String url) async {
|
||||
var dbHelper = DBHelper();
|
||||
await dbHelper.setLiked(url);
|
||||
await _dbHelper.setLiked(url);
|
||||
}
|
||||
|
||||
Future<void> _setUnliked(String url) async {
|
||||
var dbHelper = DBHelper();
|
||||
await dbHelper.setUniked(url);
|
||||
await _dbHelper.setUniked(url);
|
||||
}
|
||||
|
||||
Future<void> _requestDownload(BuildContext context,
|
||||
|
@ -186,6 +185,11 @@ class EpisodeGrid extends StatelessWidget {
|
|||
return ifUseData;
|
||||
}
|
||||
|
||||
Future<PodcastLocal> _getPodcast(String url) async {
|
||||
var podcasts = await _dbHelper.getPodcastWithUrl(url);
|
||||
return podcasts;
|
||||
}
|
||||
|
||||
/// Episode title widget.
|
||||
Widget _title(EpisodeBrief episode) => Container(
|
||||
alignment:
|
||||
|
@ -202,7 +206,20 @@ class EpisodeGrid extends StatelessWidget {
|
|||
/// Circel avatar widget.
|
||||
Widget _circleImage(BuildContext context,
|
||||
{EpisodeBrief episode, Color color, bool boo, double radius}) =>
|
||||
Container(
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
if (openPodcast) {
|
||||
final podcast = await _getPodcast(episode.enclosureUrl);
|
||||
Navigator.push(
|
||||
context,
|
||||
SlideLeftRoute(
|
||||
page: PodcastDetail(
|
||||
podcastLocal: podcast,
|
||||
)),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
height: radius ?? context.width / 16,
|
||||
width: radius ?? context.width / 16,
|
||||
child: boo
|
||||
|
@ -210,6 +227,7 @@ class EpisodeGrid extends StatelessWidget {
|
|||
: CircleAvatar(
|
||||
backgroundColor: color.withOpacity(0.5),
|
||||
backgroundImage: episode.avatarImage),
|
||||
),
|
||||
);
|
||||
|
||||
Widget _downloadIndicater(BuildContext context,
|
||||
|
|
Loading…
Reference in New Issue