Improve light-mode support
This commit is contained in:
parent
5561f18a2c
commit
8668e66813
10 changed files with 39 additions and 22 deletions
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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';
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)!),
|
||||||
],
|
],
|
||||||
|
|
|
@ -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,),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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: [
|
||||||
|
|
|
@ -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,)
|
||||||
|
|
Loading…
Reference in a new issue