-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor of thumbnail badges and compact post cards (#1066)
- Loading branch information
Showing
5 changed files
with
137 additions
and
178 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,103 +1,88 @@ | ||
import 'package:flutter/material.dart'; | ||
|
||
import 'package:flutter_bloc/flutter_bloc.dart'; | ||
|
||
import 'package:thunder/core/enums/media_type.dart'; | ||
import 'package:thunder/core/theme/bloc/theme_bloc.dart'; | ||
|
||
import '../../core/enums/media_type.dart'; | ||
import '../../core/models/post_view_media.dart'; | ||
/// Base representation of a media type badge. Holds the icon and color. | ||
class MediaTypeBadgeItem { | ||
/// The icon associated with the media type | ||
final Icon icon; | ||
|
||
/// The color associated with the media type | ||
final Color baseColor; | ||
|
||
const MediaTypeBadgeItem({required this.baseColor, required this.icon}); | ||
} | ||
|
||
class TypeBadge extends StatelessWidget { | ||
const TypeBadge({ | ||
super.key, | ||
required this.postViewMedia, | ||
required this.read, | ||
}); | ||
/// Determines whether the badge should be dimmed or not. This is usually to indicate when a post has been read. | ||
final bool dim; | ||
|
||
/// The media type of the badge. This is used to determine the badge color and icon. | ||
final MediaType mediaType; | ||
|
||
final PostViewMedia postViewMedia; | ||
final bool read; | ||
const TypeBadge({super.key, required this.dim, required this.mediaType}); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final theme = Theme.of(context); | ||
|
||
Color getMaterialColor(Color blendColor) { | ||
return Color.alphaBlend(theme.colorScheme.primaryContainer.withOpacity(0.6), blendColor).withOpacity(read ? 0.55 : 1); | ||
} | ||
|
||
Color getIconColor(Color blendColor) { | ||
return Color.alphaBlend(theme.colorScheme.onPrimaryContainer.withOpacity(0.9), blendColor).withOpacity(read ? 0.55 : 1); | ||
} | ||
|
||
final bool darkTheme = context.read<ThemeBloc>().state.useDarkTheme; | ||
const borderRadius = BorderRadius.only(topLeft: Radius.circular(15), bottomLeft: Radius.circular(4), bottomRight: Radius.circular(12), topRight: Radius.circular(4)); | ||
|
||
Map<MediaType, MediaTypeBadgeItem> mediaTypeItems = { | ||
MediaType.text: MediaTypeBadgeItem( | ||
baseColor: Colors.green, | ||
icon: Icon(size: 17, Icons.wysiwyg_rounded, color: getIconColor(theme, Colors.green)), | ||
), | ||
MediaType.link: MediaTypeBadgeItem( | ||
baseColor: Colors.blue, | ||
icon: Icon(size: 19, Icons.link_rounded, color: getIconColor(theme, Colors.blue)), | ||
), | ||
MediaType.image: MediaTypeBadgeItem( | ||
baseColor: Colors.red, | ||
icon: Icon(size: 17, Icons.image_rounded, color: getIconColor(theme, Colors.red)), | ||
) | ||
}; | ||
|
||
return SizedBox( | ||
height: 28, | ||
width: 28, | ||
child: Material( | ||
borderRadius: const BorderRadius.only( | ||
topLeft: Radius.circular(15), | ||
bottomLeft: Radius.circular(4), | ||
bottomRight: Radius.circular(12), | ||
topRight: Radius.circular(4), | ||
), | ||
borderRadius: borderRadius, | ||
// This is the thin sliver between the badge and the preview. | ||
// It should be made to match the read background color in the compact file. | ||
color: read | ||
? Color.alphaBlend( | ||
theme.colorScheme.onBackground.withOpacity(darkTheme ? 0.05 : 0.075), | ||
theme.colorScheme.background, | ||
) | ||
: theme.colorScheme.background, | ||
color: dim ? Color.alphaBlend(theme.colorScheme.onBackground.withOpacity(darkTheme ? 0.05 : 0.075), theme.colorScheme.background) : theme.colorScheme.background, | ||
child: Padding( | ||
padding: const EdgeInsets.only( | ||
left: 2.5, | ||
top: 2.5, | ||
), | ||
child: postViewMedia.media.isEmpty | ||
? Material( | ||
borderRadius: const BorderRadius.only( | ||
bottomLeft: Radius.circular(4), | ||
bottomRight: Radius.circular(12), | ||
topLeft: Radius.circular(12), | ||
topRight: Radius.circular(4), | ||
), | ||
color: getMaterialColor(Colors.green), | ||
child: Icon( | ||
size: 17, | ||
Icons.wysiwyg_rounded, | ||
color: getIconColor(Colors.green), | ||
), | ||
) | ||
: postViewMedia.media.firstOrNull?.mediaType == MediaType.link | ||
? Material( | ||
borderRadius: const BorderRadius.only( | ||
bottomLeft: Radius.circular(4), | ||
bottomRight: Radius.circular(12), | ||
topLeft: Radius.circular(12), | ||
topRight: Radius.circular(4), | ||
), | ||
color: getMaterialColor(Colors.blue), | ||
child: Icon( | ||
size: 19, | ||
Icons.link_rounded, | ||
color: getIconColor(Colors.blue), | ||
), | ||
) | ||
: Material( | ||
borderRadius: const BorderRadius.only( | ||
bottomLeft: Radius.circular(4), | ||
bottomRight: Radius.circular(12), | ||
topLeft: Radius.circular(12), | ||
topRight: Radius.circular(4), | ||
), | ||
color: getMaterialColor(Colors.red), | ||
child: Icon( | ||
size: 17, | ||
Icons.image_outlined, | ||
color: getIconColor(Colors.red), | ||
), | ||
), | ||
padding: const EdgeInsets.only(left: 2.5, top: 2.5), | ||
child: switch (mediaType) { | ||
MediaType.text => typeBadgeItem(context, mediaTypeItems[MediaType.text]!), | ||
MediaType.link => typeBadgeItem(context, mediaTypeItems[MediaType.link]!), | ||
MediaType.image => typeBadgeItem(context, mediaTypeItems[MediaType.image]!), | ||
_ => typeBadgeItem(context, mediaTypeItems[MediaType.text]!), | ||
}, | ||
), | ||
), | ||
); | ||
} | ||
|
||
Widget typeBadgeItem(context, MediaTypeBadgeItem mediaTypeBadgeItem) { | ||
final theme = Theme.of(context); | ||
const innerBorderRadius = BorderRadius.only(topLeft: Radius.circular(12), bottomLeft: Radius.circular(4), bottomRight: Radius.circular(12), topRight: Radius.circular(4)); | ||
|
||
return Material( | ||
borderRadius: innerBorderRadius, | ||
color: getMaterialColor(theme, mediaTypeBadgeItem.baseColor), | ||
child: mediaTypeBadgeItem.icon, | ||
); | ||
} | ||
|
||
Color getMaterialColor(ThemeData theme, Color blendColor) { | ||
return Color.alphaBlend(theme.colorScheme.primaryContainer.withOpacity(0.6), blendColor).withOpacity(dim ? 0.55 : 1); | ||
} | ||
|
||
Color getIconColor(ThemeData theme, Color blendColor) { | ||
return Color.alphaBlend(theme.colorScheme.onPrimaryContainer.withOpacity(0.9), blendColor).withOpacity(dim ? 0.55 : 1); | ||
} | ||
} |
Oops, something went wrong.