diff --git a/lib/pages/audio/controller.dart b/lib/pages/audio/controller.dart index f4e5828c..11bd3d7f 100644 --- a/lib/pages/audio/controller.dart +++ b/lib/pages/audio/controller.dart @@ -583,13 +583,13 @@ class AudioController extends GetxController return false; } - void playIndex(int index) { - if (index == this.index) return; + void playIndex(int index, {List? subId}) { + if (index == this.index && subId == null) return; this.index = index; final audioItem = playlist![index]; final item = audioItem.item; oid = item.oid; - subId = item.subId; + this.subId = subId ?? item.subId; itemType = item.itemType; _queryPlayUrl().then((res) { if (res) { diff --git a/lib/pages/audio/view.dart b/lib/pages/audio/view.dart index 9b16c048..10cc9b2e 100644 --- a/lib/pages/audio/view.dart +++ b/lib/pages/audio/view.dart @@ -147,7 +147,8 @@ class _AudioPageState extends State { maxWidth: min(640, context.mediaQueryShortestSide), ), builder: (context) { - final colorScheme = ColorScheme.of(context); + final theme = Theme.of(context); + final colorScheme = theme.colorScheme; return FractionallySizedBox( heightFactor: !context.mediaQuerySize.isPortrait && Utils.isMobile ? 1.0 @@ -177,101 +178,200 @@ class _AudioPageState extends State { Expanded( child: Material( type: MaterialType.transparency, - child: refreshIndicator( - onRefresh: () => _controller.loadPrev(context), - child: CustomScrollView( - controller: scrollController, - physics: _controller.reachStart - ? const ClampingScrollPhysics() - : const AlwaysScrollableScrollPhysics( - parent: ClampingScrollPhysics(), + child: Theme( + data: theme.copyWith( + dividerColor: Colors.transparent, + ), + child: refreshIndicator( + onRefresh: () => _controller.loadPrev(context), + child: CustomScrollView( + controller: scrollController, + physics: _controller.reachStart + ? const ClampingScrollPhysics() + : const AlwaysScrollableScrollPhysics( + parent: ClampingScrollPhysics(), + ), + slivers: [ + SliverPadding( + padding: EdgeInsets.only( + bottom: + MediaQuery.paddingOf(context).bottom + 100, ), - slivers: [ - SliverPadding( - padding: EdgeInsets.only( - bottom: - MediaQuery.paddingOf(context).bottom + 100, - ), - sliver: SliverList.builder( - itemCount: playlist.length, - itemBuilder: (_, index) { - if (index == playlist.length - 1) { - _controller.loadNext(context); - } - final isCurr = index == _controller.index; - final item = playlist[index]; - return ListTile( - dense: true, - minTileHeight: 45, - onTap: () { - Get.back(); - if (!isCurr) { - _controller.playIndex(index); - } - }, - title: Text.rich( - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: isCurr - ? TextStyle( - height: 1, - fontSize: 14, - color: colorScheme.primary, - fontWeight: FontWeight.bold, - ) - : const TextStyle( - height: 1, - fontSize: 14, - ), - strutStyle: const StrutStyle( - height: 1, - leading: 0, - fontSize: 14, - ), - TextSpan( - children: [ - if (isCurr) ...[ - WidgetSpan( - alignment: - PlaceholderAlignment.bottom, - child: Image.asset( - 'assets/images/live.gif', - width: 16, - height: 16, - color: colorScheme.primary, + sliver: SliverList.builder( + itemCount: playlist.length, + itemBuilder: (_, index) { + if (index == playlist.length - 1) { + _controller.loadNext(context); + } + final isCurr = index == _controller.index; + final item = playlist[index]; + if (item.parts.length > 1) { + final subId = _controller.subId.firstOrNull; + return ExpansionTile( + dense: true, + minTileHeight: 45, + initiallyExpanded: isCurr, + collapsedIconColor: isCurr + ? colorScheme.primary + : null, + iconColor: isCurr + ? null + : colorScheme.onSurfaceVariant, + controlAffinity: + ListTileControlAffinity.leading, + title: Text( + item.arc.title, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: isCurr + ? TextStyle( + fontSize: 14, + color: colorScheme.primary, + fontWeight: FontWeight.bold, + ) + : const TextStyle(fontSize: 14), + ), + trailing: isCurr + ? null + : iconButton( + icon: const Icon(Icons.clear), + onPressed: () { + if (index < + _controller.index!) { + _controller.index -= 1; + } + _controller.playlist!.removeAt( + index, + ); + (context as Element) + .markNeedsBuild(); + }, + iconColor: colorScheme.outline, + size: 28, + iconSize: 18, + ), + children: item.parts.map((e) { + final isCurr = e.subId == subId; + return ListTile( + dense: true, + minTileHeight: 45, + contentPadding: + const EdgeInsetsDirectional.only( + start: 56.0, + end: 24.0, + ), + onTap: () { + Get.back(); + if (!isCurr) { + _controller.playIndex( + index, + subId: [e.subId], + ); + } + }, + title: Text.rich( + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: isCurr + ? TextStyle( + fontSize: 14, + color: colorScheme.primary, + fontWeight: FontWeight.bold, + ) + : TextStyle( + fontSize: 14, + color: colorScheme + .onSurfaceVariant, + ), + TextSpan( + children: [ + if (isCurr) ...[ + WidgetSpan( + alignment: + PlaceholderAlignment + .bottom, + child: Image.asset( + 'assets/images/live.gif', + width: 16, + height: 16, + color: + colorScheme.primary, + ), + ), + const TextSpan(text: ' '), + ], + TextSpan(text: e.title), + ], ), ), - const TextSpan(text: ' '), + ); + }).toList(), + ); + } + return ListTile( + dense: true, + minTileHeight: 45, + onTap: () { + Get.back(); + if (!isCurr) { + _controller.playIndex(index); + } + }, + title: Text.rich( + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: isCurr + ? TextStyle( + fontSize: 14, + color: colorScheme.primary, + fontWeight: FontWeight.bold, + ) + : const TextStyle(fontSize: 14), + TextSpan( + children: [ + if (isCurr) ...[ + WidgetSpan( + alignment: + PlaceholderAlignment.bottom, + child: Image.asset( + 'assets/images/live.gif', + width: 16, + height: 16, + color: colorScheme.primary, + ), + ), + const TextSpan(text: ' '), + ], + TextSpan( + text: item.arc.title, + ), ], - TextSpan( - text: item.arc.title, - ), - ], + ), ), - ), - trailing: isCurr - ? null - : iconButton( - icon: const Icon(Icons.clear), - onPressed: () { - if (index < _controller.index!) { - _controller.index -= 1; - } - _controller.playlist!.removeAt( - index, - ); - (context as Element) - .markNeedsBuild(); - }, - iconColor: colorScheme.outline, - size: 28, - iconSize: 18, - ), - ); - }, + trailing: isCurr + ? null + : iconButton( + icon: const Icon(Icons.clear), + onPressed: () { + if (index < _controller.index!) { + _controller.index -= 1; + } + _controller.playlist!.removeAt( + index, + ); + (context as Element) + .markNeedsBuild(); + }, + iconColor: colorScheme.outline, + size: 28, + iconSize: 18, + ), + ); + }, + ), ), - ), - ], + ], + ), ), ), ), diff --git a/lib/pages/video/reply_new/view.dart b/lib/pages/video/reply_new/view.dart index 659b3882..51234b77 100644 --- a/lib/pages/video/reply_new/view.dart +++ b/lib/pages/video/reply_new/view.dart @@ -291,7 +291,10 @@ class _ReplyPageState extends CommonRichTextPubPageState { Text( title, maxLines: 1, - style: const TextStyle(fontSize: 13), + style: TextStyle( + fontSize: 13, + color: theme.colorScheme.onSurface, + ), ), ], ),