diff options
-rw-r--r-- | lib/main.dart | 42 | ||||
-rw-r--r-- | lib/providers/theme_provider.dart | 7 | ||||
-rw-r--r-- | lib/screens/chat_screen.dart | 8 | ||||
-rw-r--r-- | lib/screens/dashboard_screen.dart | 39 | ||||
-rw-r--r-- | lib/settings/preferences.dart | 15 | ||||
-rw-r--r-- | lib/settings/themes.dart | 28 | ||||
-rw-r--r-- | lib/widgets/chat_bubble.dart | 148 | ||||
-rw-r--r-- | linux/flutter/generated_plugin_registrant.cc | 4 | ||||
-rw-r--r-- | linux/flutter/generated_plugins.cmake | 1 | ||||
-rw-r--r-- | pubspec.lock | 10 | ||||
-rw-r--r-- | pubspec.yaml | 1 |
11 files changed, 191 insertions, 112 deletions
diff --git a/lib/main.dart b/lib/main.dart index 97a8fb4..b067b07 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,4 @@ +import 'package:dynamic_color/dynamic_color.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:linkchat/screens/dashboard_screen.dart'; @@ -50,20 +51,35 @@ class LinkChat extends StatelessWidget { @override Widget build(BuildContext context) { final ThemeProvider provider = context.watch<ThemeProvider>(); - final ThemeData? theme = provider.theme; - provider.syncFromPrefs(); + final ThemeEnum themeEnum = provider.theme; + return StreamBuilder( stream: _auth.userChanges, - builder: (context, snapshot) { - return MaterialApp( - theme: theme ?? ThemeSettings.lightTheme, - darkTheme: theme ?? ThemeSettings.darkTheme, - themeMode: ThemeMode.system, - routes: getApplicationRoutes(), - home: (snapshot.hasData && !snapshot.data!.isAnonymous) - ? const DashboardScreen() - : const LoginScreen(), - ); - }); + builder: (context, snapshot) => + DynamicColorBuilder(builder: (lightDynamic, darkDynamic) { + provider.syncFromPrefs(); + ThemeData lightTheme = ThemeSettings.lightTheme(lightDynamic); + ThemeData darkTheme = ThemeSettings.darkTheme(darkDynamic); + ThemeData? theme; + switch (themeEnum) { + case ThemeEnum.light: + theme = lightTheme; + case ThemeEnum.dark: + theme = darkTheme; + case ThemeEnum.auto: + theme = null; + } + return MaterialApp( + theme: theme ?? lightTheme, + darkTheme: theme ?? darkTheme, + //theme: theme ?? ThemeSettings.lightTheme(lightDynamic), + //darkTheme: theme ?? ThemeSettings.darkTheme(darkDynamic), + themeMode: ThemeMode.system, + routes: getApplicationRoutes(), + home: (snapshot.hasData && !snapshot.data!.isAnonymous) + ? const DashboardScreen() + : const LoginScreen(), + ); + })); } } diff --git a/lib/providers/theme_provider.dart b/lib/providers/theme_provider.dart index 3a65731..240c9a7 100644 --- a/lib/providers/theme_provider.dart +++ b/lib/providers/theme_provider.dart @@ -1,10 +1,11 @@ import 'package:flutter/material.dart'; import '../settings/preferences.dart'; +import '../settings/themes.dart'; class ThemeProvider with ChangeNotifier { bool synced = false; - ThemeData? _theme; + ThemeEnum _theme = ThemeEnum.auto; void syncFromPrefs() { if (synced) return; @@ -15,9 +16,9 @@ class ThemeProvider with ChangeNotifier { }); } - ThemeData? get theme => _theme; + ThemeEnum get theme => _theme; - set theme(ThemeData? theme) { + set theme(ThemeEnum theme) { Preferences.setTheme(theme); _theme = theme; notifyListeners(); diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart index 64f8621..b815a6a 100644 --- a/lib/screens/chat_screen.dart +++ b/lib/screens/chat_screen.dart @@ -1,4 +1,5 @@ import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:linkchat/firebase/auth.dart'; import 'package:linkchat/firebase/database.dart'; @@ -43,11 +44,6 @@ class _ChatScreenState extends State<ChatScreen> { leadingWidth: 30, title: Row( children: [ - // ClipRRect( - // borderRadius: BorderRadius.circular(30), - // child: CircleAvatar( - // backgroundImage: NetworkImage(user!.photoUrl), - // )), CachedAvatar(user?.photoUrl), Padding( padding: const EdgeInsets.only(left: 10), @@ -119,7 +115,7 @@ class _ChatScreenState extends State<ChatScreen> { }), ); } else if (snapshot.hasError) { - print('Error: ${snapshot.error}'); + if (kDebugMode) print('Error: ${snapshot.error}'); return const Center(child: Text('Hubo un error')); } return const Center(child: CircularProgressIndicator()); diff --git a/lib/screens/dashboard_screen.dart b/lib/screens/dashboard_screen.dart index 4905b84..be3aca0 100644 --- a/lib/screens/dashboard_screen.dart +++ b/lib/screens/dashboard_screen.dart @@ -51,29 +51,40 @@ class _DashboardScreenState extends State<DashboardScreen> { children: [ UserAccountsDrawerHeader( currentAccountPicture: CachedAvatar(_auth.currentUser?.photoURL), - accountName: Text(_auth.currentUser?.displayName ?? "Lincite"), + accountName: Text( + _auth.currentUser?.displayName ?? "Lincite", + style: TextStyle( + color: Theme.of(context).colorScheme.onPrimary, + ), + ), accountEmail: _auth.currentUser?.email != null - ? Text(_auth.currentUser!.email!) + ? Text( + _auth.currentUser!.email!, + style: TextStyle( + color: Theme.of(context).colorScheme.onPrimary, + ), + ) : null, ), ListTile( title: const Text('Tema'), - trailing: SegmentedButton<ThemeData?>( - segments: [ - const ButtonSegment<ThemeData?>( - value: null, + trailing: SegmentedButton<ThemeEnum>( + segments: const [ + ButtonSegment<ThemeEnum>( + value: ThemeEnum.auto, icon: Icon(Icons.brightness_auto), ), - ButtonSegment<ThemeData?>( - value: ThemeSettings.lightTheme, - icon: const Icon(Icons.light_mode), + ButtonSegment<ThemeEnum>( + value: ThemeEnum.light, + icon: Icon(Icons.light_mode), + ), + ButtonSegment<ThemeEnum>( + value: ThemeEnum.dark, + icon: Icon(Icons.dark_mode), ), - ButtonSegment<ThemeData?>( - value: ThemeSettings.darkTheme, - icon: const Icon(Icons.dark_mode)), ], - selected: <ThemeData?>{themeProvider.theme}, - onSelectionChanged: ((Set<ThemeData?> newSelection) { + selected: <ThemeEnum>{themeProvider.theme}, + onSelectionChanged: ((Set<ThemeEnum> newSelection) { themeProvider.theme = newSelection.first; }), ), diff --git a/lib/settings/preferences.dart b/lib/settings/preferences.dart index 3c0ef5d..9cfbf6a 100644 --- a/lib/settings/preferences.dart +++ b/lib/settings/preferences.dart @@ -1,4 +1,3 @@ -import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../settings/themes.dart'; @@ -11,21 +10,21 @@ class Preferences { return _prefs!; } - static Future<ThemeData?> getTheme() async { + static Future<ThemeEnum> getTheme() async { switch ((await prefs).getString('theme')) { case 'light': - return ThemeSettings.lightTheme; + return ThemeEnum.light; case 'dark': - return ThemeSettings.darkTheme; + return ThemeEnum.dark; } - return null; + return ThemeEnum.auto; } - static void setTheme(ThemeData? theme) { + static void setTheme(ThemeEnum? theme) { prefs.then((p) { - if (theme == ThemeSettings.lightTheme) { + if (theme == ThemeEnum.light) { p.setString('theme', 'light'); - } else if (theme == ThemeSettings.darkTheme) { + } else if (theme == ThemeEnum.dark) { p.setString('theme', 'dark'); } else { p.remove('theme'); diff --git a/lib/settings/themes.dart b/lib/settings/themes.dart index cc506a9..b9a09d7 100644 --- a/lib/settings/themes.dart +++ b/lib/settings/themes.dart @@ -1,18 +1,20 @@ import 'package:flutter/material.dart'; +enum ThemeEnum { light, dark, auto } + class ThemeSettings { - static ThemeData lightTheme = ThemeData( - useMaterial3: true, - primaryColor: Colors.purple, - fontFamily: 'Manrope', - ); + static ThemeData lightTheme(ColorScheme? lightDynamic) => ThemeData( + useMaterial3: true, + primaryColor: Colors.purple, + fontFamily: 'Manrope', + colorScheme: lightDynamic, + ); - static ThemeData darkTheme = ThemeData( - useMaterial3: true, - brightness: Brightness.dark, - fontFamily: 'Manrope', - colorScheme: const ColorScheme.dark().copyWith( - primary: Colors.purple, - ), - ); + static ThemeData darkTheme(ColorScheme? darkDynamic) => ThemeData( + useMaterial3: true, + brightness: Brightness.dark, + fontFamily: 'Manrope', + primaryColor: Colors.purple, + colorScheme: (darkDynamic ?? const ColorScheme.dark()), + ); } diff --git a/lib/widgets/chat_bubble.dart b/lib/widgets/chat_bubble.dart index e7622e4..091a039 100644 --- a/lib/widgets/chat_bubble.dart +++ b/lib/widgets/chat_bubble.dart @@ -56,38 +56,21 @@ class BubbleLeft extends StatelessWidget { @override
Widget build(BuildContext context) {
+ Color background = Theme.of(context).colorScheme.tertiaryContainer;
+ Color foreground = Theme.of(context).colorScheme.onTertiaryContainer;
return Padding(
- padding: const EdgeInsets.only(right: 77),
+ padding: const EdgeInsets.only(top: 10, right: 77),
child: ClipPath(
clipper: UpperNipMessageClipper(MessageType.receive),
child: Container(
- padding: const EdgeInsets.all(20),
- decoration: const BoxDecoration(
- color: Color(0xFFE1E1E2),
- ),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- LinkPreview(message),
- Link(
- uri: Uri.parse(message.messageText),
- builder: (context, followLink) => TextButton(
- onPressed: followLink,
- child: Text(
- message.messageText,
- style: const TextStyle(color: Colors.blue),
- ),
- ),
- ),
- IconButton(
- icon: favorited
- ? const Icon(Icons.favorite, color: Colors.black)
- : const Icon(Icons.favorite_outline, color: Colors.black),
- onPressed: () => onFavorite(message.id!, !favorited),
- ),
- ],
- ),
- ),
+ padding: const EdgeInsets.all(20),
+ decoration: BoxDecoration(color: background),
+ child: BubbleContent(
+ message,
+ favorited: favorited,
+ foregroundColor: foreground,
+ onFavorited: () => onFavorite(message.id!, !favorited),
+ )),
),
);
}
@@ -107,43 +90,100 @@ class BubbleRight extends StatelessWidget { @override
Widget build(BuildContext context) {
+ Color background = Theme.of(context).colorScheme.primaryContainer;
+ Color foreground = Theme.of(context).colorScheme.onPrimaryContainer;
return Container(
alignment: Alignment.centerRight,
child: Padding(
- padding: const EdgeInsets.only(top: 20, left: 77),
+ padding: const EdgeInsets.only(top: 10, left: 77),
child: ClipPath(
clipper: LowerNipMessageClipper(MessageType.send),
child: Container(
- padding:
- const EdgeInsets.only(left: 20, top: 10, bottom: 20, right: 20),
- decoration: const BoxDecoration(
- color: Color(0xFF113753),
- ),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- LinkPreview(message),
- Link(
- uri: Uri.parse(message.messageText),
- builder: (context, followLink) => TextButton(
- onPressed: followLink,
- child: Text(
- message.messageText,
- style: const TextStyle(color: Colors.blue),
+ padding: const EdgeInsets.only(
+ left: 20, top: 10, bottom: 20, right: 20),
+ decoration: BoxDecoration(color: background),
+ child: BubbleContent(
+ message,
+ favorited: favorited,
+ foregroundColor: foreground,
+ onFavorited: () => onFavorite(message.id!, !favorited),
+ )),
+ ),
+ ),
+ );
+ }
+}
+
+class BubbleContent extends StatelessWidget {
+ final bool favorited;
+ final Message message;
+ final Color foregroundColor;
+ final Function() onFavorited;
+
+ const BubbleContent(
+ this.message, {
+ super.key,
+ required this.favorited,
+ required this.foregroundColor,
+ required this.onFavorited,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ LinkPreview(message),
+ Row(
+ children: [
+ Expanded(
+ child: Link(
+ uri: Uri.parse(message.messageText),
+ builder: (context, followLink) => TextButton(
+ onPressed: followLink,
+ child: Text(
+ message.messageText,
+ textAlign: TextAlign.start,
+ style: TextStyle(
+ color: foregroundColor,
+ decoration: TextDecoration.underline,
+ decorationColor: foregroundColor,
),
),
),
- IconButton(
- icon: favorited
- ? const Icon(Icons.favorite, color: Colors.white)
- : const Icon(Icons.favorite_outline, color: Colors.white),
- onPressed: () => onFavorite(message.id!, !favorited),
- ),
- ],
+ ),
+ ),
+ Favorited(
+ favorited,
+ color: foregroundColor,
+ onPressed: () => onFavorited(),
),
- ),
+ ],
),
- ),
+ ],
+ );
+ }
+}
+
+class Favorited extends StatelessWidget {
+ final bool favorited;
+ final Color color;
+ final Function() onPressed;
+
+ const Favorited(
+ this.favorited, {
+ super.key,
+ required this.color,
+ required this.onPressed,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return IconButton(
+ icon: favorited
+ ? Icon(Icons.favorite, color: color)
+ : Icon(Icons.favorite_outline, color: color),
+ onPressed: onPressed,
);
}
}
diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index f6f23bf..fe56f8d 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,9 +6,13 @@ #include "generated_plugin_registrant.h" +#include <dynamic_color/dynamic_color_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h> void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) dynamic_color_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin"); + dynamic_color_plugin_register_with_registrar(dynamic_color_registrar); g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index f16b4c3..1836621 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + dynamic_color url_launcher_linux ) diff --git a/pubspec.lock b/pubspec.lock index 4088b0b..69c79fb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -161,6 +161,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + dynamic_color: + dependency: "direct main" + description: + name: dynamic_color + sha256: "74dff1435a695887ca64899b8990004f8d1232b0e84bfc4faa1fdda7c6f57cc1" + url: "https://pub.dev" + source: hosted + version: "1.6.5" email_validator: dependency: "direct main" description: @@ -871,4 +879,4 @@ packages: version: "1.0.0" sdks: dart: ">=3.0.1 <4.0.0" - flutter: ">=3.3.0" + flutter: ">=3.4.0-17.0.pre" diff --git a/pubspec.yaml b/pubspec.yaml index 8dbe28a..d6b9076 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,6 +10,7 @@ dependencies: flutter: sdk: flutter + dynamic_color: ^1.6.5 provider: ^6.0.5 shared_preferences: ^2.1.1 lottie: ^2.3.2 |