theme: Add colors, Gradient and its implementation

Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
Sahil Kumar
2021-01-06 16:25:00 +05:30
parent bc6c31c25e
commit 0d71632ef2
16 changed files with 113 additions and 196 deletions
+3
View File
@@ -271,6 +271,9 @@ class _AdvancedOptionsPageState extends State<AdvancedOptionsPage> {
showDialog( showDialog(
barrierDismissible: false, barrierDismissible: false,
context: context, context: context,
barrierColor: StreamChatTheme.of(context)
.colorTheme
.overlay,
builder: (context) => Center( builder: (context) => Center(
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
+3
View File
@@ -108,6 +108,9 @@ class ChooseUserPage extends StatelessWidget {
showDialog( showDialog(
barrierDismissible: false, barrierDismissible: false,
context: context, context: context,
barrierColor: StreamChatTheme.of(context)
.colorTheme
.overlay,
builder: (context) => Center( builder: (context) => Center(
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
+7 -19
View File
@@ -83,10 +83,7 @@ class _GroupChatDetailsScreenState extends State<GroupChatDetailsScreen> {
'NAME', 'NAME',
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: StreamChatTheme.of(context) color: StreamChatTheme.of(context).colorTheme.grey,
.colorTheme
.black
.withOpacity(0.5),
), ),
), ),
SizedBox(width: 16), SizedBox(width: 16),
@@ -103,11 +100,9 @@ class _GroupChatDetailsScreenState extends State<GroupChatDetailsScreen> {
contentPadding: const EdgeInsets.all(0), contentPadding: const EdgeInsets.all(0),
hintText: 'Choose a group chat name', hintText: 'Choose a group chat name',
hintStyle: TextStyle( hintStyle: TextStyle(
fontSize: 14, fontSize: 14,
color: StreamChatTheme.of(context) color: StreamChatTheme.of(context).colorTheme.grey,
.colorTheme ),
.black
.withOpacity(.5)),
), ),
), ),
), ),
@@ -122,7 +117,7 @@ class _GroupChatDetailsScreenState extends State<GroupChatDetailsScreen> {
icon: StreamSvgIcon.check( icon: StreamSvgIcon.check(
size: 24, size: 24,
color: _isGroupNameEmpty color: _isGroupNameEmpty
? Colors.grey ? StreamChatTheme.of(context).colorTheme.grey
: StreamChatTheme.of(context).colorTheme.accentBlue, : StreamChatTheme.of(context).colorTheme.accentBlue,
), ),
onPressed: _isGroupNameEmpty onPressed: _isGroupNameEmpty
@@ -155,14 +150,7 @@ class _GroupChatDetailsScreenState extends State<GroupChatDetailsScreen> {
Container( Container(
width: double.maxFinite, width: double.maxFinite,
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient: StreamChatTheme.of(context).colorTheme.bgGradient,
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
StreamChatTheme.of(context).colorTheme.whiteSmoke,
StreamChatTheme.of(context).colorTheme.whiteSnow,
],
),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
@@ -172,7 +160,7 @@ class _GroupChatDetailsScreenState extends State<GroupChatDetailsScreen> {
child: Text( child: Text(
'$_totalUsers ${_totalUsers > 1 ? 'Members' : 'Member'}', '$_totalUsers ${_totalUsers > 1 ? 'Members' : 'Member'}',
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w500, color: StreamChatTheme.of(context).colorTheme.grey,
), ),
), ),
), ),
+1
View File
@@ -589,6 +589,7 @@ class _GroupInfoScreenState extends State<GroupInfoScreen> {
showDialog( showDialog(
context: context, context: context,
barrierColor: StreamChatTheme.of(context).colorTheme.overlay,
builder: (context) { builder: (context) {
return StatefulBuilder(builder: (context, modalSetState) { return StatefulBuilder(builder: (context, modalSetState) {
modalSetStateCallback = modalSetState; modalSetStateCallback = modalSetState;
+1 -15
View File
@@ -237,21 +237,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
Container( Container(
width: double.maxFinite, width: double.maxFinite,
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient: StreamChatTheme.of(context).colorTheme.bgGradient,
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
StreamChatTheme.of(context)
.colorTheme
.black
.withOpacity(0.02),
StreamChatTheme.of(context)
.colorTheme
.white
.withOpacity(0.05),
],
stops: [0, 1],
),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
+10 -24
View File
@@ -180,21 +180,8 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
child: Container( child: Container(
width: double.maxFinite, width: double.maxFinite,
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient:
begin: Alignment.centerLeft, StreamChatTheme.of(context).colorTheme.bgGradient,
end: Alignment.centerRight,
colors: [
StreamChatTheme.of(context)
.colorTheme
.black
.withOpacity(0.02),
StreamChatTheme.of(context)
.colorTheme
.white
.withOpacity(0.05),
],
stops: [0, 1],
),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
@@ -206,10 +193,7 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
? 'Matches for \"$_userNameQuery\"' ? 'Matches for \"$_userNameQuery\"'
: 'On the platform', : 'On the platform',
style: TextStyle( style: TextStyle(
color: StreamChatTheme.of(context) color: StreamChatTheme.of(context).colorTheme.grey,
.colorTheme
.black
.withOpacity(0.5),
), ),
), ),
), ),
@@ -271,7 +255,9 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
padding: const EdgeInsets.all(24), padding: const EdgeInsets.all(24),
child: StreamSvgIcon.search( child: StreamSvgIcon.search(
size: 96, size: 96,
color: Colors.grey, color: StreamChatTheme.of(context)
.colorTheme
.grey,
), ),
), ),
Text( Text(
@@ -280,10 +266,10 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
.textTheme .textTheme
.footnote .footnote
.copyWith( .copyWith(
color: StreamChatTheme.of(context) color: StreamChatTheme.of(context)
.colorTheme .colorTheme
.black .grey,
.withOpacity(.5)), ),
), ),
], ],
), ),
+13 -75
View File
@@ -29,27 +29,8 @@ class ImageActionsModal extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GestureDetector( return GestureDetector(
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
onTap: () { onTap: () => Navigator.maybePop(context),
Navigator.pop(context); child: _buildPage(context),
},
child: Stack(
children: [
Positioned.fill(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.black.withOpacity(0.8),
Colors.transparent,
],
stops: [0.0, 0.4],
)),
)),
_buildPage(context),
],
),
); );
} }
@@ -57,53 +38,14 @@ class ImageActionsModal extends StatelessWidget {
return Material( return Material(
color: Colors.transparent, color: Colors.transparent,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
Row( SizedBox(
mainAxisAlignment: MainAxisAlignment.spaceBetween, height: kToolbarHeight,
children: [ child: IconButton(
Padding( icon: StreamSvgIcon.close(),
padding: const EdgeInsets.all(8.0), onPressed: () => Navigator.maybePop(context),
child: Container( ),
width: 40.0,
),
),
Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
userName,
style: StreamChatTheme.of(context)
.textTheme
.headlineBold
.copyWith(
color:
StreamChatTheme.of(context).colorTheme.white),
),
),
Text(
sentAt,
style: StreamChatTheme.of(context)
.channelPreviewTheme
.subtitle
.copyWith(
color: StreamChatTheme.of(context)
.colorTheme
.white
.withOpacity(0.5)),
),
],
),
IconButton(
icon: StreamSvgIcon.close(
size: 24.0,
color: StreamChatTheme.of(context).colorTheme.white,
),
onPressed: () {
Navigator.pop(context);
},
),
],
), ),
Align( Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
@@ -127,10 +69,8 @@ class ImageActionsModal extends StatelessWidget {
'Reply', 'Reply',
StreamSvgIcon.Icon_curve_line_left_up( StreamSvgIcon.Icon_curve_line_left_up(
size: 24.0, size: 24.0,
color: StreamChatTheme.of(context) color:
.colorTheme StreamChatTheme.of(context).colorTheme.grey,
.black
.withOpacity(0.5),
), ),
() {}), () {}),
_buildButton( _buildButton(
@@ -147,10 +87,8 @@ class ImageActionsModal extends StatelessWidget {
'Save ${urls[currentIndex].type == 'video' ? 'Video' : 'Image'}', 'Save ${urls[currentIndex].type == 'video' ? 'Video' : 'Image'}',
StreamSvgIcon.Icon_save( StreamSvgIcon.Icon_save(
size: 24.0, size: 24.0,
color: StreamChatTheme.of(context) color:
.colorTheme StreamChatTheme.of(context).colorTheme.grey,
.black
.withOpacity(0.5),
), () async { ), () async {
var url = urls[currentIndex].imageUrl ?? var url = urls[currentIndex].imageUrl ??
urls[currentIndex].assetUrl ?? urls[currentIndex].assetUrl ??
+4 -7
View File
@@ -157,9 +157,7 @@ class _ImageFooterState extends State<ImageFooter> {
icon: StreamSvgIcon.Icon_grid( icon: StreamSvgIcon.Icon_grid(
color: StreamChatTheme.of(context).colorTheme.black, color: StreamChatTheme.of(context).colorTheme.black,
), ),
onPressed: () { onPressed: () => _showPhotosModal(context),
_buildPhotosModal(context);
},
), ),
], ],
), ),
@@ -168,13 +166,14 @@ class _ImageFooterState extends State<ImageFooter> {
); );
} }
Widget _buildPhotosModal(context) { void _showPhotosModal(context) {
var videoAttachments = widget.mediaAttachments var videoAttachments = widget.mediaAttachments
.where((element) => element.type == 'video') .where((element) => element.type == 'video')
.toList(); .toList();
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
barrierColor: StreamChatTheme.of(context).colorTheme.overlay,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0), borderRadius: BorderRadius.circular(16.0),
), ),
@@ -207,9 +206,7 @@ class _ImageFooterState extends State<ImageFooter> {
icon: StreamSvgIcon.close( icon: StreamSvgIcon.close(
color: StreamChatTheme.of(context).colorTheme.black, color: StreamChatTheme.of(context).colorTheme.black,
), ),
onPressed: () { onPressed: () => Navigator.maybePop(context),
Navigator.pop(context);
},
), ),
), ),
], ],
+1
View File
@@ -106,6 +106,7 @@ class ImageHeader extends StatelessWidget implements PreferredSizeWidget {
showDialog( showDialog(
context: context, context: context,
barrierColor: StreamChatTheme.of(context).colorTheme.overlay,
builder: (context) { builder: (context) {
return StreamChannel( return StreamChannel(
channel: channel, channel: channel,
+4 -4
View File
@@ -73,17 +73,17 @@ class MessageActionsModal extends StatelessWidget {
return GestureDetector( return GestureDetector(
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
onTap: () => Navigator.pop(context), onTap: () => Navigator.maybePop(context),
child: Stack( child: Stack(
children: [ children: [
Positioned.fill( Positioned.fill(
child: BackdropFilter( child: BackdropFilter(
filter: ImageFilter.blur( filter: ImageFilter.blur(
sigmaX: 10.8731, sigmaX: 10,
sigmaY: 10.8731, sigmaY: 10,
), ),
child: Container( child: Container(
color: Colors.black.withOpacity(.2), color: StreamChatTheme.of(context).colorTheme.overlay,
), ),
), ),
), ),
+5 -13
View File
@@ -350,18 +350,9 @@ class _MessageListViewState extends State<MessageListView> {
buildParentMessage(widget.parentMessage), buildParentMessage(widget.parentMessage),
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient: StreamChatTheme.of(context)
begin: Alignment.topCenter, .colorTheme
end: Alignment.bottomCenter, .bgGradient,
colors: [
StreamChatTheme.of(context)
.colorTheme
.whiteSmoke,
StreamChatTheme.of(context)
.colorTheme
.whiteSnow,
],
),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
@@ -850,7 +841,8 @@ class _MessageListViewState extends State<MessageListView> {
widget.highlightInitialMessage && widget.highlightInitialMessage &&
_isInitialMessage(message.id)) { _isInitialMessage(message.id)) {
final colorTheme = StreamChatTheme.of(context).colorTheme; final colorTheme = StreamChatTheme.of(context).colorTheme;
final highlightColor = widget.messageHighlightColor ?? colorTheme.yellow; final highlightColor =
widget.messageHighlightColor ?? colorTheme.highlight;
child = TweenAnimationBuilder<Color>( child = TweenAnimationBuilder<Color>(
tween: ColorTween( tween: ColorTween(
begin: highlightColor, begin: highlightColor,
+15 -7
View File
@@ -40,27 +40,35 @@ class MessageReactionsModal extends StatelessWidget {
final user = StreamChat.of(context).user; final user = StreamChat.of(context).user;
final roughMaxSize = 2 * size.width / 3; final roughMaxSize = 2 * size.width / 3;
var messageTextLength = message.text.length;
if (message.quotedMessage != null) {
var quotedMessageLength = message.quotedMessage.text.length + 40;
if (message.quotedMessage.attachments?.isNotEmpty == true) {
quotedMessageLength += 40;
}
if (quotedMessageLength > messageTextLength) {
messageTextLength = quotedMessageLength;
}
}
final roughSentenceSize = final roughSentenceSize =
message.text.length * messageTheme.messageText.fontSize * 1.2; messageTextLength * messageTheme.messageText.fontSize * 1.2;
final divFactor = message.attachments?.isNotEmpty == true final divFactor = message.attachments?.isNotEmpty == true
? 1 ? 1
: (roughSentenceSize == 0 ? 1 : (roughSentenceSize / roughMaxSize)); : (roughSentenceSize == 0 ? 1 : (roughSentenceSize / roughMaxSize));
return GestureDetector( return GestureDetector(
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
onTap: () { onTap: () => Navigator.maybePop(context),
Navigator.pop(context);
},
child: Stack( child: Stack(
children: [ children: [
Positioned.fill( Positioned.fill(
child: BackdropFilter( child: BackdropFilter(
filter: ImageFilter.blur( filter: ImageFilter.blur(
sigmaX: 10.8731, sigmaX: 10,
sigmaY: 10.8731, sigmaY: 10,
), ),
child: Container( child: Container(
color: Colors.black.withOpacity(0.2), color: StreamChatTheme.of(context).colorTheme.overlay,
), ),
), ),
), ),
+2 -19
View File
@@ -313,21 +313,7 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
Container( Container(
width: double.maxFinite, width: double.maxFinite,
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient: StreamChatTheme.of(context).colorTheme.bgGradient,
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
StreamChatTheme.of(context)
.colorTheme
.black
.withOpacity(0.02),
StreamChatTheme.of(context)
.colorTheme
.white
.withOpacity(0.05),
],
stops: [0, 1],
),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
@@ -337,10 +323,7 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
child: Text( child: Text(
'${items.length} results', '${items.length} results',
style: TextStyle( style: TextStyle(
color: StreamChatTheme.of(context) color: StreamChatTheme.of(context).colorTheme.grey,
.colorTheme
.black
.withOpacity(0.5),
), ),
), ),
), ),
+2
View File
@@ -676,6 +676,7 @@ class _MessageWidgetState extends State<MessageWidget> {
final channel = StreamChannel.of(context).channel; final channel = StreamChannel.of(context).channel;
showDialog( showDialog(
context: context, context: context,
barrierColor: StreamChatTheme.of(context).colorTheme.overlay,
builder: (context) { builder: (context) {
return StreamChannel( return StreamChannel(
channel: channel, channel: channel,
@@ -716,6 +717,7 @@ class _MessageWidgetState extends State<MessageWidget> {
final channel = StreamChannel.of(context).channel; final channel = StreamChannel.of(context).channel;
showDialog( showDialog(
context: context, context: context,
barrierColor: StreamChatTheme.of(context).colorTheme.overlay,
builder: (context) { builder: (context) {
return StreamChannel( return StreamChannel(
channel: channel, channel: channel,
+38 -7
View File
@@ -460,7 +460,10 @@ class ColorTheme {
final Color accentBlue; final Color accentBlue;
final Color accentRed; final Color accentRed;
final Color accentGreen; final Color accentGreen;
final Color yellow; final Color highlight;
final Color overlay;
final Color overlayDark;
final Gradient bgGradient;
ColorTheme.light({ ColorTheme.light({
this.black = const Color(0xff000000), this.black = const Color(0xff000000),
@@ -474,7 +477,15 @@ class ColorTheme {
this.accentBlue = const Color(0xff005FFF), this.accentBlue = const Color(0xff005FFF),
this.accentRed = const Color(0xffFF3742), this.accentRed = const Color(0xffFF3742),
this.accentGreen = const Color(0xff20E070), this.accentGreen = const Color(0xff20E070),
this.yellow = const Color(0Xfffbf4dd), this.highlight = const Color(0xfffbf4dd),
this.overlay = const Color.fromRGBO(0, 0, 0, 0.2),
this.overlayDark = const Color.fromRGBO(0, 0, 0, 0.6),
this.bgGradient = const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [const Color(0xfff7f7f7), const Color(0xfffcfcfc)],
stops: [0, 1],
),
}); });
ColorTheme.dark({ ColorTheme.dark({
@@ -489,7 +500,15 @@ class ColorTheme {
this.accentBlue = const Color(0xff005FFF), this.accentBlue = const Color(0xff005FFF),
this.accentRed = const Color(0xffFF3742), this.accentRed = const Color(0xffFF3742),
this.accentGreen = const Color(0xff20E070), this.accentGreen = const Color(0xff20E070),
this.yellow = const Color(0xff302d22), this.highlight = const Color(0xff302d22),
this.overlay = const Color.fromRGBO(0, 0, 0, 0.4),
this.overlayDark = const Color.fromRGBO(255, 255, 255, 0.6),
this.bgGradient = const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [const Color(0xff101214), const Color(0xff070a0d)],
stops: [0, 1],
),
}); });
ColorTheme copyWith({ ColorTheme copyWith({
@@ -505,7 +524,10 @@ class ColorTheme {
Color accentBlue, Color accentBlue,
Color accentRed, Color accentRed,
Color accentGreen, Color accentGreen,
Color yellow, Color highlight,
Color overlay,
Color overlayDark,
Gradient bgGradient,
}) { }) {
return type == ColorThemeType.light return type == ColorThemeType.light
? ColorTheme.light( ? ColorTheme.light(
@@ -520,7 +542,10 @@ class ColorTheme {
accentBlue: accentBlue ?? this.accentBlue, accentBlue: accentBlue ?? this.accentBlue,
accentRed: accentRed ?? this.accentRed, accentRed: accentRed ?? this.accentRed,
accentGreen: accentGreen ?? this.accentGreen, accentGreen: accentGreen ?? this.accentGreen,
yellow: yellow ?? this.yellow, highlight: highlight ?? this.highlight,
overlay: overlay ?? this.overlay,
overlayDark: overlayDark ?? this.overlayDark,
bgGradient: bgGradient ?? this.bgGradient,
) )
: ColorTheme.dark( : ColorTheme.dark(
black: black ?? this.black, black: black ?? this.black,
@@ -534,7 +559,10 @@ class ColorTheme {
accentBlue: accentBlue ?? this.accentBlue, accentBlue: accentBlue ?? this.accentBlue,
accentRed: accentRed ?? this.accentRed, accentRed: accentRed ?? this.accentRed,
accentGreen: accentGreen ?? this.accentGreen, accentGreen: accentGreen ?? this.accentGreen,
yellow: yellow ?? this.yellow, highlight: highlight ?? this.highlight,
overlay: overlay ?? this.overlay,
overlayDark: overlayDark ?? this.overlayDark,
bgGradient: bgGradient ?? this.bgGradient,
); );
} }
@@ -552,7 +580,10 @@ class ColorTheme {
accentBlue: other.accentBlue, accentBlue: other.accentBlue,
accentRed: other.accentRed, accentRed: other.accentRed,
accentGreen: other.accentGreen, accentGreen: other.accentGreen,
yellow: other.yellow, highlight: other.highlight,
overlay: other.overlay,
overlayDark: other.overlayDark,
bgGradient: other.bgGradient,
); );
} }
} }
+4 -6
View File
@@ -363,12 +363,10 @@ class _UserListViewState extends State<UserListView>
child: Text( child: Text(
header, header,
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 14.5, fontSize: 14.5,
color: StreamChatTheme.of(context) color: StreamChatTheme.of(context).colorTheme.grey,
.colorTheme ),
.black
.withOpacity(0.3)),
), ),
), ),
); );