diff --git a/lib/pages/audio/view.dart b/lib/pages/audio/view.dart index d3cb0d1f1..ab5025891 100644 --- a/lib/pages/audio/view.dart +++ b/lib/pages/audio/view.dart @@ -200,6 +200,186 @@ class _AudioPageState extends State { builder: (context) { final theme = Theme.of(context); final colorScheme = theme.colorScheme; + Widget child = CustomScrollView( + controller: scrollController, + physics: _controller.reachStart + ? null + : const AlwaysScrollableScrollPhysics(), + 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]; + 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; + } + 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: .bottom, + child: Image.asset( + 'assets/images/live.gif', + width: 16, + height: 16, + cacheWidth: 16.cacheSize( + context, + ), + color: colorScheme.primary, + ), + ), + const TextSpan(text: ' '), + ], + TextSpan(text: e.title), + ], + ), + ), + ); + }).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: .bottom, + child: Image.asset( + 'assets/images/live.gif', + width: 16, + height: 16, + cacheWidth: 16.cacheSize( + context, + ), + color: colorScheme.primary, + ), + ), + const TextSpan(text: ' '), + ], + TextSpan( + text: item.arc.title, + ), + ], + ), + ), + trailing: isCurr + ? null + : iconButton( + icon: const Icon(Icons.clear), + onPressed: () { + if (index < _controller.index!) { + _controller.index -= 1; + } + playlist.removeAt(index); + (context as Element).markNeedsBuild(); + }, + iconColor: colorScheme.outline, + size: 28, + iconSize: 18, + ), + ); + }, + ), + ), + ], + ); + if (!_controller.reachStart) { + child = refreshIndicator( + onRefresh: () => _controller.loadPrev(context), + isClampingScrollPhysics: true, + child: child, + ); + } return FractionallySizedBox( heightFactor: PlatformUtils.isMobile && !context.mediaQuerySize.isPortrait @@ -219,9 +399,7 @@ class _AudioPageState extends State { height: 3, decoration: BoxDecoration( color: colorScheme.outline, - borderRadius: const BorderRadius.all( - Radius.circular(3), - ), + borderRadius: const .all(.circular(3)), ), ), ), @@ -231,200 +409,8 @@ class _AudioPageState extends State { child: Material( type: MaterialType.transparency, child: Theme( - data: theme.copyWith( - dividerColor: Colors.transparent, - ), - child: refreshIndicator( - onRefresh: () => _controller.loadPrev(context), - isClampingScrollPhysics: true, - child: CustomScrollView( - controller: scrollController, - physics: _controller.reachStart - ? const ClampingScrollPhysics() - : const AlwaysScrollableScrollPhysics( - parent: ClampingScrollPhysics(), - ), - 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]; - 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; - } - 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: .bottom, - child: Image.asset( - 'assets/images/live.gif', - width: 16, - height: 16, - cacheWidth: 16.cacheSize( - context, - ), - color: - colorScheme.primary, - ), - ), - const TextSpan(text: ' '), - ], - TextSpan(text: e.title), - ], - ), - ), - ); - }).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: .bottom, - child: Image.asset( - 'assets/images/live.gif', - width: 16, - height: 16, - cacheWidth: 16.cacheSize( - context, - ), - color: colorScheme.primary, - ), - ), - const TextSpan(text: ' '), - ], - TextSpan( - text: item.arc.title, - ), - ], - ), - ), - trailing: isCurr - ? null - : iconButton( - icon: const Icon(Icons.clear), - onPressed: () { - if (index < _controller.index!) { - _controller.index -= 1; - } - playlist.removeAt(index); - (context as Element) - .markNeedsBuild(); - }, - iconColor: colorScheme.outline, - size: 28, - iconSize: 18, - ), - ); - }, - ), - ), - ], - ), - ), + data: theme.copyWith(dividerColor: Colors.transparent), + child: child, ), ), ), diff --git a/lib/pages/video/reply_reply/view.dart b/lib/pages/video/reply_reply/view.dart index 500ad6da7..09ebf3c47 100644 --- a/lib/pages/video/reply_reply/view.dart +++ b/lib/pages/video/reply_reply/view.dart @@ -185,11 +185,7 @@ class _VideoReplyReplyPanelState extends State child: CustomScrollView( key: ValueKey(scrollController.hashCode), controller: scrollController, - physics: widget.isNested - ? const AlwaysScrollableScrollPhysics( - parent: ClampingScrollPhysics(), - ) - : const AlwaysScrollableScrollPhysics(), + physics: const AlwaysScrollableScrollPhysics(), slivers: [ if (!isDialogue) ...[ if ((widget.firstFloor ?? _controller.firstFloor.value)