diff --git a/lib/main.dart b/lib/main.dart index 38dc151..cd72e08 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,16 +3,15 @@ import 'dart:io' show Platform; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:google_nav_bar/google_nav_bar.dart'; import 'package:sqflite_common_ffi/sqflite_ffi.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:openlib/ui/extensions.dart'; +import 'package:openlib/ui/themes.dart'; import 'package:openlib/ui/trending_page.dart'; import 'package:openlib/ui/search_page.dart'; import 'package:openlib/ui/mylibrary_page.dart'; import 'package:openlib/ui/settings_page.dart'; import 'package:openlib/services/database.dart' show Sqlite, MyLibraryDb; import 'package:openlib/state/state.dart' - show selectedIndexProvider, dbProvider; + show selectedIndexProvider, themeModeProvider, dbProvider; void main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -31,10 +30,10 @@ void main() async { ); } -class MyApp extends StatelessWidget { +class MyApp extends ConsumerWidget { const MyApp({super.key}); @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { return MaterialApp( builder: (BuildContext context, Widget? child) { return MediaQuery( @@ -46,32 +45,9 @@ class MyApp extends StatelessWidget { }, debugShowCheckedModeBanner: false, title: 'Openlib', - theme: ThemeData( - primaryColor: Colors.white, - colorScheme: ColorScheme.light( - primary: Colors.white, - secondary: '#FB0101'.toColor(), - tertiary: Colors.black, - tertiaryContainer: '#F2F2F2'.toColor(), - ), - textTheme: const TextTheme( - displayLarge: TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - fontSize: 21, - ), - displayMedium: TextStyle( - fontSize: 13, - fontWeight: FontWeight.bold, - color: Colors.black, - overflow: TextOverflow.ellipsis, - ), - ), - fontFamily: GoogleFonts.nunito().fontFamily, - useMaterial3: true, - textSelectionTheme: TextSelectionThemeData( - selectionColor: '#FB0101'.toColor(), - selectionHandleColor: '#FB0101'.toColor())), + theme: lightTheme, + darkTheme: darkTheme, + themeMode: ref.watch(themeModeProvider), home: const HomePage(), ); } diff --git a/lib/state/state.dart b/lib/state/state.dart index 88abdc9..f31ac87 100644 --- a/lib/state/state.dart +++ b/lib/state/state.dart @@ -1,4 +1,5 @@ import 'dart:math'; +import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:openlib/services/database.dart'; import 'package:dio/dio.dart'; @@ -31,6 +32,8 @@ Map sortValues = { final selectedIndexProvider = StateProvider((ref) => 0); +final themeModeProvider = StateProvider((ref) => ThemeMode.light); + final selectedTypeState = StateProvider((ref) => "All"); final getTypeValue = Provider.autoDispose((ref) { diff --git a/lib/ui/components/book_card_widget.dart b/lib/ui/components/book_card_widget.dart index bcdaabb..22e6997 100644 --- a/lib/ui/components/book_card_widget.dart +++ b/lib/ui/components/book_card_widget.dart @@ -81,10 +81,10 @@ class BookInfoCard extends StatelessWidget { children: [ Text( title, - style: const TextStyle( + style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, - color: Colors.black, + color: Theme.of(context).colorScheme.tertiary, ), overflow: TextOverflow.ellipsis, maxLines: 2, @@ -94,7 +94,8 @@ class BookInfoCard extends StatelessWidget { style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, - color: "#4D4D4D".toColor(), + color: + Theme.of(context).textTheme.headlineMedium?.color, ), overflow: TextOverflow.ellipsis, maxLines: 1, @@ -104,7 +105,7 @@ class BookInfoCard extends StatelessWidget { style: TextStyle( fontSize: 11, fontWeight: FontWeight.bold, - color: "#7B7B7B".toColor(), + color: Theme.of(context).textTheme.headlineSmall?.color, ), overflow: TextOverflow.ellipsis, maxLines: 1, diff --git a/lib/ui/components/book_info_widget.dart b/lib/ui/components/book_info_widget.dart index a9c8ca8..c9266b3 100644 --- a/lib/ui/components/book_info_widget.dart +++ b/lib/ui/components/book_info_widget.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:openlib/ui/extensions.dart'; import 'package:cached_network_image/cached_network_image.dart'; class BookInfoWidget extends StatelessWidget { @@ -65,28 +64,32 @@ class BookInfoWidget extends StatelessWidget { text: data.title, fontSize: 19, topPadding: 15, - color: Colors.black, + color: Theme.of(context).colorScheme.tertiary, maxLines: 7, ), _TopPaddedText( text: data.publisher ?? "unknown", fontSize: 15, topPadding: 7, - color: "#595E60".toColor(), + color: Theme.of(context).textTheme.headlineMedium!.color!, maxLines: 4, ), _TopPaddedText( text: data.author ?? "unknown", fontSize: 13, topPadding: 7, - color: "#7F7F7F".toColor(), + color: Theme.of(context).textTheme.headlineSmall!.color!, maxLines: 3, ), _TopPaddedText( text: data.info ?? "", fontSize: 11, topPadding: 9, - color: "#A9A8A2".toColor(), + color: Theme.of(context) + .textTheme + .headlineSmall! + .color! + .withAlpha(155), maxLines: 4, ), // child slot of page @@ -112,7 +115,8 @@ class BookInfoWidget extends StatelessWidget { style: TextStyle( fontSize: 11, fontWeight: FontWeight.bold, - color: "#6B6B6B".toColor(), + color: + Theme.of(context).colorScheme.tertiary.withAlpha(150), letterSpacing: 1.5, ), ), diff --git a/lib/ui/components/file_buttons_widget.dart b/lib/ui/components/file_buttons_widget.dart index 4c4270b..dbc343f 100644 --- a/lib/ui/components/file_buttons_widget.dart +++ b/lib/ui/components/file_buttons_widget.dart @@ -27,10 +27,10 @@ class FileOpenAndDeleteButtons extends StatelessWidget { TextButton( style: TextButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.secondary, - textStyle: const TextStyle( + textStyle: TextStyle( fontSize: 13, fontWeight: FontWeight.w900, - color: Colors.white, + color: Theme.of(context).colorScheme.primary, )), onPressed: () => { if (format == 'pdf') @@ -82,14 +82,14 @@ class FileOpenAndDeleteButtons extends StatelessWidget { ); }); }, - child: const Padding( - padding: EdgeInsets.all(5.3), + child: Padding( + padding: const EdgeInsets.all(5.3), child: Text( 'Delete', style: TextStyle( fontSize: 13, fontWeight: FontWeight.bold, - color: Colors.black, + color: Theme.of(context).colorScheme.tertiary, ), ), ), diff --git a/lib/ui/search_page.dart b/lib/ui/search_page.dart index 896aa7f..423301e 100644 --- a/lib/ui/search_page.dart +++ b/lib/ui/search_page.dart @@ -42,12 +42,14 @@ class SearchPage extends ConsumerWidget { cursorColor: Theme.of(context).colorScheme.secondary, decoration: InputDecoration( enabledBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black45, width: 2), + borderSide: BorderSide(color: Colors.grey, width: 2), borderRadius: BorderRadius.all(Radius.circular(50)), ), - focusedBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black54, width: 2), - borderRadius: BorderRadius.all(Radius.circular(50)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.tertiary, + width: 2), + borderRadius: const BorderRadius.all(Radius.circular(50)), ), suffixIcon: IconButton( padding: const EdgeInsets.only(right: 5), @@ -88,12 +90,14 @@ class SearchPage extends ConsumerWidget { color: Theme.of(context).colorScheme.secondary, ), enabledBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black54, width: 2), + borderSide: BorderSide(color: Colors.grey, width: 2), borderRadius: BorderRadius.all(Radius.circular(50)), ), - focusedBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black54, width: 2), - borderRadius: BorderRadius.all(Radius.circular(50)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.tertiary, + width: 2), + borderRadius: const BorderRadius.all(Radius.circular(50)), ), ), icon: const Icon(Icons.arrow_drop_down), @@ -129,12 +133,14 @@ class SearchPage extends ConsumerWidget { color: Theme.of(context).colorScheme.secondary, ), enabledBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black45, width: 2), + borderSide: BorderSide(color: Colors.grey, width: 2), borderRadius: BorderRadius.all(Radius.circular(50)), ), - focusedBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black54, width: 2), - borderRadius: BorderRadius.all(Radius.circular(50)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.tertiary, + width: 2), + borderRadius: const BorderRadius.all(Radius.circular(50)), ), ), value: dropdownSortValue, diff --git a/lib/ui/settings_page.dart b/lib/ui/settings_page.dart index 3fba825..5bd0cb8 100644 --- a/lib/ui/settings_page.dart +++ b/lib/ui/settings_page.dart @@ -1,11 +1,13 @@ import 'package:flutter/material.dart'; import 'package:openlib/ui/components/page_title_widget.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:openlib/state/state.dart' show themeModeProvider; -class SettingsPage extends StatelessWidget { +class SettingsPage extends ConsumerWidget { const SettingsPage({Key? key}) : super(key: key); @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { return Padding( padding: const EdgeInsets.only(left: 5, right: 5, top: 10), child: SingleChildScrollView( @@ -28,56 +30,21 @@ class SettingsPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const Text( - "Material You", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - ), - Switch( - // This bool value toggles the switch. - value: true, - activeColor: Colors.red, - onChanged: (bool value) { - // This is called when the user toggles the switch. - print(value); - }, - ) - ], - ), - ), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 5, right: 5, top: 10), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5), - color: Theme.of(context).colorScheme.tertiaryContainer, - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const Text( + Text( "Dark Mode", style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, - color: Colors.black, + color: Theme.of(context).colorScheme.tertiary, ), ), Switch( // This bool value toggles the switch. - value: false, + value: ref.watch(themeModeProvider) == ThemeMode.dark, activeColor: Colors.red, onChanged: (bool value) { - // This is called when the user toggles the switch. - print(value); + ref.read(themeModeProvider.notifier).state = + value == true ? ThemeMode.dark : ThemeMode.light; }, ) ], diff --git a/lib/ui/themes.dart b/lib/ui/themes.dart new file mode 100644 index 0000000..a26e6bb --- /dev/null +++ b/lib/ui/themes.dart @@ -0,0 +1,72 @@ +import 'package:flutter/material.dart'; +import 'package:openlib/ui/extensions.dart'; +import 'package:google_fonts/google_fonts.dart'; + +ThemeData lightTheme = ThemeData( + primaryColor: Colors.white, + colorScheme: ColorScheme.light( + primary: Colors.white, + secondary: '#FB0101'.toColor(), + tertiary: Colors.black, + tertiaryContainer: '#F2F2F2'.toColor(), + ), + textTheme: TextTheme( + displayLarge: const TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + fontSize: 21, + ), + displayMedium: const TextStyle( + fontSize: 13, + fontWeight: FontWeight.bold, + color: Colors.black, + overflow: TextOverflow.ellipsis, + ), + headlineMedium: TextStyle( + color: "#595E60".toColor(), + ), + headlineSmall: TextStyle( + color: "#7F7F7F".toColor(), + )), + fontFamily: GoogleFonts.nunito().fontFamily, + useMaterial3: true, + textSelectionTheme: TextSelectionThemeData( + selectionColor: '#FB0101'.toColor(), + selectionHandleColor: '#FB0101'.toColor(), + ), +); + +ThemeData darkTheme = ThemeData( + primaryColor: Colors.black, + colorScheme: ColorScheme.dark( + primary: Colors.black, + secondary: '#FB0101'.toColor(), + tertiary: Colors.white, + tertiaryContainer: '#2B2B2B'.toColor(), + ), + textTheme: TextTheme( + displayLarge: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 21, + ), + displayMedium: const TextStyle( + fontSize: 13, + fontWeight: FontWeight.bold, + color: Colors.white, + overflow: TextOverflow.ellipsis, + ), + headlineMedium: TextStyle( + color: "#F5F5F5".toColor(), + ), + headlineSmall: TextStyle( + color: "#E8E2E2".toColor(), + ), + ), + fontFamily: GoogleFonts.nunito().fontFamily, + useMaterial3: true, + textSelectionTheme: TextSelectionThemeData( + selectionColor: '#FB0101'.toColor(), + selectionHandleColor: '#FB0101'.toColor(), + ), +); diff --git a/lib/ui/trending_page.dart b/lib/ui/trending_page.dart index b6af624..2a80176 100644 --- a/lib/ui/trending_page.dart +++ b/lib/ui/trending_page.dart @@ -46,10 +46,9 @@ class TrendingPage extends ConsumerWidget { ); })); }, - child: Container( + child: SizedBox( width: double.infinity, height: double.infinity, - color: const Color.fromARGB(255, 255, 255, 255), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center,