mirror of
https://github.com/Dr-Blank/Vaani.git
synced 2025-12-28 22:09:31 +00:00
fix: resolve Series deserialization issues and add author sorting
- Fix genres error by parsing JSON manually to avoid Series deserialization - Fix series blank screen by using SimpleSeries class instead of full Series - Add alphabetical sorting to authors page - Work around shelfsdk Series variant detection issues The Audiobookshelf API returns Series objects that don't match any of the variant detection patterns in the shelfsdk SeriesConverter. Since we can't modify the external shelfsdk, we parse the API responses manually to extract only the data we need for display.
This commit is contained in:
parent
5afce16532
commit
f60ea72659
3 changed files with 72 additions and 39 deletions
|
|
@ -25,6 +25,10 @@ class LibraryAuthorsPage extends HookConsumerWidget {
|
|||
);
|
||||
}
|
||||
|
||||
// Sort authors alphabetically by name
|
||||
final sortedAuthors = List<Author>.from(authors)
|
||||
..sort((a, b) => a.name.toLowerCase().compareTo(b.name.toLowerCase()));
|
||||
|
||||
return GridView.builder(
|
||||
padding: const EdgeInsets.all(16),
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
|
|
@ -33,9 +37,9 @@ class LibraryAuthorsPage extends HookConsumerWidget {
|
|||
crossAxisSpacing: 16,
|
||||
mainAxisSpacing: 16,
|
||||
),
|
||||
itemCount: authors.length,
|
||||
itemCount: sortedAuthors.length,
|
||||
itemBuilder: (context, index) {
|
||||
final author = authors[index];
|
||||
final author = sortedAuthors[index];
|
||||
return AuthorCard(author: author);
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:shelfsdk/audiobookshelf_api.dart';
|
||||
import 'package:vaani/api/library_browser_provider.dart';
|
||||
|
||||
class LibrarySeriesPage extends HookConsumerWidget {
|
||||
|
|
@ -15,8 +14,8 @@ class LibrarySeriesPage extends HookConsumerWidget {
|
|||
title: const Text('Series'),
|
||||
),
|
||||
body: seriesAsync.when(
|
||||
data: (seriesResponse) {
|
||||
if (seriesResponse == null || seriesResponse.results.isEmpty) {
|
||||
data: (seriesList) {
|
||||
if (seriesList.isEmpty) {
|
||||
return const Center(
|
||||
child: Text('No series found'),
|
||||
);
|
||||
|
|
@ -24,9 +23,9 @@ class LibrarySeriesPage extends HookConsumerWidget {
|
|||
|
||||
return ListView.builder(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
itemCount: seriesResponse.results.length,
|
||||
itemCount: seriesList.length,
|
||||
itemBuilder: (context, index) {
|
||||
final series = seriesResponse.results[index];
|
||||
final series = seriesList[index];
|
||||
return SeriesListTile(series: series);
|
||||
},
|
||||
);
|
||||
|
|
@ -55,22 +54,10 @@ class SeriesListTile extends StatelessWidget {
|
|||
required this.series,
|
||||
});
|
||||
|
||||
final Series series;
|
||||
final SimpleSeries series;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Extract series data based on variant
|
||||
final String seriesName = series.name;
|
||||
final int? numBooks = series.maybeMap(
|
||||
(s) => null, // base variant
|
||||
numBooks: (s) => s.numBooks,
|
||||
books: (s) => s.books.length,
|
||||
sequence: (s) => null,
|
||||
shelf: (s) => s.books.length,
|
||||
author: (s) => s.items?.length,
|
||||
orElse: () => null,
|
||||
);
|
||||
|
||||
return Card(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
|
||||
child: ListTile(
|
||||
|
|
@ -87,18 +74,18 @@ class SeriesListTile extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
title: Text(
|
||||
seriesName,
|
||||
series.name,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
subtitle: numBooks != null
|
||||
? Text('$numBooks ${numBooks == 1 ? 'book' : 'books'}')
|
||||
subtitle: series.numBooks != null
|
||||
? Text('${series.numBooks} ${series.numBooks == 1 ? 'book' : 'books'}')
|
||||
: null,
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
onTap: () {
|
||||
// TODO: Navigate to series detail page
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Tapped on $seriesName'),
|
||||
content: Text('Tapped on ${series.name}'),
|
||||
duration: const Duration(seconds: 1),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue