Improve light-mode support

This commit is contained in:
Nutcake 2023-05-25 19:30:15 +02:00
parent 5561f18a2c
commit 8668e66813
10 changed files with 39 additions and 22 deletions

View file

@ -1,4 +1,5 @@
import 'package:contacts_plus_plus/config.dart'; import 'package:contacts_plus_plus/config.dart';
import 'package:flutter/material.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:html/parser.dart' as htmlparser; import 'package:html/parser.dart' as htmlparser;
@ -90,4 +91,14 @@ extension Format on Duration {
extension DateTimeX on DateTime { extension DateTimeX on DateTime {
static DateTime epoch = DateTime.fromMillisecondsSinceEpoch(0); static DateTime epoch = DateTime.fromMillisecondsSinceEpoch(0);
static DateTime one = DateTime(1); static DateTime one = DateTime(1);
}
extension ColorX on Color {
Color invert() {
final r = 255 - red;
final g = 255 - green;
final b = 255 - blue;
return Color.fromARGB((opacity * 255).round(), r, g, b);
}
} }

View file

@ -1,8 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_phoenix/flutter_phoenix.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:contacts_plus_plus/models/authentication_data.dart'; import 'package:contacts_plus_plus/models/authentication_data.dart';

View file

@ -119,10 +119,16 @@ class _ContactsPlusPlusState extends State<ContactsPlusPlus> {
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
title: 'Contacts++', title: 'Contacts++',
theme: ThemeData( theme: ThemeData(
useMaterial3: true,
textTheme: _typography.black,
colorScheme: lightDynamic ?? ColorScheme.fromSeed(seedColor: Colors.purple, brightness: Brightness.light),
),
darkTheme: ThemeData(
useMaterial3: true, useMaterial3: true,
textTheme: _typography.white, textTheme: _typography.white,
colorScheme: darkDynamic ?? ColorScheme.fromSeed(seedColor: Colors.purple, brightness: Brightness.dark), colorScheme: darkDynamic ?? ColorScheme.fromSeed(seedColor: Colors.purple, brightness: Brightness.dark),
), ),
themeMode: ThemeMode.dark,
home: Builder( // Builder is necessary here since we need a context which has access to the ClientHolder home: Builder( // Builder is necessary here since we need a context which has access to the ClientHolder
builder: (context) { builder: (context) {
showUpdateDialogOnFirstBuild(context); showUpdateDialogOnFirstBuild(context);

View file

@ -93,14 +93,14 @@ enum OnlineStatus {
online; online;
static final List<Color> _colors = [ static final List<Color> _colors = [
Colors.white54, Colors.transparent,
Colors.white54, Colors.transparent,
Colors.yellow, Colors.yellow,
Colors.red, Colors.red,
Colors.green, Colors.green,
]; ];
Color get color => _colors[index]; Color color(BuildContext context) => this == OnlineStatus.offline || this == OnlineStatus.invisible ? Theme.of(context).colorScheme.onSurface : _colors[index];
factory OnlineStatus.fromString(String? text) { factory OnlineStatus.fromString(String? text) {
return OnlineStatus.values.firstWhere((element) => element.name.toLowerCase() == text?.toLowerCase(), return OnlineStatus.values.firstWhere((element) => element.name.toLowerCase() == text?.toLowerCase(),

View file

@ -15,11 +15,11 @@ class FriendOnlineStatusIndicator extends StatelessWidget {
child: Image.asset( child: Image.asset(
"assets/images/logo-white.png", "assets/images/logo-white.png",
alignment: Alignment.center, alignment: Alignment.center,
color: userStatus.onlineStatus.color, color: userStatus.onlineStatus.color(context),
), ),
) : Icon( ) : Icon(
userStatus.onlineStatus == OnlineStatus.offline ? Icons.circle_outlined : Icons.circle, userStatus.onlineStatus == OnlineStatus.offline ? Icons.circle_outlined : Icons.circle,
color: userStatus.onlineStatus.color, color: userStatus.onlineStatus.color(context),
size: 10, size: 10,
); );
} }

View file

@ -77,7 +77,7 @@ class _FriendsListState extends State<FriendsList> {
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.only(right: 8.0), padding: const EdgeInsets.only(right: 8.0),
child: Icon(Icons.circle, size: 16, color: userStatus.onlineStatus.color,), child: Icon(Icons.circle, size: 16, color: userStatus.onlineStatus.color(context),),
), ),
Text(toBeginningOfSentenceCase(userStatus.onlineStatus.name) ?? "Unknown"), Text(toBeginningOfSentenceCase(userStatus.onlineStatus.name) ?? "Unknown"),
], ],
@ -112,7 +112,7 @@ class _FriendsListState extends State<FriendsList> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Icon(Icons.circle, size: 16, color: item.color,), Icon(Icons.circle, size: 16, color: item.color(context),),
const SizedBox(width: 8,), const SizedBox(width: 8,),
Text(toBeginningOfSentenceCase(item.name)!), Text(toBeginningOfSentenceCase(item.name)!),
], ],

View file

@ -13,14 +13,14 @@ class GenericAvatar extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return imageUri.isEmpty ? CircleAvatar( return imageUri.isEmpty ? CircleAvatar(
radius: radius, radius: radius,
foregroundColor: foregroundColor, foregroundColor: foregroundColor ?? Theme.of(context).colorScheme.onPrimaryContainer,
backgroundColor: Colors.transparent, backgroundColor: Theme.of(context).colorScheme.primaryContainer,
child: Icon(placeholderIcon, color: foregroundColor,), child: Icon(placeholderIcon, color: foregroundColor,),
) : CachedNetworkImage( ) : CachedNetworkImage(
imageBuilder: (context, imageProvider) { imageBuilder: (context, imageProvider) {
return CircleAvatar( return CircleAvatar(
foregroundImage: imageProvider, foregroundImage: imageProvider,
foregroundColor: foregroundColor, foregroundColor: Colors.transparent,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
radius: radius, radius: radius,
); );
@ -28,20 +28,20 @@ class GenericAvatar extends StatelessWidget {
imageUrl: imageUri, imageUrl: imageUri,
placeholder: (context, url) { placeholder: (context, url) {
return CircleAvatar( return CircleAvatar(
backgroundColor: Colors.white54, backgroundColor: Theme.of(context).colorScheme.primaryContainer,
foregroundColor: foregroundColor, foregroundColor: foregroundColor ?? Theme.of(context).colorScheme.onPrimaryContainer,
radius: radius, radius: radius,
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: CircularProgressIndicator(color: foregroundColor, strokeWidth: 2), child: CircularProgressIndicator(color: foregroundColor ?? Theme.of(context).colorScheme.onPrimaryContainer, strokeWidth: 2),
), ),
); );
}, },
errorWidget: (context, error, what) => CircleAvatar( errorWidget: (context, error, what) => CircleAvatar(
radius: radius, radius: radius,
foregroundColor: foregroundColor, foregroundColor: foregroundColor ?? Theme.of(context).colorScheme.onPrimaryContainer,
backgroundColor: Colors.transparent, backgroundColor: Theme.of(context).colorScheme.primaryContainer,
child: Icon(placeholderIcon, color: foregroundColor,), child: Icon(placeholderIcon, color: foregroundColor ?? Theme.of(context).colorScheme.onPrimaryContainer,),
), ),
); );
} }

View file

@ -205,7 +205,7 @@ class _MessageInputBarState extends State<MessageInputBar> {
}, },
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
border: const Border(top: BorderSide(width: 1, color: Colors.black38)), border: const Border(top: BorderSide(width: 1, color: Colors.black)),
color: Theme color: Theme
.of(context) .of(context)
.colorScheme .colorScheme
@ -389,13 +389,14 @@ class _MessageInputBarState extends State<MessageInputBar> {
} }
_currentText = text; _currentText = text;
}, },
style: Theme.of(context).textTheme.bodyLarge,
decoration: InputDecoration( decoration: InputDecoration(
isDense: true, isDense: true,
hintText: _isRecording ? "" : "Message ${widget.recipient hintText: _isRecording ? "" : "Message ${widget.recipient
.username}...", .username}...",
hintMaxLines: 1, hintMaxLines: 1,
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
fillColor: Colors.black38, fillColor: Colors.black26,
filled: true, filled: true,
border: OutlineInputBorder( border: OutlineInputBorder(
borderSide: BorderSide.none, borderSide: BorderSide.none,

View file

@ -1,3 +1,4 @@
import 'package:contacts_plus_plus/auxiliary.dart';
import 'package:contacts_plus_plus/clients/audio_cache_client.dart'; import 'package:contacts_plus_plus/clients/audio_cache_client.dart';
import 'package:contacts_plus_plus/clients/messaging_client.dart'; import 'package:contacts_plus_plus/clients/messaging_client.dart';
import 'package:contacts_plus_plus/models/friend.dart'; import 'package:contacts_plus_plus/models/friend.dart';
@ -89,7 +90,7 @@ class _MessagesListState extends State<MessagesList> with SingleTickerProviderSt
constraints: const BoxConstraints(maxHeight: 64), constraints: const BoxConstraints(maxHeight: 64),
decoration: BoxDecoration( decoration: BoxDecoration(
color: appBarColor, color: appBarColor,
border: const Border(top: BorderSide(width: 1, color: Colors.black26),) border: const Border(bottom: BorderSide(width: 1, color: Colors.black),)
), ),
child: Stack( child: Stack(
children: [ children: [

View file

@ -56,7 +56,7 @@ class _MyProfileDialogState extends State<MyProfileDialog> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text(profile.username, style: tt.titleLarge), Text(profile.username, style: tt.titleLarge),
Text(profile.email, style: tt.labelMedium?.copyWith(color: Colors.white54),) Text(profile.email, style: tt.labelMedium?.copyWith(color: Theme.of(context).colorScheme.onSurface.withAlpha(150)),)
], ],
), ),
GenericAvatar(imageUri: Aux.neosDbToHttp(profile.userProfile.iconUrl), radius: 24,) GenericAvatar(imageUri: Aux.neosDbToHttp(profile.userProfile.iconUrl), radius: 24,)