From 4aebc0aac553d1a9315603529ba0319613be45d0 Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Mon, 6 Jan 2025 08:59:50 +0800 Subject: [PATCH] feat: sponsorblock: show video label Closes #102 Signed-off-by: bggRGjQaUbCoE --- lib/pages/video/detail/controller.dart | 6 ++ lib/pages/video/detail/introduction/view.dart | 83 ++++++++++++++++--- 2 files changed, 79 insertions(+), 10 deletions(-) diff --git a/lib/pages/video/detail/controller.dart b/lib/pages/video/detail/controller.dart index c260f61f..01e028fb 100644 --- a/lib/pages/video/detail/controller.dart +++ b/lib/pages/video/detail/controller.dart @@ -476,6 +476,7 @@ class VideoDetailController extends GetxController List? _segmentProgressList; Color _getColor(SegmentType segment) => _blockColor?[segment.index] ?? segment.color; + late RxString videoLabel = ''.obs; Timer? skipTimer; late final listKey = GlobalKey(); @@ -747,6 +748,7 @@ class VideoDetailController extends GetxController }, options: _options, ); + videoLabel.value = ''; segmentList.clear(); _segmentProgressList = null; _handleSBData(result); @@ -772,6 +774,10 @@ class VideoDetailController extends GetxController (item) { SegmentType segmentType = SegmentType.values[list.indexOf(item['category'])]; + if (item['segment'][0] == 0 && item['segment'][1] == 0) { + videoLabel.value += + '${videoLabel.value.isNotEmpty ? '/' : ''}${segmentType.title}'; + } SkipType skipType = _blockSettings![segmentType.index].second; if (skipType != SkipType.showOnly) { if (item['segment'][1] == item['segment'][0] || diff --git a/lib/pages/video/detail/introduction/view.dart b/lib/pages/video/detail/introduction/view.dart index 9bbf20fe..49a7462a 100644 --- a/lib/pages/video/detail/introduction/view.dart +++ b/lib/pages/video/detail/introduction/view.dart @@ -137,6 +137,77 @@ class _VideoInfoState extends State with TickerProviderStateMixin { late final _horizontalMemberPage = GStorage.horizontalMemberPage; + Widget get _buildVideoTitle => videoDetailCtr.enableSponsorBlock + ? Obx( + () => Text.rich( + TextSpan( + children: [ + if (videoDetailCtr.videoLabel.value.isNotEmpty) ...[ + WidgetSpan( + alignment: PlaceholderAlignment.middle, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 4, + vertical: 2, + ), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.secondaryContainer, + borderRadius: BorderRadius.circular(4), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Stack( + alignment: Alignment.center, + children: [ + Icon( + Icons.shield_outlined, + size: + MediaQuery.textScalerOf(context).scale(16), + ), + Icon( + Icons.play_arrow_rounded, + size: + MediaQuery.textScalerOf(context).scale(12), + color: Theme.of(context) + .colorScheme + .onSecondaryContainer, + ), + ], + ), + Text( + videoDetailCtr.videoLabel.value, + strutStyle: StrutStyle(leading: 0, height: 1), + style: TextStyle( + height: 1, + fontSize: 13, + color: Theme.of(context) + .colorScheme + .onSecondaryContainer, + ), + ), + ], + ), + ), + ), + TextSpan(text: ' '), + ], + TextSpan( + text: '${videoDetail.title ?? videoItem['title'] ?? ''}'), + ], + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: const TextStyle(fontSize: 16), + ), + ) + : Text( + '${videoDetail.title ?? videoItem['title'] ?? ''}', + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: const TextStyle(fontSize: 16), + ); + void handleState(Future Function() action) async { if (isProcessing.not) { isProcessing = true; @@ -455,12 +526,7 @@ class _VideoInfoState extends State with TickerProviderStateMixin { Utils.copyText( '${videoDetail.title ?? videoItem['title'] ?? ''}'); }, - child: Text( - '${videoDetail.title ?? videoItem['title'] ?? ''}', - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: const TextStyle(fontSize: 16), - ), + child: _buildVideoTitle, ), expanded: GestureDetector( onLongPress: () { @@ -468,10 +534,7 @@ class _VideoInfoState extends State with TickerProviderStateMixin { Utils.copyText( '${videoDetail.title ?? videoItem['title'] ?? ''}'); }, - child: Text( - videoDetail.title ?? videoItem['title'] ?? '', - style: const TextStyle(fontSize: 16), - ), + child: _buildVideoTitle, ), theme: const ExpandableThemeData( animationDuration: Duration(milliseconds: 300),