aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorIván Ávalos <avalos@disroot.org>2023-05-27 13:14:45 -0600
committerIván Ávalos <avalos@disroot.org>2023-05-27 13:25:24 -0600
commita88ccf31b59541faea8c38c638737c1359cfff47 (patch)
tree30acf22e4df0bfa41b34e40b223521fbef5a4730 /lib
parentd0d54a9d6e7ac947ae86962b6bbc7eeb9ada5011 (diff)
downloadlinkchat-a88ccf31b59541faea8c38c638737c1359cfff47.tar.gz
linkchat-a88ccf31b59541faea8c38c638737c1359cfff47.tar.bz2
linkchat-a88ccf31b59541faea8c38c638737c1359cfff47.zip
Se implementan colores dinámicos (Android 13)
Diffstat (limited to 'lib')
-rw-r--r--lib/main.dart42
-rw-r--r--lib/providers/theme_provider.dart7
-rw-r--r--lib/screens/chat_screen.dart8
-rw-r--r--lib/screens/dashboard_screen.dart39
-rw-r--r--lib/settings/preferences.dart15
-rw-r--r--lib/settings/themes.dart28
-rw-r--r--lib/widgets/chat_bubble.dart148
7 files changed, 176 insertions, 111 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,
);
}
}