mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-15 18:25:59 -07:00
fix: Small improvement to library screen
This commit is contained in:
parent
b2657f6408
commit
16bf5e8a32
3 changed files with 204 additions and 136 deletions
|
|
@ -12,6 +12,13 @@ sealed class NameSwitch {
|
||||||
String label(BuildContext context);
|
String label(BuildContext context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Resume extends NameSwitch {
|
||||||
|
const Resume();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String label(BuildContext context) => context.localized.dashboardContinue;
|
||||||
|
}
|
||||||
|
|
||||||
class NextUp extends NameSwitch {
|
class NextUp extends NameSwitch {
|
||||||
const NextUp();
|
const NextUp();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,23 +90,32 @@ class LibraryScreen extends _$LibraryScreen {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> loadResume(ViewModel viewModel) async {}
|
||||||
|
|
||||||
Future<void> loadRecommendations(ViewModel viewModel) async {
|
Future<void> loadRecommendations(ViewModel viewModel) async {
|
||||||
List<RecommendedModel> newRecommendations = [];
|
List<RecommendedModel> newRecommendations = [];
|
||||||
final latest = await api.usersUserIdItemsLatestGet(
|
|
||||||
|
final resume = await api.usersUserIdItemsResumeGet(
|
||||||
parentId: viewModel.id,
|
parentId: viewModel.id,
|
||||||
limit: 14,
|
limit: 14,
|
||||||
isPlayed: false,
|
enableUserData: true,
|
||||||
imageTypeLimit: 1,
|
enableImageTypes: [
|
||||||
includeItemTypes: viewModel.collectionType.itemKinds.map((e) => e.dtoKind).toList(),
|
ImageType.primary,
|
||||||
|
ImageType.banner,
|
||||||
|
ImageType.screenshot,
|
||||||
|
],
|
||||||
|
mediaTypes: [MediaType.video],
|
||||||
|
enableTotalRecordCount: false,
|
||||||
);
|
);
|
||||||
newRecommendations = [
|
newRecommendations = [
|
||||||
...newRecommendations,
|
...newRecommendations,
|
||||||
RecommendedModel(
|
RecommendedModel(
|
||||||
name: const Latest(),
|
name: const Resume(),
|
||||||
posters: latest.body?.map((e) => ItemBaseModel.fromBaseDto(e, ref)).toList() ?? [],
|
posters: resume.body?.items?.map((e) => ItemBaseModel.fromBaseDto(e, ref)).toList() ?? [],
|
||||||
type: null,
|
type: null,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
if (viewModel.collectionType == CollectionType.movies) {
|
if (viewModel.collectionType == CollectionType.movies) {
|
||||||
final response = await api.moviesRecommendationsGet(
|
final response = await api.moviesRecommendationsGet(
|
||||||
parentId: viewModel.id,
|
parentId: viewModel.id,
|
||||||
|
|
@ -146,6 +155,22 @@ class LibraryScreen extends _$LibraryScreen {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final latest = await api.usersUserIdItemsLatestGet(
|
||||||
|
parentId: viewModel.id,
|
||||||
|
limit: 14,
|
||||||
|
isPlayed: false,
|
||||||
|
imageTypeLimit: 1,
|
||||||
|
includeItemTypes: viewModel.collectionType.itemKinds.map((e) => e.dtoKind).toList(),
|
||||||
|
);
|
||||||
|
newRecommendations = [
|
||||||
|
...newRecommendations,
|
||||||
|
RecommendedModel(
|
||||||
|
name: const Latest(),
|
||||||
|
posters: latest.body?.map((e) => ItemBaseModel.fromBaseDto(e, ref)).toList() ?? [],
|
||||||
|
type: null,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
recommendations: newRecommendations,
|
recommendations: newRecommendations,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,9 @@ class LibraryScreen extends ConsumerStatefulWidget {
|
||||||
|
|
||||||
class _LibraryScreenState extends ConsumerState<LibraryScreen> with SingleTickerProviderStateMixin {
|
class _LibraryScreenState extends ConsumerState<LibraryScreen> with SingleTickerProviderStateMixin {
|
||||||
final GlobalKey<RefreshIndicatorState>? refreshKey = GlobalKey();
|
final GlobalKey<RefreshIndicatorState>? refreshKey = GlobalKey();
|
||||||
|
|
||||||
|
bool refreshing = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final libraryScreenState = ref.watch(libraryScreenProvider);
|
final libraryScreenState = ref.watch(libraryScreenProvider);
|
||||||
|
|
@ -60,7 +63,20 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen> with SingleTicker
|
||||||
body: PullToRefresh(
|
body: PullToRefresh(
|
||||||
refreshOnStart: true,
|
refreshOnStart: true,
|
||||||
refreshKey: refreshKey,
|
refreshKey: refreshKey,
|
||||||
onRefresh: () => ref.read(libraryScreenProvider.notifier).fetchAllLibraries(),
|
onRefresh: () async {
|
||||||
|
if (refreshing) return;
|
||||||
|
setState(() => refreshing = true);
|
||||||
|
try {
|
||||||
|
await ref.read(libraryScreenProvider.notifier).fetchAllLibraries();
|
||||||
|
} finally {
|
||||||
|
if (mounted) {
|
||||||
|
setState(() => refreshing = false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: AnimatedOpacity(
|
||||||
|
opacity: refreshing ? 0.75 : 1.0,
|
||||||
|
duration: const Duration(milliseconds: 175),
|
||||||
child: SizedBox.expand(
|
child: SizedBox.expand(
|
||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
controller: AdaptiveLayout.scrollOf(context, HomeTabs.library),
|
controller: AdaptiveLayout.scrollOf(context, HomeTabs.library),
|
||||||
|
|
@ -79,6 +95,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen> with SingleTicker
|
||||||
views: views,
|
views: views,
|
||||||
selectedView: libraryScreenState.selectedViewModel,
|
selectedView: libraryScreenState.selectedViewModel,
|
||||||
onSelected: (view) {
|
onSelected: (view) {
|
||||||
|
if (refreshing) return;
|
||||||
ref.read(libraryScreenProvider.notifier).selectLibrary(view);
|
ref.read(libraryScreenProvider.notifier).selectLibrary(view);
|
||||||
refreshKey?.currentState?.show();
|
refreshKey?.currentState?.show();
|
||||||
},
|
},
|
||||||
|
|
@ -141,18 +158,21 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen> with SingleTicker
|
||||||
if (viewTypes.contains(LibraryViewType.recommended)) ...[
|
if (viewTypes.contains(LibraryViewType.recommended)) ...[
|
||||||
if (recommendations.isNotEmpty)
|
if (recommendations.isNotEmpty)
|
||||||
...recommendations.where((element) => element.posters.isNotEmpty).map(
|
...recommendations.where((element) => element.posters.isNotEmpty).map(
|
||||||
(element) => SliverToBoxAdapter(
|
(element) {
|
||||||
|
return SliverToBoxAdapter(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
child: PosterRow(
|
child: PosterRow(
|
||||||
contentPadding: padding,
|
contentPadding: padding,
|
||||||
posters: element.posters,
|
posters: element.posters,
|
||||||
|
primaryPosters: element.name is Resume,
|
||||||
label: element.type != null
|
label: element.type != null
|
||||||
? "${element.type?.label(context)} - ${element.name.label(context)}"
|
? "${element.type?.label(context)} - ${element.name.label(context)}"
|
||||||
: element.name.label(context),
|
: element.name.label(context),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
if (viewTypes.contains(LibraryViewType.favourites))
|
if (viewTypes.contains(LibraryViewType.favourites))
|
||||||
|
|
@ -209,6 +229,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen> with SingleTicker
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -297,6 +318,19 @@ class LibraryRow extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Row(
|
||||||
|
spacing: 8,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
if (isSelected)
|
||||||
|
Container(
|
||||||
|
height: 12,
|
||||||
|
width: 12,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
Text(
|
Text(
|
||||||
view.name,
|
view.name,
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
|
@ -305,6 +339,8 @@ class LibraryRow extends ConsumerWidget {
|
||||||
textAlign: TextAlign.start,
|
textAlign: TextAlign.start,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue