Skip to content

Commit

Permalink
feat: initial library render (authors page)
Browse files Browse the repository at this point in the history
  • Loading branch information
nesquikm committed Oct 27, 2023
1 parent 208af0f commit 2c346c7
Show file tree
Hide file tree
Showing 14 changed files with 292 additions and 77 deletions.
1 change: 1 addition & 0 deletions lib/features/common/common.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'view/view.dart';
14 changes: 14 additions & 0 deletions lib/features/common/view/fullscreen_error_message.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import 'package:flutter/material.dart';

class FullscreenErrorMessage extends StatelessWidget {
const FullscreenErrorMessage({required this.text, super.key});

final String text;

@override
Widget build(BuildContext context) {
return Center(
child: Text(text),
);
}
}
12 changes: 12 additions & 0 deletions lib/features/common/view/fullscreen_progress_indicator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import 'package:flutter/material.dart';

class FullscreenProgressIndicator extends StatelessWidget {
const FullscreenProgressIndicator({super.key});

@override
Widget build(BuildContext context) {
return const Center(
child: CircularProgressIndicator(),
);
}
}
2 changes: 2 additions & 0 deletions lib/features/common/view/view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export 'fullscreen_error_message.dart';
export 'fullscreen_progress_indicator.dart';
69 changes: 52 additions & 17 deletions lib/features/library/page/library_authors_page.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import 'package:bsr/app/router/router.dart';
import 'dart:collection';

import 'package:bsr/features/common/common.dart';
import 'package:bsr/features/library/library.dart';
import 'package:bsr/features/library/view/author_tomes_sliver.dart';
import 'package:bsr/features/library/view/fullscreen_empty_library.dart';
import 'package:bsr/l10n/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
Expand All @@ -14,24 +19,54 @@ class _LibraryAuthorsPageState extends ConsumerState<LibraryAuthorsPage> {
@override
Widget build(BuildContext context) {
final l10n = context.l10n;
return Scaffold(
appBar: AppBar(title: Text(l10n.counterAppBarTitle)),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('LibraryAuthors'),
TextButton(
onPressed: () {
ref.goFurther(AppRoute.reader);
},
child: const Text('Reader'),

final result = ref.watch(
tomeLibraryGroupedByAuthorAndSortedByTitleProvider,
);

final slivers = switch (result) {
AsyncValue<SplayTreeMap<String, LinkedHashMap<String, CachedTome>>>(
:final valueOrNull?,
) =>
valueOrNull.entries.isEmpty
? const SliverFillRemaining(
child: FullscreenEmptyLibrary(),
)
: SliverList.builder(
itemBuilder: (context, index) {
final author = valueOrNull.keys.elementAt(index);
final tomes = valueOrNull.values.elementAt(index);

return AuthorTomesSliver(author: author, tomes: tomes);
},
itemCount: valueOrNull.entries.length,
),
AsyncValue(
:final error?,
) =>
SliverFillRemaining(
child: FullscreenErrorMessage(
text: 'Error loading library $error',
),
TextButton(
onPressed: () {
ref.goFurther(AppRoute.settings);
},
child: const Text('Settings'),
),
_ => const SliverFillRemaining(
child: FullscreenProgressIndicator(),
),
};

return Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(
title: Text(l10n.counterAppBarTitle),
actions: [
IconButton(
icon: const Icon(Icons.search),
onPressed: () {},
),
],
),
slivers,
],
),
);
Expand Down
101 changes: 64 additions & 37 deletions lib/features/library/tome_library/tome_library.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,28 @@ class TomeLibrary extends _$TomeLibrary {
);
}

Future<LinkedHashMap<String, CachedTome>> getSortedByTitle() async {
return _getSortedByTitle(await future);
}
// Future<LinkedHashMap<String, CachedTome>> getSortedByTitle() async {
// return _getSortedByTitle(await future);
// }

Future<SplayTreeMap<String, LinkedHashMap<String, CachedTome>>>
getGroupedByAuthorAndSortedByTitle() async {
final tomeList = await future;
final result = SplayTreeMap<String, LinkedHashMap<String, CachedTome>>(
(a, b) => a.compareTo(b),
);
// Future<SplayTreeMap<String, LinkedHashMap<String, CachedTome>>>
// getGroupedByAuthorAndSortedByTitle() async {
// final tomeList = await future;
// final result = SplayTreeMap<String, LinkedHashMap<String, CachedTome>>(
// (a, b) => a.compareTo(b),
// );

for (final tome in tomeList.entries) {
final author = tome.value.tomeInfo.author ?? '';
// for (final tome in tomeList.entries) {
// final author = tome.value.tomeInfo.author ?? '';

final authorTomeList = result[author] ?? <String, CachedTome>{}
..addAll({tome.key: tome.value});
// final authorTomeList = result[author] ?? <String, CachedTome>{}
// ..addAll({tome.key: tome.value});

result[author] = _getSortedByTitle(authorTomeList);
}
// result[author] = _getSortedByTitle(authorTomeList);
// }

return result;
}
// return result;
// }

Future<void> setDirectory(String directoryPath) async {
_log.fine('setDirectory($directoryPath)');
Expand Down Expand Up @@ -83,26 +83,53 @@ class TomeLibrary extends _$TomeLibrary {
_markedAsRemoved.remove(id);
ref.invalidateSelf();
}
}

LinkedHashMap<String, CachedTome> _getSortedByTitle(
Map<String, CachedTome> tomeList,
) {
final sortedList = tomeList.entries.toList()
..sort((a, b) {
final aTitle = a.value.tomeInfo.title;
final bTitle = b.value.tomeInfo.title;
return (aTitle == null || bTitle == null)
? 0
: aTitle.compareTo(bTitle);
});

return LinkedHashMap<String, CachedTome>.fromEntries(
sortedList.map(
(e) => MapEntry(
e.key,
e.value,
),
),
);
@riverpod
Future<LinkedHashMap<String, CachedTome>> tomeLibrarySortedByTitle(
TomeLibrarySortedByTitleRef ref,
) async {
return _getSortedByTitle(await ref.watch(tomeLibraryProvider.future));
}

@riverpod
Future<SplayTreeMap<String, LinkedHashMap<String, CachedTome>>>
tomeLibraryGroupedByAuthorAndSortedByTitle(
TomeLibraryGroupedByAuthorAndSortedByTitleRef ref,
) async {
final tomeList = await ref.watch(tomeLibraryProvider.future);
final result = SplayTreeMap<String, LinkedHashMap<String, CachedTome>>(
(a, b) => a.compareTo(b),
);

for (final tome in tomeList.entries) {
final author = tome.value.tomeInfo.author ?? '';

final authorTomeList = result[author] ?? <String, CachedTome>{}
..addAll({tome.key: tome.value});

result[author] = _getSortedByTitle(authorTomeList);
}

return result;
}

LinkedHashMap<String, CachedTome> _getSortedByTitle(
Map<String, CachedTome> tomeList,
) {
final sortedList = tomeList.entries.toList()
..sort((a, b) {
final aTitle = a.value.tomeInfo.title;
final bTitle = b.value.tomeInfo.title;
return (aTitle == null || bTitle == null) ? 0 : aTitle.compareTo(bTitle);
});

return LinkedHashMap<String, CachedTome>.fromEntries(
sortedList.map(
(e) => MapEntry(
e.key,
e.value,
),
),
);
}
40 changes: 39 additions & 1 deletion lib/features/library/tome_library/tome_library.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions lib/features/library/view/author_list_tile.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import 'package:flutter/material.dart';

class AuthorListTile extends StatelessWidget {
const AuthorListTile({required this.author, super.key});

final String author;

@override
Widget build(BuildContext context) {
return ListTile(
title: Text(author),
);
}
}
37 changes: 37 additions & 0 deletions lib/features/library/view/author_tomes_sliver.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import 'dart:collection';

import 'package:bsr/features/library/library.dart';
import 'package:bsr/features/library/view/view.dart';
import 'package:flutter/material.dart';

class AuthorTomesSliver extends StatelessWidget {
const AuthorTomesSliver({
required this.author,
required this.tomes,
super.key,
});

final String author;
final LinkedHashMap<String, CachedTome> tomes;

@override
Widget build(BuildContext context) {
return SliverList.list(
children: [
SliverToBoxAdapter(
child: AuthorListTile(
author: author,
),
),
SliverList.builder(
itemBuilder: (context, index) => SliverToBoxAdapter(
child: TomeListTile(
tome: tomes.values.elementAt(index),
),
),
itemCount: tomes.length,
),
],
);
}
}
12 changes: 12 additions & 0 deletions lib/features/library/view/fullscreen_empty_library.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import 'package:flutter/material.dart';

class FullscreenEmptyLibrary extends StatelessWidget {
const FullscreenEmptyLibrary({super.key});

@override
Widget build(BuildContext context) {
return const Center(
child: Text('Library is empty'),
);
}
}
11 changes: 11 additions & 0 deletions lib/features/library/view/tome_card.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

class TomeCard extends StatelessWidget {
const TomeCard({super.key});

@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
22 changes: 22 additions & 0 deletions lib/features/library/view/tome_list_tile.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'package:bsr/features/library/library.dart';
import 'package:flutter/material.dart';

class TomeListTile extends StatelessWidget {
const TomeListTile({required this.tome, super.key});

final CachedTome tome;

@override
Widget build(BuildContext context) {
final tomeInfo = tome.tomeInfo;

return Card(
child: ListTile(
leading: const Icon(Icons.book),
title: Text(tomeInfo.title ?? ''),
subtitle: Text(tomeInfo.author ?? ''),
trailing: const Icon(Icons.more_vert),
),
);
}
}
5 changes: 5 additions & 0 deletions lib/features/library/view/view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export 'author_list_tile.dart';
export 'author_tomes_sliver.dart';
export 'fullscreen_empty_library.dart';
export 'tome_card.dart';
export 'tome_list_tile.dart';
Loading

0 comments on commit 2c346c7

Please sign in to comment.