Initial commit

This commit is contained in:
admin1
2026-07-14 11:11:36 +08:00
commit 656499cf94
604 changed files with 119518 additions and 0 deletions
@@ -0,0 +1,97 @@
import 'dart:io' show Platform;
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../providers/di_providers.dart';
import '../../../providers/emby_headers_provider.dart';
import '../../../providers/session_provider.dart';
import '../../../shared/mappers/media_image_url.dart';
import '../../../shared/theme/app_theme.dart';
import '../../../shared/utils/media_nav.dart';
import '../../../shared/widgets/hover_scrollable_row.dart';
import '../../../shared/widgets/media_poster_card.dart';
import 'section_container.dart';
class SpecialFeaturesSection extends ConsumerWidget {
final String itemId;
final bool embedded;
final Widget? leading;
const SpecialFeaturesSection({
super.key,
required this.itemId,
this.embedded = false,
this.leading,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final session = ref.watch(activeSessionProvider);
if (session == null) return const SizedBox.shrink();
final imageHeaders = ref.watch(embyImageHeadersProvider).value;
final asyncItems = ref.watch(specialFeaturesDataProvider(itemId));
return asyncItems.when(
loading: () => const SizedBox.shrink(),
error: (error, stackTrace) => const SizedBox.shrink(),
data: (items) {
if (items.isEmpty) return const SizedBox.shrink();
final sectionPad = SectionContainer.hPadOf(context);
final listPadding = EdgeInsetsDirectional.fromSTEB(
embedded ? 0.0 : sectionPad,
0,
sectionPad,
0,
);
final isAndroid = Platform.isAndroid;
return SectionContainer(
title: '花絮',
embedded: embedded,
leadingDivider: embedded,
leading: leading,
child: SizedBox(
height: isAndroid ? 210 : 300,
child: Theme(
data: AppTheme.dark(),
child: HoverScrollableRow(
builder: (_, controller) => ListView.builder(
controller: controller,
scrollDirection: Axis.horizontal,
padding: listPadding,
itemCount: items.length,
itemBuilder: (_, i) {
final item = items[i];
final imageUrl = EmbyImageUrl.primary(
baseUrl: session.serverUrl,
token: session.token,
item: item,
maxHeight: 480,
);
return Padding(
padding: EdgeInsetsDirectional.only(
end: i < items.length - 1 ? 12 : 0,
),
child: MediaPosterCard(
item: item,
imageUrl: imageUrl,
width: isAndroid ? 105 : 160,
showHoverPlayIcon: false,
enableContextMenu: false,
imageHeaders: imageHeaders,
onTap: () => goMediaDetail(context, item, ref: ref),
),
);
},
),
),
),
),
);
},
);
}
}