Skip to content

Commit

Permalink
Update videos_page.dart
Browse files Browse the repository at this point in the history
  • Loading branch information
wheremyfiji committed May 12, 2024
1 parent 771f0ea commit e59d807
Showing 1 changed file with 215 additions and 64 deletions.
279 changes: 215 additions & 64 deletions lib/src/presentation/pages/anime_details/videos_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';

import 'package:url_launcher/url_launcher_string.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:collection/collection.dart';

import '../../../services/http/http_service_provider.dart';
import '../../../utils/extensions/riverpod_extensions.dart';
Expand Down Expand Up @@ -64,56 +65,75 @@ class AnimeVideosPage extends ConsumerWidget {
...videos.when(
data: (data) {
return [
SliverList.builder(
itemCount: data.length,
itemBuilder: (context, index) {
final item = data[index];

return ListTile(
visualDensity: VisualDensity.compact,
//onTap: () {},
onTap: () => launchUrlString(
item.url,
mode: LaunchMode.externalApplication,
),
leading: SizedBox(
height: 48,
child: AspectRatio(
aspectRatio: 16 / 9,
child: Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(8),
),
child: CachedImage(
item.imageUrl,
fit: BoxFit.cover,
),
),
),
),
title: Text(
item.name ?? '',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: context.colorScheme.onBackground,
// fontSize: 14,
height: 1.2,
),
),
subtitle: Text(
item.kind.rusName,
style: TextStyle(
//fontSize: 12,
color: context.colorScheme.onBackground
.withOpacity(0.8),
),
),
);
},
SliverPadding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 0),
sliver: SliverGrid.builder(
gridDelegate:
const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 380.0, // 440 ?? 340
childAspectRatio: 16 / 9,
crossAxisSpacing: 8.0,
mainAxisSpacing: 8.0,
),
itemBuilder: (context, index) => VideoCard(data[index]),
itemCount: data.length,
),
),
// SliverList.builder(
// itemCount: data.length,
// itemBuilder: (context, index) {
// final item = data[index];

// return Padding(
// padding: const EdgeInsets.symmetric(horizontal: 16.0),
// child: VideoCard(item),
// );

// return ListTile(
// visualDensity: VisualDensity.compact,
// //onTap: () {},
// onTap: () => launchUrlString(
// item.url,
// mode: LaunchMode.externalApplication,
// ),
// leading: SizedBox(
// height: 48,
// child: AspectRatio(
// aspectRatio: 16 / 9,
// child: Container(
// clipBehavior: Clip.antiAlias,
// decoration: BoxDecoration(
// color: Colors.black,
// borderRadius: BorderRadius.circular(8),
// ),
// child: CachedImage(
// item.imageUrl,
// fit: BoxFit.cover,
// ),
// ),
// ),
// ),
// title: Text(
// item.name ?? '',
// maxLines: 2,
// overflow: TextOverflow.ellipsis,
// style: TextStyle(
// color: context.colorScheme.onBackground,
// // fontSize: 14,
// height: 1.2,
// ),
// ),
// subtitle: Text(
// item.kind.rusName,
// style: TextStyle(
// //fontSize: 12,
// color: context.colorScheme.onBackground
// .withOpacity(0.8),
// ),
// ),
// );
// },
// ),
];
},
loading: () => [
Expand All @@ -130,13 +150,132 @@ class AnimeVideosPage extends ConsumerWidget {
),
],
),
SliverPadding(
padding: EdgeInsets.only(
bottom: context.padding.bottom + 16.0,
),
),
],
),
),
);
}
}

class VideoCard extends StatelessWidget {
const VideoCard(this.item, {super.key});

final AnimeVideo item;

@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, boxConstraints) {
return DecoratedBox(
position: DecorationPosition.foreground,
decoration: BoxDecoration(
border: Border.all(
color: context.colorScheme.outline,
),
borderRadius: BorderRadius.circular(12.0),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(12.0),
child: Stack(
children: [
Positioned.fill(
// top: -1,
// left: -1,
// right: -1,
// bottom: -1,
child: CachedImage(item.imageUrl),
),
Positioned.fill(
top: -1,
bottom: -1,
left: -1,
right: -1,
child: IgnorePointer(
child: DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
context.theme.scaffoldBackgroundColor
.withOpacity(0),
context.theme.scaffoldBackgroundColor,
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
),
),
),
Align(
alignment: Alignment.bottomLeft,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 6),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
// if (item.hosting != null)
// Text(
// item.hosting!,
// style: context.textTheme.bodySmall,
// ),
Text(
item.kind.rusName,
style: context.textTheme.bodySmall?.copyWith(
letterSpacing: 1,
),
),
const SizedBox(
height: 2.0,
),
Text(
(item.name == null || item.name!.isEmpty)
? '[Без нзвания]'
: item.name!,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: context.textTheme.bodyLarge?.copyWith(
height: 1.2,
),
),
],
),
),
),
Align(
child: SizedBox(
height: boxConstraints.maxHeight,
child: AspectRatio(
aspectRatio: 16 / 9,
child: Material(
type: MaterialType.transparency,
child: InkWell(
// onTap: () {
// print('url: ${item.url}');
// },
onTap: () => launchUrlString(
item.url,
mode: LaunchMode.externalApplication,
),
),
),
),
),
),
],
),
),
);
},
);
}
}

final animeVideosProvider =
FutureProvider.autoDispose.family<List<AnimeVideo>, int>((ref, id) async {
final dio = ref.read(httpServiceProvider);
Expand All @@ -151,7 +290,11 @@ final animeVideosProvider =
for (final e in response) AnimeVideo.fromJson(e),
];

return list;
//list.sortBy<num>((e) => e.kind.index);

final sortedList = list.sortedBy<num>((e) => e.kind.index);

return sortedList;
}, name: 'animeVideosProvider');

class AnimeVideo {
Expand All @@ -173,27 +316,35 @@ class AnimeVideo {
this.hosting,
});

factory AnimeVideo.fromJson(Map<String, dynamic> json) => AnimeVideo(
id: json["id"],
url: json["url"],
imageUrl: json["image_url"],
playerUrl: json["player_url"],
name: json["name"],
kind: AnimeVideoKind.fromValue(json["kind"]),
hosting: json["hosting"],
);
factory AnimeVideo.fromJson(Map<String, dynamic> json) {
final url = (json["url"] as String).replaceFirst('http://', 'https://');
final imageUrl =
(json["image_url"] as String).replaceFirst('http://', 'https://');
final playerUrl =
(json["player_url"] as String).replaceFirst('http://', 'https://');

return AnimeVideo(
id: json["id"],
url: url,
imageUrl: imageUrl,
playerUrl: playerUrl,
name: json["name"],
kind: AnimeVideoKind.fromValue(json["kind"]),
hosting: json["hosting"],
);
}
}

enum AnimeVideoKind {
pv('pv'),
characterTrailer('character_trailer'),
cm('cm'),
op('op'),
ed('ed'),
episodePreview('episode_preview'),
pv('pv'),
opEdClip('op_ed_clip'),
clip('clip'),
other('other'),
episodePreview('episode_preview');
characterTrailer('character_trailer'),
cm('cm'),
other('other');

final String value;

Expand Down

0 comments on commit e59d807

Please sign in to comment.