Modified Home page design to contain both trending and genres page

This commit is contained in:
dstark5
2024-10-19 18:17:59 +05:30
parent e79042ebc1
commit 43aba47453
5 changed files with 519 additions and 238 deletions

View File

@ -8,6 +8,7 @@ import 'package:flutter/services.dart';
// Package imports: // Package imports:
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_nav_bar/google_nav_bar.dart'; import 'package:google_nav_bar/google_nav_bar.dart';
import 'package:openlib/ui/home_page.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart'; import 'package:sqflite_common_ffi/sqflite_ffi.dart';
// Project imports: // Project imports:
@ -17,8 +18,6 @@ import 'package:openlib/ui/search_page.dart';
import 'package:openlib/ui/settings_page.dart'; import 'package:openlib/ui/settings_page.dart';
import 'package:openlib/ui/themes.dart'; import 'package:openlib/ui/themes.dart';
import 'package:openlib/ui/trending_page.dart'; import 'package:openlib/ui/trending_page.dart';
import 'package:openlib/ui/categories_page.dart';
import 'package:openlib/services/files.dart' import 'package:openlib/services/files.dart'
show moveFilesToAndroidInternalStorage; show moveFilesToAndroidInternalStorage;
@ -102,23 +101,22 @@ class MyApp extends ConsumerWidget {
theme: lightTheme, theme: lightTheme,
darkTheme: darkTheme, darkTheme: darkTheme,
themeMode: ref.watch(themeModeProvider), themeMode: ref.watch(themeModeProvider),
home: const HomePage(), home: const MainScreen(),
); );
} }
} }
class HomePage extends ConsumerStatefulWidget { class MainScreen extends ConsumerStatefulWidget {
const HomePage({super.key}); const MainScreen({super.key});
@override @override
ConsumerState<ConsumerStatefulWidget> createState() => _HomePageState(); ConsumerState<ConsumerStatefulWidget> createState() => _MainScreenState();
} }
class _HomePageState extends ConsumerState<HomePage> { class _MainScreenState extends ConsumerState<MainScreen> {
static const List<Widget> _widgetOptions = <Widget>[ static const List<Widget> _widgetOptions = <Widget>[
TrendingPage(), HomePage(),
SearchPage(), SearchPage(),
CategoriesPage(),
MyLibraryPage(), MyLibraryPage(),
SettingsPage() SettingsPage()
]; ];
@ -156,12 +154,12 @@ class _HomePageState extends ConsumerState<HomePage> {
tabs: [ tabs: [
GButton( GButton(
icon: Icons.trending_up, icon: Icons.trending_up,
text: 'Trending', text: 'Home',
iconColor: isDarkMode ? Colors.white : Colors.black, iconColor: isDarkMode ? Colors.white : Colors.black,
textStyle: const TextStyle( textStyle: const TextStyle(
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
color: Colors.white, color: Colors.white,
fontSize: 10, fontSize: 11,
), ),
), ),
GButton( GButton(
@ -171,27 +169,17 @@ class _HomePageState extends ConsumerState<HomePage> {
textStyle: const TextStyle( textStyle: const TextStyle(
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
color: Colors.white, color: Colors.white,
fontSize: 10, fontSize: 11,
),
),
GButton(
icon: Icons.home,
text: 'Home',
iconColor: isDarkMode ? Colors.white : Colors.black,
textStyle: const TextStyle(
fontWeight: FontWeight.w900,
color: Colors.white,
fontSize: 10,
), ),
), ),
GButton( GButton(
icon: Icons.collections_bookmark, icon: Icons.collections_bookmark,
text: 'Library', text: 'My Library',
iconColor: isDarkMode ? Colors.white : Colors.black, iconColor: isDarkMode ? Colors.white : Colors.black,
textStyle: const TextStyle( textStyle: const TextStyle(
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
color: Colors.white, color: Colors.white,
fontSize: 10, fontSize: 11,
), ),
), ),
GButton( GButton(
@ -201,7 +189,7 @@ class _HomePageState extends ConsumerState<HomePage> {
textStyle: const TextStyle( textStyle: const TextStyle(
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
color: Colors.white, color: Colors.white,
fontSize: 10, fontSize: 11,
), ),
), ),
], ],

View File

@ -42,6 +42,7 @@ Map<String, String> sortValues = {
List<String> fileType = ["All", "PDF", "Epub", "Cbr", "Cbz"]; List<String> fileType = ["All", "PDF", "Epub", "Cbr", "Cbz"];
final selectedIndexProvider = StateProvider<int>((ref) => 0); final selectedIndexProvider = StateProvider<int>((ref) => 0);
final homePageSelectedIndexProvider = StateProvider<int>((ref) => 0);
final themeModeProvider = StateProvider<ThemeMode>((ref) => ThemeMode.light); final themeModeProvider = StateProvider<ThemeMode>((ref) => ThemeMode.light);
@ -72,9 +73,11 @@ final searchQueryProvider = StateProvider<String>((ref) => "");
// Sub category type list providers // Sub category type list providers
final getSubCategoryTypeList = FutureProvider.family.autoDispose<List<CategoryBookData>, String>((ref, url) async { final getSubCategoryTypeList = FutureProvider.family
.autoDispose<List<CategoryBookData>, String>((ref, url) async {
SubCategoriesTypeList subCategoriesTypeList = SubCategoriesTypeList(); SubCategoriesTypeList subCategoriesTypeList = SubCategoriesTypeList();
List<CategoryBookData> subCategories = await subCategoriesTypeList.categoriesBooks(url: url); List<CategoryBookData> subCategories =
await subCategoriesTypeList.categoriesBooks(url: url);
List<CategoryBookData> uniqueArray = subCategories.toSet().toList(); List<CategoryBookData> uniqueArray = subCategories.toSet().toList();
uniqueArray.shuffle(); uniqueArray.shuffle();
return uniqueArray; return uniqueArray;

View File

@ -11,83 +11,221 @@ import 'package:openlib/ui/extensions.dart';
import 'package:openlib/ui/results_page.dart'; import 'package:openlib/ui/results_page.dart';
import 'package:openlib/ui/components/error_widget.dart'; import 'package:openlib/ui/components/error_widget.dart';
import 'package:openlib/state/state.dart' import 'package:openlib/state/state.dart'
show show getSubCategoryTypeList, enableFiltersState;
getSubCategoryTypeList,
enableFiltersState;
class CategoryBook { class CategoryBook {
final String title; final String title;
final String thumbnail; final String thumbnail;
final String tag; final String tag;
final String info; final String info;
CategoryBook({required this.title, required this.thumbnail,required this.tag, required this.info}); CategoryBook(
{required this.title,
required this.thumbnail,
required this.tag,
required this.info});
} }
List<CategoryBook> categoriesTypeValues = [ List<CategoryBook> categoriesTypeValues = [
CategoryBook( info : "Timeless literary works often revered for their artistic merit and cultural significance.", CategoryBook(
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/1%20classic.jpeg", title: "Classics", tag: "list/tag/classics"), info:
CategoryBook( info : "Stories focused on romantic relationships, exploring love, passion, and emotional connections.", "Timeless literary works often revered for their artistic merit and cultural significance.",
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/2%20romance.jpeg", title: "Romance", tag: "list/tag/romance"), thumbnail:
CategoryBook( info : "Narrative literature created from the imagination, not based on real events.", "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/1%20classic.jpeg",
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/3%20fiction.jpeg", title: "Fiction", tag: "list/tag/fiction"), title: "Classics",
CategoryBook( info : "Books targeted at teenage readers, addressing themes relevant to adolescence.", tag: "list/tag/classics"),
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/4%20young%20adult.jpeg", title: "Young Adult", tag: "list/tag/young-adult"), CategoryBook(
CategoryBook( info : "A genre featuring magical elements, mythical creatures, and fantastical worlds.", info:
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/5%20fantasy%20book.jpeg", title: "Fantasy", tag: "list/tag/fantasy"), "Stories focused on romantic relationships, exploring love, passion, and emotional connections.",
CategoryBook( info : "Literature that explores futuristic concepts, advanced technology, and space exploration.", thumbnail:
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/6%20science%20fiction.jpeg", title: "Science Fiction", tag: "list/tag/science-fiction"), "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/2%20romance.jpeg",
CategoryBook( info : "Works based on factual information, including essays, biographies, and documentaries.", title: "Romance",
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/7%20non%20fiction.jpeg", title: "Nonfiction", tag: "list/tag/non-fiction"), tag: "list/tag/romance"),
CategoryBook( info : "Books aimed at young readers, often with illustrations and simple narratives.", CategoryBook(
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/8%20children.jpeg", title: "Children", tag: "list/tag/children"), info:
CategoryBook( info : "Literature that examines past events, cultures, and significant historical figures.", "Narrative literature created from the imagination, not based on real events.",
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/9%20history.jpeg", title: "History", tag: "list/tag/history"), thumbnail:
CategoryBook( info : "Stories centered around suspenseful plots, often involving crime or puzzles to solve.", "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/3%20fiction.jpeg",
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/10%20mystery.jpeg", title: "Mystery", tag: "list/tag/mystery"), title: "Fiction",
CategoryBook( info : "Refers to the artwork and design that visually represents a book, influencing reader interest.", tag: "list/tag/fiction"),
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/11%20covers.jpeg", title: "Covers", tag: "list/tag/covers"), CategoryBook(
CategoryBook( info : "A genre designed to evoke fear, dread, or terror in the reader through suspenseful storytelling.", info:
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/12%20horror.jpeg", title: "Horror", tag: "list/tag/horror"), "Books targeted at teenage readers, addressing themes relevant to adolescence.",
CategoryBook( info : "Novels set in a specific historical period, blending factual events with fictional characters.", thumbnail:
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/13%20historical%20fiction.jpeg", title: "Historical Fiction", tag: "list/tag/historical-fiction"), "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/4%20young%20adult.jpeg",
CategoryBook( info : "Literature that features male same-sex relationships and explores LGBTQ+ themes.", title: "Young Adult",
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/14%20gay.jpeg", title: "Gay", tag: "list/tag/gay"), tag: "list/tag/young-adult"),
CategoryBook( info : "Often refers to critically acclaimed or popular books, usually categorized by rankings or awards.", CategoryBook(
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/15%20best%20.jpeg", title: "Best", tag: "list/tag/best"), info:
CategoryBook( info : "Refers to the names of books, which often reflect their themes or subject matter.", "A genre featuring magical elements, mythical creatures, and fantastical worlds.",
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/16%20titles.jpeg", title: "Titles", tag: "list/tag/titles"), thumbnail:
CategoryBook( info : "Books intended for readers aged 8-12, featuring age-appropriate themes and characters.", "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/5%20fantasy%20book.jpeg",
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/17%20middle%20grade.jpeg", title: "Middle Grade", tag: "list/tag/middle-grade"), title: "Fantasy",
CategoryBook( info : "Stories that incorporate supernatural elements, including ghosts, vampires, and otherworldly beings.", tag: "list/tag/fantasy"),
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/18%20paranormal.jpeg", title: "Paranormal", tag: "list/tag/paranormal"), CategoryBook(
CategoryBook( info : "A theme exploring the complexities and nuances of love in various forms and relationships.", info:
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/19%20love.jpeg", title: "Love", tag: "list/tag/love"), "Literature that explores futuristic concepts, advanced technology, and space exploration.",
CategoryBook( info : "Literature that represents diverse sexual orientations and gender identities within the LGBTQ+ spectrum.", thumbnail:
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/20%20queer.jpeg", title: "Queer", tag: "list/tag/queer"), "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/6%20science%20fiction.jpeg",
CategoryBook( info : "Works based on factual information, including essays, biographies, and documentaries.", title: "Science Fiction",
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/21%20nonfictino.jpeg", title: "Nonfiction", tag: "list/tag/nonfiction"), tag: "list/tag/science-fiction"),
CategoryBook( info : "Novels combining romantic plots set against a historical backdrop.", CategoryBook(
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/22%20historical%20romance.jpeg", title: "Historical Romance", tag: "list/tag/historical-romance"), info:
CategoryBook( info : "Literature encompassing themes related to lesbian, gay, bisexual, and transgender identities.", "Works based on factual information, including essays, biographies, and documentaries.",
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/23%20lgbt.jpeg", title: "LGBT", tag: "list/tag/lgbt"), thumbnail:
CategoryBook( info : "Works set in modern times, often addressing current social issues and relatable characters.", "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/7%20non%20fiction.jpeg",
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/24%20contemporary.jpeg", title: "Contemporary", tag: "list/tag/contemporary"), title: "Nonfiction",
CategoryBook( info : "A suspenseful genre focused on excitement, tension, and unexpected twists.", tag: "list/tag/non-fiction"),
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/25%20thriller.jpeg", title: "Thriller", tag: "list/tag/thriller"), CategoryBook(
CategoryBook( info : "Literature that explores women's experiences, perspectives, and empowerment.", info:
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/26%20women.jpeg", title: "Women", tag: "list/tag/women"), "Books aimed at young readers, often with illustrations and simple narratives.",
CategoryBook( info : "Nonfiction works detailing the life story of an individual, highlighting their achievements and challenges.", thumbnail:
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/27%20biography.jpeg", title: "Biography", tag: "list/tag/biography"), "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/8%20children.jpeg",
CategoryBook( info : "Inclusive literature representing the experiences of the lesbian, gay, bisexual, transgender, and queer community.", title: "Children",
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/28%20lgbtq.jpeg", title: "LGBTQ", tag: "list/tag/lgbtq"), tag: "list/tag/children"),
CategoryBook( info : "A collection of related books that follow a common storyline or set of characters.", CategoryBook(
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/29%20series%20.jpeg", title: "Series", tag: "list/tag/series"), info:
CategoryBook( info : "Refers to prompts or contests encouraging creative thinking about book titles.", "Literature that examines past events, cultures, and significant historical figures.",
thumbnail: "https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/30%20title%20chhallenge.jpeg", title: "Title Challenge", tag: "list/tag/title-challenge"), thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/9%20history.jpeg",
title: "History",
tag: "list/tag/history"),
CategoryBook(
info:
"Stories centered around suspenseful plots, often involving crime or puzzles to solve.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/10%20mystery.jpeg",
title: "Mystery",
tag: "list/tag/mystery"),
CategoryBook(
info:
"Refers to the artwork and design that visually represents a book, influencing reader interest.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/11%20covers.jpeg",
title: "Covers",
tag: "list/tag/covers"),
CategoryBook(
info:
"A genre designed to evoke fear, dread, or terror in the reader through suspenseful storytelling.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/12%20horror.jpeg",
title: "Horror",
tag: "list/tag/horror"),
CategoryBook(
info:
"Novels set in a specific historical period, blending factual events with fictional characters.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/13%20historical%20fiction.jpeg",
title: "Historical Fiction",
tag: "list/tag/historical-fiction"),
CategoryBook(
info:
"Often refers to critically acclaimed or popular books, usually categorized by rankings or awards.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/15%20best%20.jpeg",
title: "Best",
tag: "list/tag/best"),
CategoryBook(
info:
"Refers to the names of books, which often reflect their themes or subject matter.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/16%20titles.jpeg",
title: "Titles",
tag: "list/tag/titles"),
CategoryBook(
info:
"Books intended for readers aged 8-12, featuring age-appropriate themes and characters.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/17%20middle%20grade.jpeg",
title: "Middle Grade",
tag: "list/tag/middle-grade"),
CategoryBook(
info:
"Stories that incorporate supernatural elements, including ghosts, vampires, and otherworldly beings.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/18%20paranormal.jpeg",
title: "Paranormal",
tag: "list/tag/paranormal"),
CategoryBook(
info:
"A theme exploring the complexities and nuances of love in various forms and relationships.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/19%20love.jpeg",
title: "Love",
tag: "list/tag/love"),
CategoryBook(
info:
"Literature that represents diverse sexual orientations and gender identities within the LGBTQ+ spectrum.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/20%20queer.jpeg",
title: "Queer",
tag: "list/tag/queer"),
CategoryBook(
info:
"Works based on factual information, including essays, biographies, and documentaries.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/21%20nonfictino.jpeg",
title: "Nonfiction",
tag: "list/tag/nonfiction"),
CategoryBook(
info:
"Novels combining romantic plots set against a historical backdrop.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/22%20historical%20romance.jpeg",
title: "Historical Romance",
tag: "list/tag/historical-romance"),
CategoryBook(
info:
"Works set in modern times, often addressing current social issues and relatable characters.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/24%20contemporary.jpeg",
title: "Contemporary",
tag: "list/tag/contemporary"),
CategoryBook(
info:
"A suspenseful genre focused on excitement, tension, and unexpected twists.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/25%20thriller.jpeg",
title: "Thriller",
tag: "list/tag/thriller"),
CategoryBook(
info:
"Literature that explores women's experiences, perspectives, and empowerment.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/26%20women.jpeg",
title: "Women",
tag: "list/tag/women"),
CategoryBook(
info:
"Nonfiction works detailing the life story of an individual, highlighting their achievements and challenges.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/27%20biography.jpeg",
title: "Biography",
tag: "list/tag/biography"),
CategoryBook(
info:
"Inclusive literature representing the experiences of the lesbian, gay, bisexual, transgender, and queer community.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/28%20lgbtq.jpeg",
title: "LGBTQ",
tag: "list/tag/lgbtq"),
CategoryBook(
info:
"A collection of related books that follow a common storyline or set of characters.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/29%20series%20.jpeg",
title: "Series",
tag: "list/tag/series"),
CategoryBook(
info:
"Refers to prompts or contests encouraging creative thinking about book titles.",
thumbnail:
"https://raw.githubusercontent.com/Nav-jangra/images/refs/heads/main/30%20title%20chhallenge.jpeg",
title: "Title Challenge",
tag: "list/tag/title-challenge"),
]; ];
class CategoriesPage extends ConsumerWidget { class GenresPage extends ConsumerWidget {
const CategoriesPage({super.key}); const GenresPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
@ -97,9 +235,6 @@ class CategoriesPage extends ConsumerWidget {
padding: const EdgeInsets.only(left: 5, right: 5, top: 10), padding: const EdgeInsets.only(left: 5, right: 5, top: 10),
child: CustomScrollView( child: CustomScrollView(
slivers: <Widget>[ slivers: <Widget>[
const SliverToBoxAdapter(
child: TitleText("Categories"),
),
SliverPadding( SliverPadding(
padding: const EdgeInsets.only(left: 5, right: 5, top: 10), padding: const EdgeInsets.only(left: 5, right: 5, top: 10),
sliver: SliverList( sliver: SliverList(
@ -115,7 +250,10 @@ class CategoriesPage extends ConsumerWidget {
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (BuildContext context) { builder: (BuildContext context) {
return CategoryListingPage(url: category.tag, title: category.title,); return CategoryListingPage(
url: category.tag,
title: category.title,
);
}, },
), ),
); );
@ -155,7 +293,6 @@ class BookInfoCard extends StatelessWidget {
height: 120, height: 120,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5), borderRadius: BorderRadius.circular(5),
color: Theme.of(context).colorScheme.tertiaryContainer,
), ),
margin: const EdgeInsets.only(bottom: 10), margin: const EdgeInsets.only(bottom: 10),
child: Row( child: Row(
@ -202,15 +339,15 @@ class BookInfoCard extends StatelessWidget {
child: SizedBox( child: SizedBox(
width: double.infinity, width: double.infinity,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
title, title,
style: TextStyle( style: TextStyle(
fontSize: 25, fontSize: 19,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.secondary, color: Theme.of(context).colorScheme.tertiary,
), ),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
maxLines: 2, maxLines: 2,
@ -238,153 +375,156 @@ class BookInfoCard extends StatelessWidget {
} }
class CategoryListingPage extends ConsumerWidget { class CategoryListingPage extends ConsumerWidget {
const CategoryListingPage({super.key, required this.url, required this.title}); const CategoryListingPage(
{super.key, required this.url, required this.title});
final double imageHeight = 145; final double imageHeight = 145;
final double imageWidth = 105; final double imageWidth = 105;
final String url ; final String url;
final String title; final String title;
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final trendingBooks = ref.watch(getSubCategoryTypeList( url)); final booksBasedOnGenre = ref.watch(getSubCategoryTypeList(url));
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.background, backgroundColor: Theme.of(context).colorScheme.background,
title: const Text("Openlib"), title: const Text("Openlib"),
titleTextStyle: Theme.of(context).textTheme.displayLarge, titleTextStyle: Theme.of(context).textTheme.displayLarge,
), ),
body : trendingBooks.when( body: booksBasedOnGenre.when(
skipLoadingOnRefresh: false, skipLoadingOnRefresh: false,
data: (data) { data: (data) {
return Padding( return Padding(
padding: const EdgeInsets.only(left: 5, right: 5, top: 10), padding: const EdgeInsets.only(left: 5, right: 5, top: 10),
child: CustomScrollView( child: CustomScrollView(
physics: const BouncingScrollPhysics(), physics: const BouncingScrollPhysics(),
slivers: [ slivers: [
SliverToBoxAdapter( SliverToBoxAdapter(
child: TitleText(title), child: TitleText(title),
),
SliverPadding(
padding: const EdgeInsets.all(5),
sliver: SliverGrid(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 10.0,
crossAxisSpacing: 13.0,
mainAxisExtent: 205,
), ),
delegate: SliverChildBuilderDelegate( SliverPadding(
(BuildContext context, int index) { padding: const EdgeInsets.all(5),
return InkWell( sliver: SliverGrid(
onTap: () { gridDelegate:
ref.read(enableFiltersState.notifier).state = false; const SliverGridDelegateWithFixedCrossAxisCount(
Navigator.push(context, MaterialPageRoute( crossAxisCount: 3,
builder: (BuildContext context) { mainAxisSpacing: 10.0,
return ResultPage( crossAxisSpacing: 13.0,
searchQuery: data[index].title!); mainAxisExtent: 205,
})); ),
}, delegate: SliverChildBuilderDelegate(
child: SizedBox( (BuildContext context, int index) {
width: double.infinity, return InkWell(
height: double.infinity, onTap: () {
child: Column( ref.read(enableFiltersState.notifier).state =
mainAxisAlignment: MainAxisAlignment.start, false;
crossAxisAlignment: CrossAxisAlignment.center, Navigator.push(context, MaterialPageRoute(
children: [ builder: (BuildContext context) {
CachedNetworkImage( return ResultPage(
height: imageHeight, searchQuery: data[index].title!);
width: imageWidth, }));
imageUrl: data[index].thumbnail!, },
imageBuilder: (context, imageProvider) => child: SizedBox(
Container( width: double.infinity,
decoration: BoxDecoration( height: double.infinity,
boxShadow: const [ child: Column(
BoxShadow( mainAxisAlignment: MainAxisAlignment.start,
color: Colors.grey, crossAxisAlignment:
spreadRadius: 0.1, CrossAxisAlignment.center,
blurRadius: 1) children: [
], CachedNetworkImage(
borderRadius: const BorderRadius.all(
Radius.circular(5)),
image: DecorationImage(
image: imageProvider,
fit: BoxFit.fill,
),
),
),
placeholder: (context, url) => Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: "#E3E8E9".toColor(),
),
height: imageHeight,
width: imageWidth,
),
errorWidget: (context, url, error) {
return Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(5),
color: Colors.grey,
),
height: imageHeight, height: imageHeight,
width: imageWidth, width: imageWidth,
child: const Center( imageUrl: data[index].thumbnail!,
child: Icon(Icons.image_rounded), imageBuilder:
(context, imageProvider) =>
Container(
decoration: BoxDecoration(
boxShadow: const [
BoxShadow(
color: Colors.grey,
spreadRadius: 0.1,
blurRadius: 1)
],
borderRadius:
const BorderRadius.all(
Radius.circular(5)),
image: DecorationImage(
image: imageProvider,
fit: BoxFit.fill,
),
),
), ),
); placeholder: (context, url) =>
}, Container(
), decoration: BoxDecoration(
Padding( borderRadius:
padding: const EdgeInsets.only(top: 4), BorderRadius.circular(5),
child: SizedBox( color: "#E3E8E9".toColor(),
width: imageWidth, ),
child: Text( height: imageHeight,
data[index].title!, width: imageWidth,
style: Theme.of(context) ),
.textTheme errorWidget: (context, url, error) {
.displayMedium, return Container(
maxLines: 2, decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(5),
color: Colors.grey,
),
height: imageHeight,
width: imageWidth,
child: const Center(
child: Icon(Icons.image_rounded),
),
);
},
), ),
), Padding(
), padding: const EdgeInsets.only(top: 4),
]), child: SizedBox(
), width: imageWidth,
); child: Text(
}, data[index].title!,
childCount: data.length, style: Theme.of(context)
.textTheme
.displayMedium,
maxLines: 2,
),
),
),
]),
),
);
},
childCount: data.length,
),
),
), ),
), ],
), ),
], );
), },
); error: (error, _) {
}, return CustomErrorWidget(
error: (error, _) { error: error,
return CustomErrorWidget( stackTrace: _,
error: error, // onRefresh: () {
stackTrace: _, // // ignore: unused_result
// onRefresh: () { // ref.refresh(getbooksBasedOnGenre);
// // ignore: unused_result // },
// ref.refresh(getTrendingBooks); );
// }, },
); loading: () {
}, return Center(
loading: () { child: SizedBox(
return Center( width: 25,
child: SizedBox( height: 25,
width: 25, child: CircularProgressIndicator(
height: 25, color: Theme.of(context).colorScheme.secondary,
child: CircularProgressIndicator( strokeCap: StrokeCap.round,
color: Theme.of(context).colorScheme.secondary, ),
strokeCap: StrokeCap.round, ));
), }));
));
})
);
} }
} }

154
lib/ui/home_page.dart Normal file
View File

@ -0,0 +1,154 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:openlib/state/state.dart';
import 'package:openlib/ui/categories_page.dart';
import 'package:openlib/ui/components/page_title_widget.dart';
import 'package:openlib/ui/trending_page.dart';
class HomePage extends ConsumerStatefulWidget {
const HomePage({super.key});
@override
ConsumerState<ConsumerStatefulWidget> createState() => _HomePageState();
}
class _HomePageState extends ConsumerState<HomePage> {
final List<Widget> _pages = const [
TrendingPage(),
GenresPage(),
];
@override
Widget build(BuildContext context) {
final selectedIndex = ref.watch(homePageSelectedIndexProvider);
return Scaffold(
body: Column(
children: [
Padding(
padding: const EdgeInsets.only(left: 5, right: 5, top: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TitleText(selectedIndex == 0 ? "Trending" : "Genres"),
PelletContainer(
selectedIndex: selectedIndex,
onTrendingSelected: () => {
ref.read(homePageSelectedIndexProvider.notifier).state = 0
},
onCategoriesSelected: () => {
ref.read(homePageSelectedIndexProvider.notifier).state = 1
},
),
],
),
),
Expanded(child: _pages[selectedIndex]), // Display the selected page
],
),
);
}
}
class PelletContainer extends StatelessWidget {
final int selectedIndex;
final VoidCallback onTrendingSelected;
final VoidCallback onCategoriesSelected;
const PelletContainer({
super.key,
required this.selectedIndex,
required this.onTrendingSelected,
required this.onCategoriesSelected,
});
@override
Widget build(BuildContext context) {
return Container(
height: 30,
width: 125,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Theme.of(context).colorScheme.secondary,
border: Border.all(color: Theme.of(context).colorScheme.secondary),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
// Left Button (Trending)
Expanded(
child: GestureDetector(
onTap: onTrendingSelected,
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
decoration: BoxDecoration(
color: selectedIndex == 0
? Theme.of(context).colorScheme.secondary
: Theme.of(context).colorScheme.primary,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(25),
bottomLeft: Radius.circular(25),
topRight: Radius.circular(0),
bottomRight: Radius.circular(0),
),
),
child: TextButton.icon(
onPressed: null, // Disable direct onPressed to avoid conflict
icon: Icon(
Icons.trending_up,
color: selectedIndex == 0
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.tertiary,
),
label: const Text(''), // Empty label
style: TextButton.styleFrom(
backgroundColor: Colors.transparent,
padding: const EdgeInsets.symmetric(horizontal: 8),
),
),
),
),
),
const VerticalDivider(
width: 0,
thickness: 1,
color: Colors.grey,
),
// Right Button (Categories)
Expanded(
child: GestureDetector(
onTap: onCategoriesSelected,
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
decoration: BoxDecoration(
color: selectedIndex == 1
? Theme.of(context).colorScheme.secondary
: Theme.of(context).colorScheme.primary,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(0),
bottomLeft: Radius.circular(0),
topRight: Radius.circular(25),
bottomRight: Radius.circular(25),
),
),
child: TextButton.icon(
onPressed: null,
icon: Icon(
Icons.dashboard_rounded,
color: selectedIndex == 1
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.tertiary,
),
label: const Text(''), // Empty label
style: TextButton.styleFrom(
backgroundColor: Colors.transparent,
padding: const EdgeInsets.symmetric(horizontal: 8),
),
),
),
),
),
],
),
);
}
}

View File

@ -7,7 +7,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
// Project imports: // Project imports:
import 'package:openlib/ui/components/error_widget.dart'; import 'package:openlib/ui/components/error_widget.dart';
import 'package:openlib/ui/components/page_title_widget.dart';
import 'package:openlib/ui/results_page.dart'; import 'package:openlib/ui/results_page.dart';
import 'extensions.dart'; import 'extensions.dart';
@ -31,9 +30,6 @@ class TrendingPage extends ConsumerWidget {
child: CustomScrollView( child: CustomScrollView(
physics: const BouncingScrollPhysics(), physics: const BouncingScrollPhysics(),
slivers: [ slivers: [
const SliverToBoxAdapter(
child: TitleText("Trending"),
),
SliverPadding( SliverPadding(
padding: const EdgeInsets.all(5), padding: const EdgeInsets.all(5),
sliver: SliverGrid( sliver: SliverGrid(