Skip to content

Commit

Permalink
chore(yt): display shorts in horizontal list in feed & related videos
Browse files Browse the repository at this point in the history
  • Loading branch information
MSOB7YY committed Jul 11, 2024
1 parent 49e9c55 commit dd1eb4a
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 12 deletions.
41 changes: 41 additions & 0 deletions lib/youtube/pages/youtube_feed_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,47 @@ class YoutubeHomeFeedPage extends StatelessWidget {
thumbnailWidth: thumbnailWidth,
thumbnailHeight: thumbnailHeight,
),
sliverListBuilder: (feed, itemBuilder, dummyCard) {
return SliverVariedExtentList.builder(
itemExtentBuilder: (index, dimensions) {
if (feed.shortsSection.relatedItemsShortsData[index] != null) return 64.0 * 3 + 24.0 * 2;
final item = feed.items[index];
if (item is StreamInfoItemShort) return 0;
return thumbnailItemExtent;
},
itemCount: feed.items.length,
itemBuilder: (context, index) {
final shortSection = feed.shortsSection.relatedItemsShortsData[index];
if (shortSection != null) {
const height = 64.0 * 3;
const width = height * (9 / 16 * 1.2);
const hPadding = 4.0;
return SizedBox(
height: height,
child: ListView.builder(
padding: const EdgeInsets.symmetric(vertical: 24.0 / 6, horizontal: 4.0),
scrollDirection: Axis.horizontal,
itemExtent: width + hPadding * 2,
itemCount: shortSection.length,
itemBuilder: (context, index) {
final shortIndex = shortSection[index];
final short = feed.items[shortIndex] as StreamInfoItemShort;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: hPadding),
child: YoutubeShortVideoTallCard(
short: short,
thumbnailWidth: width,
thumbnailHeight: height,
),
);
},
),
);
}
return itemBuilder(feed.items[index], index, feed);
},
);
},
itemBuilder: (item, i, _) {
return switch (item.runtimeType) {
const (StreamInfoItem) => YoutubeVideoCard(
Expand Down
23 changes: 14 additions & 9 deletions lib/youtube/pages/youtube_main_page_fetcher_acc_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ import 'package:namida/ui/widgets/settings/extra_settings.dart';
import 'package:namida/youtube/controller/youtube_account_controller.dart';
import 'package:namida/youtube/pages/user/youtube_account_manage_page.dart';

typedef YoutubeMainPageFetcherItemBuilder<T, W> = Widget? Function(T item, int index, W list);

class YoutubeMainPageFetcherAccBase<W extends YoutiPieListWrapper<T>, T extends MapSerializable> extends StatefulWidget {
final bool transparentShimmer;
final String title;
final CacheDetails<W> cacheReader;
final Future<W?> Function(ExecuteDetails details) networkFetcher;
final Widget dummyCard;
final double itemExtent;
final Widget? Function(T item, int index, W list) itemBuilder;
final YoutubeMainPageFetcherItemBuilder<T, W> itemBuilder;
final SliverMultiBoxAdaptorWidget? Function(W list, YoutubeMainPageFetcherItemBuilder<T, W> itemBuilder, Widget dummyCard)? sliverListBuilder;

const YoutubeMainPageFetcherAccBase({
super.key,
Expand All @@ -35,6 +38,7 @@ class YoutubeMainPageFetcherAccBase<W extends YoutiPieListWrapper<T>, T extends
required this.dummyCard,
required this.itemExtent,
required this.itemBuilder,
this.sliverListBuilder,
});

@override
Expand Down Expand Up @@ -195,14 +199,15 @@ class _YoutubePageState<W extends YoutiPieListWrapper<T>, T extends MapSerializa
)
: listItems == null
? const SliverToBoxAdapter()
: SliverFixedExtentList.builder(
itemCount: listItems.items.length,
itemExtent: widget.itemExtent,
itemBuilder: (context, i) {
final item = listItems.items[i];
return widget.itemBuilder(item, i, listItems);
},
),
: widget.sliverListBuilder?.call(listItems, widget.itemBuilder, widget.dummyCard) ??
SliverFixedExtentList.builder(
itemCount: listItems.items.length,
itemExtent: widget.itemExtent,
itemBuilder: (context, i) {
final item = listItems.items[i];
return widget.itemBuilder(item, i, listItems);
},
),
SliverToBoxAdapter(
child: ObxO(
rx: _isLoadingNext,
Expand Down
85 changes: 85 additions & 0 deletions lib/youtube/widgets/yt_video_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:namida/controller/player_controller.dart';
import 'package:namida/core/enums.dart';
import 'package:namida/core/extensions.dart';
import 'package:namida/core/translations/language.dart';
import 'package:namida/core/utils.dart';
import 'package:namida/ui/widgets/custom_widgets.dart';
import 'package:namida/youtube/class/youtube_id.dart';
import 'package:namida/youtube/functions/yt_playlist_utils.dart';
Expand Down Expand Up @@ -209,6 +210,90 @@ class YoutubeShortVideoCard extends StatelessWidget {
}
}

class YoutubeShortVideoTallCard extends StatelessWidget {
final StreamInfoItemShort short;
final double thumbnailWidth;
final double? thumbnailHeight;

const YoutubeShortVideoTallCard({
super.key,
required this.short,
required this.thumbnailWidth,
required this.thumbnailHeight,
});

List<NamidaPopupItem> getMenuItems() {
final videoId = short.id;
return YTUtils.getVideoCardMenuItems(
videoId: videoId,
url: short.buildUrl(),
channelID: null,
playlistID: null,
idsNamesLookup: {videoId: short.title},
);
}

Future<void> _onShortTap() => _VideoCardUtils.onVideoTap(videoId: short.id);

@override
Widget build(BuildContext context) {
final videoId = short.id;
final title = short.title;
final viewsCountText = short.viewsText;
final thumbnail = short.liveThumbs.pick()?.url;

return NamidaPopupWrapper(
openOnTap: false,
childrenDefault: getMenuItems,
child: NamidaInkWell(
bgColor: context.theme.cardColor,
borderRadius: 8.0,
onTap: _onShortTap,
child: YoutubeThumbnail(
key: Key(videoId),
borderRadius: 8.0,
videoId: videoId,
customUrl: thumbnail,
width: thumbnailWidth,
height: thumbnailHeight,
isImportantInCache: false,
type: ThumbnailType.video,
onTopWidgets: (color) {
return [
Positioned(
bottom: 0,
left: 0,
child: Padding(
padding: const EdgeInsets.all(2.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: [
Text(
title,
style: context.textTheme.displayMedium?.copyWith(fontSize: 12.0),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Text(
viewsCountText,
style: context.textTheme.displaySmall?.copyWith(fontSize: 11.0),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
),
),
];
},
),
),
);
}
}

class YoutubeVideoCardDummy extends StatelessWidget {
final double? thumbnailWidth;
final double? thumbnailHeight;
Expand Down
37 changes: 35 additions & 2 deletions lib/youtube/youtube_miniplayer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -841,11 +841,44 @@ class YoutubeMiniPlayerState extends State<YoutubeMiniPlayer> {
),
),
)
: SliverFixedExtentList.builder(
: SliverVariedExtentList.builder(
key: Key("${currentId}_feedlist"),
itemExtent: relatedThumbnailItemExtent,
itemExtentBuilder: (index, dimensions) {
if (page.relatedVideosResult.shortsSection.relatedItemsShortsData[index] != null) return 64.0 * 3 + 24.0 * 2;
final item = page.relatedVideosResult.items[index];
if (item is StreamInfoItemShort) return 0;
return relatedThumbnailItemExtent;
},
itemCount: page.relatedVideosResult.items.length,
itemBuilder: (context, index) {
final shortSection = page.relatedVideosResult.shortsSection.relatedItemsShortsData[index];
if (shortSection != null) {
const height = 64.0 * 3;
const width = height * (9 / 16 * 1.2);
const hPadding = 4.0;
return SizedBox(
height: height,
child: ListView.builder(
padding: const EdgeInsets.symmetric(vertical: 24.0 / 6, horizontal: 4.0),
scrollDirection: Axis.horizontal,
itemExtent: width + hPadding * 2,
itemCount: shortSection.length,
itemBuilder: (context, index) {
final shortIndex = shortSection[index];
final short = page.relatedVideosResult.items[shortIndex] as StreamInfoItemShort;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: hPadding),
child: YoutubeShortVideoTallCard(
short: short,
thumbnailWidth: width,
thumbnailHeight: height,
),
);
},
),
);
}

final item = page.relatedVideosResult.items[index];
return switch (item.runtimeType) {
const (StreamInfoItem) => YoutubeVideoCard(
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: namida
description: A Beautiful and Feature-rich Music Player, With YouTube & Video Support Built in Flutter
publish_to: "none"
version: 3.1.6-beta+240710229
version: 3.1.7-beta+240711002

environment:
sdk: ">=3.4.0 <4.0.0"
Expand Down

0 comments on commit dd1eb4a

Please sign in to comment.