feat: Improve library search screen (#477)

Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
PartyDonut 2025-08-28 23:26:10 +02:00 committed by GitHub
parent 571b682b80
commit d22d340181
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
41 changed files with 2881 additions and 2026 deletions

View file

@ -6,6 +6,7 @@ import 'package:auto_route/auto_route.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:fladder/models/library_filter_model.dart';
import 'package:fladder/models/recommended_model.dart';
import 'package:fladder/models/view_model.dart';
import 'package:fladder/providers/library_screen_provider.dart';
@ -15,6 +16,7 @@ import 'package:fladder/screens/shared/flat_button.dart';
import 'package:fladder/screens/shared/media/poster_row.dart';
import 'package:fladder/screens/shared/nested_scaffold.dart';
import 'package:fladder/screens/shared/nested_sliver_appbar.dart';
import 'package:fladder/theme.dart';
import 'package:fladder/util/adaptive_layout/adaptive_layout.dart';
import 'package:fladder/util/fladder_image.dart';
import 'package:fladder/util/localization_helper.dart';
@ -159,6 +161,16 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen> with SingleTicker
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: PosterRow(
contentPadding: padding,
onLabelClick: () => context.pushRoute(
LibrarySearchRoute(
viewModelId: libraryScreenState.selectedViewModel?.id ?? "",
).withFilter(
const LibraryFilterModel(
favourites: true,
recursive: true,
),
),
),
posters: favourites,
label: context.localized.favorites,
),
@ -173,6 +185,16 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen> with SingleTicker
child: PosterRow(
contentPadding: padding,
posters: element.posters,
onLabelClick: () => context.pushRoute(
LibrarySearchRoute(
viewModelId: libraryScreenState.selectedViewModel?.id ?? "",
).withFilter(
LibraryFilterModel(
recursive: true,
genres: {(element.name as Other).customLabel: true},
),
),
),
label: element.type != null
? "${element.type?.label(context)} - ${element.name.label(context)}"
: element.name.label(context),
@ -210,7 +232,7 @@ class LibraryRow extends ConsumerWidget {
label: context.localized.library(views.length),
items: views,
startIndex: selectedView != null ? views.indexOf(selectedView!) : null,
height: 165,
height: 125,
contentPadding: padding,
itemBuilder: (context, index) {
final view = views[index];
@ -240,52 +262,51 @@ class LibraryRow extends ConsumerWidget {
items: viewActions.popupMenuItems(useIcons: true),
);
},
child: Card(
color: isSelected ? Theme.of(context).colorScheme.primaryContainer : null,
shadowColor: Colors.transparent,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 4,
children: [
SizedBox(
width: 200,
child: Card(
child: AspectRatio(
aspectRatio: 1.60,
child: FladderImage(
image: view.imageData?.primary,
fit: BoxFit.cover,
placeHolder: Center(
child: Text(
view.name,
style: Theme.of(context).textTheme.titleMedium,
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.start,
),
),
child: Stack(
children: [
AnimatedContainer(
duration: const Duration(milliseconds: 250),
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
border: Border.all(
width: isSelected ? 4 : 0,
color: isSelected ? Theme.of(context).colorScheme.primary : Colors.transparent,
),
borderRadius: FladderTheme.defaultShape.borderRadius,
),
clipBehavior: Clip.hardEdge,
width: 200,
child: ClipRRect(
borderRadius: FladderTheme.smallShape.borderRadius,
child: AspectRatio(
aspectRatio: 1.60,
child: FladderImage(
image: view.imageData?.primary,
fit: BoxFit.cover,
placeHolder: Center(
child: Text(
view.name,
style: Theme.of(context).textTheme.titleMedium,
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.start,
),
),
),
),
Expanded(
),
),
Positioned.fill(
child: Align(
alignment: Alignment.bottomLeft,
child: AnimatedOpacity(
duration: const Duration(milliseconds: 250),
opacity: isSelected ? 0 : 1,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4.0),
padding: const EdgeInsets.all(6),
child: Row(
spacing: 8,
children: [
if (isSelected)
Container(
height: 12,
width: 12,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary,
shape: BoxShape.circle,
),
),
Text(
view.name,
style: Theme.of(context).textTheme.titleMedium,
@ -297,9 +318,9 @@ class LibraryRow extends ConsumerWidget {
),
),
),
],
),
),
),
],
),
);
},