added dark mode

This commit is contained in:
dstark5
2023-08-23 01:02:21 -07:00
parent b2a1be7a7e
commit 010dc1dfdb
9 changed files with 130 additions and 102 deletions

View File

@ -3,16 +3,15 @@ import 'dart:io' show Platform;
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:sqflite_common_ffi/sqflite_ffi.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/trending_page.dart';
import 'package:openlib/ui/search_page.dart'; import 'package:openlib/ui/search_page.dart';
import 'package:openlib/ui/mylibrary_page.dart'; import 'package:openlib/ui/mylibrary_page.dart';
import 'package:openlib/ui/settings_page.dart'; import 'package:openlib/ui/settings_page.dart';
import 'package:openlib/services/database.dart' show Sqlite, MyLibraryDb; import 'package:openlib/services/database.dart' show Sqlite, MyLibraryDb;
import 'package:openlib/state/state.dart' import 'package:openlib/state/state.dart'
show selectedIndexProvider, dbProvider; show selectedIndexProvider, themeModeProvider, dbProvider;
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
@ -31,10 +30,10 @@ void main() async {
); );
} }
class MyApp extends StatelessWidget { class MyApp extends ConsumerWidget {
const MyApp({super.key}); const MyApp({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context, WidgetRef ref) {
return MaterialApp( return MaterialApp(
builder: (BuildContext context, Widget? child) { builder: (BuildContext context, Widget? child) {
return MediaQuery( return MediaQuery(
@ -46,32 +45,9 @@ class MyApp extends StatelessWidget {
}, },
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
title: 'Openlib', title: 'Openlib',
theme: ThemeData( theme: lightTheme,
primaryColor: Colors.white, darkTheme: darkTheme,
colorScheme: ColorScheme.light( themeMode: ref.watch(themeModeProvider),
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())),
home: const HomePage(), home: const HomePage(),
); );
} }

View File

@ -1,4 +1,5 @@
import 'dart:math'; import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:openlib/services/database.dart'; import 'package:openlib/services/database.dart';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
@ -31,6 +32,8 @@ Map<String, String> sortValues = {
final selectedIndexProvider = StateProvider<int>((ref) => 0); final selectedIndexProvider = StateProvider<int>((ref) => 0);
final themeModeProvider = StateProvider<ThemeMode>((ref) => ThemeMode.light);
final selectedTypeState = StateProvider<String>((ref) => "All"); final selectedTypeState = StateProvider<String>((ref) => "All");
final getTypeValue = Provider.autoDispose<String>((ref) { final getTypeValue = Provider.autoDispose<String>((ref) {

View File

@ -81,10 +81,10 @@ class BookInfoCard extends StatelessWidget {
children: [ children: [
Text( Text(
title, title,
style: const TextStyle( style: TextStyle(
fontSize: 15, fontSize: 15,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.black, color: Theme.of(context).colorScheme.tertiary,
), ),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
maxLines: 2, maxLines: 2,
@ -94,7 +94,8 @@ class BookInfoCard extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: "#4D4D4D".toColor(), color:
Theme.of(context).textTheme.headlineMedium?.color,
), ),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
maxLines: 1, maxLines: 1,
@ -104,7 +105,7 @@ class BookInfoCard extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 11, fontSize: 11,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: "#7B7B7B".toColor(), color: Theme.of(context).textTheme.headlineSmall?.color,
), ),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
maxLines: 1, maxLines: 1,

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:openlib/ui/extensions.dart';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
class BookInfoWidget extends StatelessWidget { class BookInfoWidget extends StatelessWidget {
@ -65,28 +64,32 @@ class BookInfoWidget extends StatelessWidget {
text: data.title, text: data.title,
fontSize: 19, fontSize: 19,
topPadding: 15, topPadding: 15,
color: Colors.black, color: Theme.of(context).colorScheme.tertiary,
maxLines: 7, maxLines: 7,
), ),
_TopPaddedText( _TopPaddedText(
text: data.publisher ?? "unknown", text: data.publisher ?? "unknown",
fontSize: 15, fontSize: 15,
topPadding: 7, topPadding: 7,
color: "#595E60".toColor(), color: Theme.of(context).textTheme.headlineMedium!.color!,
maxLines: 4, maxLines: 4,
), ),
_TopPaddedText( _TopPaddedText(
text: data.author ?? "unknown", text: data.author ?? "unknown",
fontSize: 13, fontSize: 13,
topPadding: 7, topPadding: 7,
color: "#7F7F7F".toColor(), color: Theme.of(context).textTheme.headlineSmall!.color!,
maxLines: 3, maxLines: 3,
), ),
_TopPaddedText( _TopPaddedText(
text: data.info ?? "", text: data.info ?? "",
fontSize: 11, fontSize: 11,
topPadding: 9, topPadding: 9,
color: "#A9A8A2".toColor(), color: Theme.of(context)
.textTheme
.headlineSmall!
.color!
.withAlpha(155),
maxLines: 4, maxLines: 4,
), ),
// child slot of page // child slot of page
@ -112,7 +115,8 @@ class BookInfoWidget extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 11, fontSize: 11,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: "#6B6B6B".toColor(), color:
Theme.of(context).colorScheme.tertiary.withAlpha(150),
letterSpacing: 1.5, letterSpacing: 1.5,
), ),
), ),

View File

@ -27,10 +27,10 @@ class FileOpenAndDeleteButtons extends StatelessWidget {
TextButton( TextButton(
style: TextButton.styleFrom( style: TextButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.secondary, backgroundColor: Theme.of(context).colorScheme.secondary,
textStyle: const TextStyle( textStyle: TextStyle(
fontSize: 13, fontSize: 13,
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
color: Colors.white, color: Theme.of(context).colorScheme.primary,
)), )),
onPressed: () => { onPressed: () => {
if (format == 'pdf') if (format == 'pdf')
@ -82,14 +82,14 @@ class FileOpenAndDeleteButtons extends StatelessWidget {
); );
}); });
}, },
child: const Padding( child: Padding(
padding: EdgeInsets.all(5.3), padding: const EdgeInsets.all(5.3),
child: Text( child: Text(
'Delete', 'Delete',
style: TextStyle( style: TextStyle(
fontSize: 13, fontSize: 13,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.black, color: Theme.of(context).colorScheme.tertiary,
), ),
), ),
), ),

View File

@ -42,12 +42,14 @@ class SearchPage extends ConsumerWidget {
cursorColor: Theme.of(context).colorScheme.secondary, cursorColor: Theme.of(context).colorScheme.secondary,
decoration: InputDecoration( decoration: InputDecoration(
enabledBorder: const OutlineInputBorder( enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black45, width: 2), borderSide: BorderSide(color: Colors.grey, width: 2),
borderRadius: BorderRadius.all(Radius.circular(50)), borderRadius: BorderRadius.all(Radius.circular(50)),
), ),
focusedBorder: const OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.black54, width: 2), borderSide: BorderSide(
borderRadius: BorderRadius.all(Radius.circular(50)), color: Theme.of(context).colorScheme.tertiary,
width: 2),
borderRadius: const BorderRadius.all(Radius.circular(50)),
), ),
suffixIcon: IconButton( suffixIcon: IconButton(
padding: const EdgeInsets.only(right: 5), padding: const EdgeInsets.only(right: 5),
@ -88,12 +90,14 @@ class SearchPage extends ConsumerWidget {
color: Theme.of(context).colorScheme.secondary, color: Theme.of(context).colorScheme.secondary,
), ),
enabledBorder: const OutlineInputBorder( enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black54, width: 2), borderSide: BorderSide(color: Colors.grey, width: 2),
borderRadius: BorderRadius.all(Radius.circular(50)), borderRadius: BorderRadius.all(Radius.circular(50)),
), ),
focusedBorder: const OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.black54, width: 2), borderSide: BorderSide(
borderRadius: BorderRadius.all(Radius.circular(50)), color: Theme.of(context).colorScheme.tertiary,
width: 2),
borderRadius: const BorderRadius.all(Radius.circular(50)),
), ),
), ),
icon: const Icon(Icons.arrow_drop_down), icon: const Icon(Icons.arrow_drop_down),
@ -129,12 +133,14 @@ class SearchPage extends ConsumerWidget {
color: Theme.of(context).colorScheme.secondary, color: Theme.of(context).colorScheme.secondary,
), ),
enabledBorder: const OutlineInputBorder( enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black45, width: 2), borderSide: BorderSide(color: Colors.grey, width: 2),
borderRadius: BorderRadius.all(Radius.circular(50)), borderRadius: BorderRadius.all(Radius.circular(50)),
), ),
focusedBorder: const OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.black54, width: 2), borderSide: BorderSide(
borderRadius: BorderRadius.all(Radius.circular(50)), color: Theme.of(context).colorScheme.tertiary,
width: 2),
borderRadius: const BorderRadius.all(Radius.circular(50)),
), ),
), ),
value: dropdownSortValue, value: dropdownSortValue,

View File

@ -1,11 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:openlib/ui/components/page_title_widget.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); const SettingsPage({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context, WidgetRef ref) {
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: SingleChildScrollView( child: SingleChildScrollView(
@ -28,56 +30,21 @@ class SettingsPage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
const Text( 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(
"Dark Mode", "Dark Mode",
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.black, color: Theme.of(context).colorScheme.tertiary,
), ),
), ),
Switch( Switch(
// This bool value toggles the switch. // This bool value toggles the switch.
value: false, value: ref.watch(themeModeProvider) == ThemeMode.dark,
activeColor: Colors.red, activeColor: Colors.red,
onChanged: (bool value) { onChanged: (bool value) {
// This is called when the user toggles the switch. ref.read(themeModeProvider.notifier).state =
print(value); value == true ? ThemeMode.dark : ThemeMode.light;
}, },
) )
], ],

72
lib/ui/themes.dart Normal file
View File

@ -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(),
),
);

View File

@ -46,10 +46,9 @@ class TrendingPage extends ConsumerWidget {
); );
})); }));
}, },
child: Container( child: SizedBox(
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
color: const Color.fromARGB(255, 255, 255, 255),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,