Skip to content

Commit

Permalink
Refactor of thumbnail badges and compact post cards (#1066)
Browse files Browse the repository at this point in the history
  • Loading branch information
hjiangsu authored Jan 18, 2024
1 parent 313e25b commit 86942ed
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 178 deletions.
6 changes: 0 additions & 6 deletions lib/community/widgets/post_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -192,16 +192,10 @@ class _PostCardState extends State<PostCard> {
child: state.useCompactView
? PostCardViewCompact(
postViewMedia: widget.postViewMedia,
showThumbnailPreviewOnRight: state.showThumbnailPreviewOnRight,
showTextPostIndicator: state.showTextPostIndicator,
showPostAuthor: state.showPostAuthor,
hideNsfwPreviews: state.hideNsfwPreviews,
markPostReadOnMediaView: state.markPostReadOnMediaView,
communityMode: widget.communityMode,
isUserLoggedIn: isUserLoggedIn,
listingType: widget.listingType,
navigateToPost: ({PostViewMedia? postViewMedia}) async => await navigateToPost(context, postViewMedia: widget.postViewMedia),
indicateRead: widget.indicateRead,
)
: PostCardViewComfortable(
postViewMedia: widget.postViewMedia,
Expand Down
141 changes: 63 additions & 78 deletions lib/community/widgets/post_card_type_badge.dart
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);
}
}
Loading

0 comments on commit 86942ed

Please sign in to comment.