From 967923c771e3e141d63da384f2ddb0890a0a044e Mon Sep 17 00:00:00 2001 From: TheGuyDangerous Date: Mon, 7 Oct 2024 22:24:53 +0530 Subject: [PATCH] Fix light mode --- .../settings/settings_screen_state.dart | 284 ++++++++++-------- lib/widgets/library/history_list.dart | 50 +-- lib/widgets/settings/api_key_input.dart | 4 +- lib/widgets/settings/settings_switch.dart | 22 +- lib/widgets/thread/follow_up_input.dart | 2 +- lib/widgets/thread/sources_section.dart | 2 +- lib/widgets/thread/summary_card.dart | 4 +- 7 files changed, 217 insertions(+), 151 deletions(-) diff --git a/lib/screens/settings/settings_screen_state.dart b/lib/screens/settings/settings_screen_state.dart index f33858f..57ef087 100644 --- a/lib/screens/settings/settings_screen_state.dart +++ b/lib/screens/settings/settings_screen_state.dart @@ -133,145 +133,185 @@ class SettingsScreenState extends State { @override Widget build(BuildContext context) { - final themeProvider = Provider.of(context); - - return Scaffold( - appBar: AppBar( - title: Text('Settings', - style: - TextStyle(fontFamily: 'Raleway', fontWeight: FontWeight.bold)), - ), - body: SingleChildScrollView( - padding: EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('API Keys', style: Theme.of(context).textTheme.titleLarge), - SizedBox(height: 16), - ApiKeyInput( - label: 'Brave Search API Key', - controller: _braveApiController, - icon: Iconsax.search_normal, - ), - ApiKeyInput( - label: 'Groq API Key', - controller: _groqApiController, - icon: Iconsax.code, - ), - SizedBox(height: 24), - Text('Privacy', style: Theme.of(context).textTheme.titleLarge), - SizedBox(height: 16), - SettingsSwitch( - title: 'Incognito Mode', - subtitle: 'Disable search history', - value: _isIncognitoMode, - onChanged: (value) { - setState(() { - _isIncognitoMode = value; - }); - }, - ), - SizedBox(height: 24), - Text('Speech Recognition', - style: Theme.of(context).textTheme.titleLarge), - SizedBox(height: 16), - SettingsSwitch( - title: 'Use OpenAI Whisper Model', - subtitle: 'For improved speech recognition', - value: _useWhisperModel, - onChanged: (value) { - setState(() { - _useWhisperModel = value; - }); - }, - trailing: IconButton( - icon: Icon(Iconsax.info_circle, color: Colors.white70), - onPressed: _showWhisperInfoDialog, - ), - ), - SizedBox(height: 24), - SettingsSwitch( - title: 'Dark Mode', - subtitle: 'Toggle dark/light theme', - value: themeProvider.isDarkMode, - onChanged: (value) { - themeProvider.toggleTheme(); - }, - ), - SizedBox(height: 24), - ElevatedButton( - onPressed: _isValidating ? null : _validateApiKeys, - child: Container( - width: double.infinity, - child: Center( + return Consumer( + builder: (context, themeProvider, child) { + return Scaffold( + appBar: AppBar( + title: Text('Settings', + style: TextStyle( + fontFamily: 'Raleway', fontWeight: FontWeight.bold)), + ), + body: SingleChildScrollView( + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('API Keys', + style: TextStyle( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white + : Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold)), + SizedBox(height: 16), + ApiKeyInput( + label: 'Brave Search API Key', + controller: _braveApiController, + icon: Iconsax.search_normal, + ), + ApiKeyInput( + label: 'Groq API Key', + controller: _groqApiController, + icon: Iconsax.code, + ), + SizedBox(height: 24), + Text('Privacy', + style: TextStyle( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white70 + : Colors.grey[600], + fontSize: 18, + fontWeight: FontWeight.bold)), + SizedBox(height: 16), + SettingsSwitch( + isDarkMode: Theme.of(context).brightness == Brightness.dark, + title: 'Incognito Mode', + subtitle: 'Disable search history', + value: _isIncognitoMode, + onChanged: (value) { + setState(() { + _isIncognitoMode = value; + }); + }, + ), + SizedBox(height: 24), + Text('Speech Recognition', + style: TextStyle( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white70 + : Colors.grey[600], + fontSize: 18, + fontWeight: FontWeight.bold)), + SizedBox(height: 16), + SettingsSwitch( + title: 'Use OpenAI Whisper Model', + subtitle: 'For improved speech recognition', + value: _useWhisperModel, + onChanged: (value) { + setState(() { + _useWhisperModel = value; + }); + }, + trailing: IconButton( + icon: Icon(Iconsax.info_circle, + color: Theme.of(context).brightness == Brightness.dark + ? Colors.grey[600] + : Colors.black), + onPressed: _showWhisperInfoDialog, + ), + isDarkMode: Theme.of(context).brightness == Brightness.dark, + ), + SizedBox(height: 24), + SettingsSwitch( + isDarkMode: Theme.of(context).brightness == Brightness.dark, + title: 'Dark Mode', + subtitle: 'Toggle dark/light theme', + value: themeProvider.isDarkMode, + onChanged: (value) { + themeProvider.toggleTheme(); + }, + ), + SizedBox(height: 24), + ElevatedButton( + onPressed: _isValidating ? null : _validateApiKeys, child: _isValidating ? SizedBox( width: 24, height: 24, child: CircularProgressIndicator( - color: Colors.white, + color: Colors.grey[600], strokeWidth: 2, ), ) : Text('Validate and Save Settings'), + style: ElevatedButton.styleFrom( + backgroundColor: themeProvider.isDarkMode + ? Colors.grey[800] + : Colors.grey[800], + foregroundColor: Colors.white, + padding: EdgeInsets.symmetric(horizontal: 32, vertical: 16), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + minimumSize: + Size(double.infinity, 50), // Ensure consistent height + ), ), - ), - style: ElevatedButton.styleFrom( - backgroundColor: Colors.grey[800], - foregroundColor: Colors.white, - padding: EdgeInsets.symmetric(horizontal: 32, vertical: 16), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + SizedBox(height: 32), + Text('About', + style: TextStyle( + color: themeProvider.isDarkMode + ? Colors.white + : Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold)), + SizedBox(height: 16), + ListTile( + leading: Icon(Iconsax.info_circle, + color: themeProvider.isDarkMode + ? Colors.white70 + : Colors.grey[600]), + title: Text('Version'), + subtitle: Text(AppConstants.appVersion), ), - minimumSize: - Size(double.infinity, 50), // Ensure consistent height - ), - ), - SizedBox(height: 32), - Text('About', style: Theme.of(context).textTheme.titleLarge), - SizedBox(height: 16), - ListTile( - leading: Icon(Iconsax.info_circle, color: Colors.white70), - title: Text('Version'), - subtitle: Text(AppConstants.appVersion), - ), - ListTile( - leading: Icon(Iconsax.document, color: Colors.white70), - title: Text('License'), - subtitle: Text('Custom License'), - onTap: () { - Navigator.push( - context, - MaterialPageRoute(builder: (context) => LicenseScreen()), - ); - }, - ), - ListTile( - leading: Icon(Iconsax.code, color: Colors.white70), - title: Text('Source Code'), - subtitle: Text('GitHub'), - onTap: () => _launchURL(AppConstants.githubUrl), - ), - SizedBox(height: 32), - Center( - child: Text( - 'Created with ❣️ by Sannidhya Dubey', - style: TextStyle( - fontFamily: 'Raleway', - color: Colors.white70, - fontSize: 14, + ListTile( + leading: Icon(Iconsax.document, + color: themeProvider.isDarkMode + ? Colors.white70 + : Colors.grey[600]), + title: Text('License'), + subtitle: Text('Custom License'), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => LicenseScreen()), + ); + }, + ), + ListTile( + leading: Icon(Iconsax.code, + color: themeProvider.isDarkMode + ? Colors.white70 + : Colors.grey[600]), + title: Text('Source Code'), + subtitle: Text('GitHub'), + onTap: () => _launchURL(AppConstants.githubUrl), + ), + SizedBox(height: 32), + Center( + child: Text( + 'Created with ❣️ by Sannidhya Dubey', + style: TextStyle( + fontFamily: 'Raleway', + color: themeProvider.isDarkMode + ? Colors.white70 + : Colors.grey[600], + fontSize: 14, + ), + ), ), - ), + ], ), - ], - ), - ), + ), + ); + }, ); } Future _launchURL(String url) async { - if (await canLaunch(url)) { - await launch(url); + final uri = Uri.parse(url); + if (await canLaunchUrl(uri)) { + await launchUrl(uri); } else { Fluttertoast.showToast(msg: "Could not launch $url"); } diff --git a/lib/widgets/library/history_list.dart b/lib/widgets/library/history_list.dart index 8d43a9c..f861ca9 100644 --- a/lib/widgets/library/history_list.dart +++ b/lib/widgets/library/history_list.dart @@ -24,7 +24,13 @@ class HistoryList extends StatelessWidget { itemCount: searchHistory.length + 1, separatorBuilder: (context, index) { if (index == 0) return SizedBox.shrink(); - return Divider(color: Colors.grey[800], height: 1, thickness: 0.5); + return Divider( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.grey[800] + : Colors.grey[200], + height: 1, + thickness: 0.5, + ); }, itemBuilder: (context, index) { if (index == 0) { @@ -97,7 +103,9 @@ class HistoryList extends StatelessWidget { onItemTap(item['query']); }, child: Card( - color: Colors.black, + color: Theme.of(context).brightness == Brightness.dark + ? Colors.grey[900] + : Colors.grey[100], // Make the container transparent margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), @@ -106,33 +114,29 @@ class HistoryList extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - item['query'], - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 16, - ), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ), - Text( - _formatTimestamp(item['timestamp']), - style: TextStyle(color: Colors.white60, fontSize: 12), - ), - ], + Text( + item['query'], + style: TextStyle( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white + : Colors.black, + fontWeight: FontWeight.bold, + fontSize: 16, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, ), SizedBox(height: 8), Text( item['summary'] != null ? _truncateSummary(item['summary']) : 'No summary available', - style: TextStyle(color: Colors.white70, fontSize: 14), + style: TextStyle( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white70 + : Colors.black87, + fontSize: 14, + ), maxLines: 2, overflow: TextOverflow.ellipsis, ), diff --git a/lib/widgets/settings/api_key_input.dart b/lib/widgets/settings/api_key_input.dart index c23d44b..02e6ebf 100644 --- a/lib/widgets/settings/api_key_input.dart +++ b/lib/widgets/settings/api_key_input.dart @@ -17,7 +17,9 @@ class ApiKeyInput extends StatelessWidget { return Container( margin: EdgeInsets.symmetric(vertical: 8), decoration: BoxDecoration( - color: Colors.grey[900], + color: Theme.of(context).brightness == Brightness.dark + ? Colors.grey[900] + : Colors.grey[800], borderRadius: BorderRadius.circular(12), ), child: ListTile( diff --git a/lib/widgets/settings/settings_switch.dart b/lib/widgets/settings/settings_switch.dart index dcf2d29..e9f3ee8 100644 --- a/lib/widgets/settings/settings_switch.dart +++ b/lib/widgets/settings/settings_switch.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import '../../theme_provider.dart'; class SettingsSwitch extends StatelessWidget { final String title; @@ -6,6 +7,7 @@ class SettingsSwitch extends StatelessWidget { final bool value; final ValueChanged onChanged; final Widget? trailing; + final bool isDarkMode; const SettingsSwitch({ Key? key, @@ -14,16 +16,32 @@ class SettingsSwitch extends StatelessWidget { required this.value, required this.onChanged, this.trailing, + required this.isDarkMode, }) : super(key: key); @override Widget build(BuildContext context) { return SwitchListTile( - title: Text(title, style: TextStyle(color: Colors.white)), - subtitle: Text(subtitle, style: TextStyle(color: Colors.white70)), + title: Text( + title, + style: TextStyle( + color: isDarkMode ? Colors.white : Colors.black, + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + subtitle: Text( + subtitle, + style: TextStyle( + color: isDarkMode ? Colors.white70 : Colors.black54, + fontSize: 14, + ), + ), value: value, onChanged: onChanged, activeColor: Colors.blue, + inactiveThumbColor: isDarkMode ? Colors.grey[600] : Colors.grey[400], + inactiveTrackColor: isDarkMode ? Colors.grey[800] : Colors.grey[300], secondary: trailing, ); } diff --git a/lib/widgets/thread/follow_up_input.dart b/lib/widgets/thread/follow_up_input.dart index f7f71c4..3f89ae1 100644 --- a/lib/widgets/thread/follow_up_input.dart +++ b/lib/widgets/thread/follow_up_input.dart @@ -20,7 +20,7 @@ class FollowUpInput extends StatelessWidget { decoration: BoxDecoration( color: Theme.of(context).brightness == Brightness.dark ? Colors.grey[900] - : Colors.grey[100], + : Colors.grey[300], // Slightly darker grey for light mode borderRadius: BorderRadius.circular(30), ), child: Row( diff --git a/lib/widgets/thread/sources_section.dart b/lib/widgets/thread/sources_section.dart index ae8ad83..67d79c3 100644 --- a/lib/widgets/thread/sources_section.dart +++ b/lib/widgets/thread/sources_section.dart @@ -30,7 +30,7 @@ class SourcesSection extends StatelessWidget { decoration: BoxDecoration( color: themeProvider.isDarkMode ? Colors.grey[800] - : Colors.grey[200], + : Colors.grey[300], // Slightly darker grey for light mode borderRadius: BorderRadius.circular(12), ), child: Row( diff --git a/lib/widgets/thread/summary_card.dart b/lib/widgets/thread/summary_card.dart index ad9fde9..e2caf0f 100644 --- a/lib/widgets/thread/summary_card.dart +++ b/lib/widgets/thread/summary_card.dart @@ -20,7 +20,9 @@ class SummaryCard extends StatelessWidget { final themeProvider = Provider.of(context); return Card( - color: themeProvider.isDarkMode ? Colors.grey[900] : Colors.grey[100], + color: themeProvider.isDarkMode + ? Colors.grey[900] + : Colors.grey[300], // Slightly darker grey for light mode margin: EdgeInsets.all(16), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), child: Padding(