Skip to content

Commit

Permalink
Add support for customizable action colors (#1304)
Browse files Browse the repository at this point in the history
* Add support for customizale action colors

* Add red action color

* Refactor action color settings widget
  • Loading branch information
micahmo authored May 1, 2024
1 parent 7293229 commit 405491c
Show file tree
Hide file tree
Showing 22 changed files with 636 additions and 95 deletions.
25 changes: 13 additions & 12 deletions lib/community/utils/post_card_action_helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import 'package:thunder/post/widgets/reason_bottom_sheet.dart';
import 'package:thunder/shared/advanced_share_sheet.dart';
import 'package:thunder/shared/picker_item.dart';
import 'package:thunder/shared/snackbar.dart';
import 'package:thunder/thunder/bloc/thunder_bloc.dart';
import 'package:thunder/user/bloc/user_bloc.dart';
import 'package:thunder/user/enums/user_action.dart';
import 'package:thunder/utils/instance.dart';
Expand Down Expand Up @@ -70,7 +71,7 @@ class ExtendedPostCardActions {
required this.icon,
this.trailingIcon,
required this.label,
this.color,
this.getColor,
this.getForegroundColor,
this.getOverrideIcon,
this.getOverrideLabel,
Expand All @@ -83,8 +84,8 @@ class ExtendedPostCardActions {
final IconData icon;
final IconData? trailingIcon;
final String label;
final Color? color;
final Color? Function(PostView postView)? getForegroundColor;
final Color Function(BuildContext context)? getColor;
final Color? Function(BuildContext context, PostView postView)? getForegroundColor;
final IconData? Function(PostView postView)? getOverrideIcon;
final String? Function(BuildContext context, PostView postView)? getOverrideLabel;
final String? Function(BuildContext context, PostViewMedia postViewMedia)? getSubtitleLabel;
Expand Down Expand Up @@ -195,33 +196,33 @@ final List<ExtendedPostCardActions> postCardActionItems = [
postCardAction: PostCardAction.upvote,
label: l10n.upvote,
icon: Icons.arrow_upward_rounded,
color: Colors.orange,
getForegroundColor: (postView) => postView.myVote == 1 ? Colors.orange : null,
getColor: (context) => context.read<ThunderBloc>().state.upvoteColor.color,
getForegroundColor: (context, postView) => postView.myVote == 1 ? context.read<ThunderBloc>().state.upvoteColor.color : null,
shouldEnable: (isUserLoggedIn) => isUserLoggedIn,
),
ExtendedPostCardActions(
postCardAction: PostCardAction.downvote,
label: l10n.downvote,
icon: Icons.arrow_downward_rounded,
color: Colors.blue,
getForegroundColor: (postView) => postView.myVote == -1 ? Colors.blue : null,
getColor: (context) => context.read<ThunderBloc>().state.downvoteColor.color,
getForegroundColor: (context, postView) => postView.myVote == -1 ? context.read<ThunderBloc>().state.downvoteColor.color : null,
shouldShow: (context, commentView) => context.read<AuthBloc>().state.downvotesEnabled,
shouldEnable: (isUserLoggedIn) => isUserLoggedIn,
),
ExtendedPostCardActions(
postCardAction: PostCardAction.save,
label: l10n.save,
icon: Icons.star_border_rounded,
color: Colors.purple,
getForegroundColor: (postView) => postView.saved ? Colors.purple : null,
getColor: (context) => context.read<ThunderBloc>().state.saveColor.color,
getForegroundColor: (context, postView) => postView.saved ? context.read<ThunderBloc>().state.saveColor.color : null,
getOverrideIcon: (postView) => postView.saved ? Icons.star_rounded : null,
shouldEnable: (isUserLoggedIn) => isUserLoggedIn,
),
ExtendedPostCardActions(
postCardAction: PostCardAction.toggleRead,
label: l10n.toggelRead,
icon: Icons.mail_outline_outlined,
color: Colors.teal.shade300,
getColor: (context) => context.read<ThunderBloc>().state.markReadColor.color,
getOverrideIcon: (postView) => postView.read ? Icons.mark_email_unread_rounded : Icons.mark_email_read_outlined,
shouldEnable: (isUserLoggedIn) => isUserLoggedIn,
),
Expand Down Expand Up @@ -520,8 +521,8 @@ class _PostCardActionPickerState extends State<PostCardActionPicker> {
return PickerItemData(
label: a.label,
icon: a.getOverrideIcon?.call(widget.postViewMedia.postView) ?? a.icon,
backgroundColor: a.color,
foregroundColor: a.getForegroundColor?.call(widget.postViewMedia.postView),
backgroundColor: a.getColor?.call(context),
foregroundColor: a.getForegroundColor?.call(context, widget.postViewMedia.postView),
onSelected: (a.shouldEnable?.call(isUserLoggedIn) ?? true) ? () => onSelected(a.postCardAction) : null,
);
},
Expand Down
7 changes: 5 additions & 2 deletions lib/community/widgets/post_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ class _PostCardState extends State<PostCard> {
background: dismissDirection == DismissDirection.startToEnd
? AnimatedContainer(
alignment: Alignment.centerLeft,
color: swipeAction == null ? state.leftPrimaryPostGesture.getColor().withOpacity(dismissThreshold / firstActionThreshold) : (swipeAction ?? SwipeAction.none).getColor(),
color:
swipeAction == null ? state.leftPrimaryPostGesture.getColor(context).withOpacity(dismissThreshold / firstActionThreshold) : (swipeAction ?? SwipeAction.none).getColor(context),
duration: const Duration(milliseconds: 200),
child: SizedBox(
width: MediaQuery.of(context).size.width * (state.tabletMode ? 0.5 : 1) * dismissThreshold,
Expand All @@ -188,7 +189,9 @@ class _PostCardState extends State<PostCard> {
)
: AnimatedContainer(
alignment: Alignment.centerRight,
color: swipeAction == null ? state.rightPrimaryPostGesture.getColor().withOpacity(dismissThreshold / firstActionThreshold) : (swipeAction ?? SwipeAction.none).getColor(),
color: swipeAction == null
? state.rightPrimaryPostGesture.getColor(context).withOpacity(dismissThreshold / firstActionThreshold)
: (swipeAction ?? SwipeAction.none).getColor(context),
duration: const Duration(milliseconds: 200),
child: SizedBox(
width: (MediaQuery.of(context).size.width * (state.tabletMode ? 0.5 : 1)) * dismissThreshold,
Expand Down
10 changes: 3 additions & 7 deletions lib/community/widgets/post_card_actions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ class PostCardActions extends StatelessWidget {
required this.onSaveAction,
});

final MaterialColor upVoteColor = Colors.orange;
final MaterialColor downVoteColor = Colors.blue;
final MaterialColor savedColor = Colors.purple;

@override
Widget build(BuildContext context) {
return BlocBuilder<ThunderBloc, ThunderState>(
Expand All @@ -47,7 +43,7 @@ class PostCardActions extends StatelessWidget {
Icons.arrow_upward,
semanticLabel: voteType == 1 ? 'Upvoted' : 'Upvote',
),
color: voteType == 1 ? upVoteColor : null,
color: voteType == 1 ? context.read<ThunderBloc>().state.upvoteColor.color : null,
visualDensity: VisualDensity.compact,
onPressed: () {
HapticFeedback.mediumImpact();
Expand All @@ -59,7 +55,7 @@ class PostCardActions extends StatelessWidget {
Icons.arrow_downward,
semanticLabel: voteType == -1 ? 'Downvoted' : 'Downvote',
),
color: voteType == -1 ? downVoteColor : null,
color: voteType == -1 ? context.read<ThunderBloc>().state.downvoteColor.color : null,
visualDensity: VisualDensity.compact,
onPressed: () {
HapticFeedback.mediumImpact();
Expand All @@ -72,7 +68,7 @@ class PostCardActions extends StatelessWidget {
saved ? Icons.star_rounded : Icons.star_border_rounded,
semanticLabel: saved ? 'Saved' : 'Save',
),
color: saved ? savedColor : null,
color: saved ? context.read<ThunderBloc>().state.saveColor.color : null,
visualDensity: VisualDensity.compact,
onPressed: () {
HapticFeedback.mediumImpact();
Expand Down
11 changes: 4 additions & 7 deletions lib/community/widgets/post_card_metadata.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ import 'package:thunder/utils/date_time.dart';
import 'package:thunder/utils/instance.dart';
import 'package:thunder/utils/numbers.dart';

const Color upVoteColor = Colors.orange;
const Color downVoteColor = Colors.blue;

/// Contains metadata related to a given post. This is generally displayed as part of the post card.
///
/// This information is customizable, and can be changed by the user in the settings.
Expand Down Expand Up @@ -131,8 +128,8 @@ class ScorePostCardMetaData extends StatelessWidget {
final readColor = theme.textTheme.bodyMedium?.color?.withOpacity(0.45);

final color = switch (voteType) {
1 => upVoteColor,
-1 => downVoteColor,
1 => context.read<ThunderBloc>().state.upvoteColor.color,
-1 => context.read<ThunderBloc>().state.downvoteColor.color,
_ => hasBeenRead ? readColor : theme.textTheme.bodyMedium?.color,
};

Expand Down Expand Up @@ -179,7 +176,7 @@ class UpvotePostCardMetaData extends StatelessWidget {
final readColor = theme.textTheme.bodyMedium?.color?.withOpacity(0.45);

final color = switch (isUpvoted) {
true => upVoteColor,
true => context.read<ThunderBloc>().state.upvoteColor.color,
_ => hasBeenRead ? readColor : theme.textTheme.bodyMedium?.color,
};

Expand Down Expand Up @@ -218,7 +215,7 @@ class DownvotePostCardMetaData extends StatelessWidget {
final readColor = theme.textTheme.bodyMedium?.color?.withOpacity(0.45);

final color = switch (isDownvoted) {
true => downVoteColor,
true => context.read<ThunderBloc>().state.downvoteColor.color,
_ => hasBeenRead ? readColor : theme.textTheme.bodyMedium?.color,
};

Expand Down
11 changes: 7 additions & 4 deletions lib/community/widgets/post_card_view_comfortable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,16 @@ class PostCardViewComfortable extends StatelessWidget {
WidgetSpan(
child: Icon(
Icons.lock,
color: indicateRead && postViewMedia.postView.read ? Colors.orange.shade900.withOpacity(0.55) : Colors.orange.shade900,
color:
indicateRead && postViewMedia.postView.read ? context.read<ThunderBloc>().state.upvoteColor.color.withOpacity(0.55) : context.read<ThunderBloc>().state.upvoteColor.color,
size: 15 * textScaleFactor,
)),
],
if (!useSaveButton && postViewMedia.postView.saved)
WidgetSpan(
child: Icon(
Icons.star_rounded,
color: indicateRead && postViewMedia.postView.read ? Colors.purple.withOpacity(0.55) : Colors.purple,
color: indicateRead && postViewMedia.postView.read ? context.read<ThunderBloc>().state.saveColor.color.withOpacity(0.55) : context.read<ThunderBloc>().state.saveColor.color,
size: 17 * textScaleFactor,
semanticLabel: 'Saved',
),
Expand Down Expand Up @@ -199,15 +200,17 @@ class PostCardViewComfortable extends StatelessWidget {
WidgetSpan(
child: Icon(
Icons.lock,
color: indicateRead && postViewMedia.postView.read ? Colors.orange.shade900.withOpacity(0.55) : Colors.orange.shade900,
color:
indicateRead && postViewMedia.postView.read ? context.read<ThunderBloc>().state.upvoteColor.color.withOpacity(0.55) : context.read<ThunderBloc>().state.upvoteColor.color,
size: 15 * textScaleFactor,
)),
],
if (!useSaveButton && postViewMedia.postView.saved)
WidgetSpan(
child: Icon(
Icons.star_rounded,
color: indicateRead && postViewMedia.postView.read ? Colors.purple.withOpacity(0.55) : Colors.purple,
color:
indicateRead && postViewMedia.postView.read ? context.read<ThunderBloc>().state.saveColor.color.withOpacity(0.55) : context.read<ThunderBloc>().state.saveColor.color,
size: 17 * textScaleFactor,
semanticLabel: 'Saved',
),
Expand Down
7 changes: 5 additions & 2 deletions lib/community/widgets/post_card_view_compact.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ class PostCardViewCompact extends StatelessWidget {
WidgetSpan(
child: Icon(
Icons.lock,
color: indicateRead && postViewMedia.postView.read ? Colors.orange.shade900.withOpacity(0.55) : Colors.orange.shade900,
color: indicateRead && postViewMedia.postView.read
? context.read<ThunderBloc>().state.upvoteColor.color.withOpacity(0.55)
: context.read<ThunderBloc>().state.upvoteColor.color,
size: 15 * textScaleFactor,
),
),
Expand All @@ -90,7 +92,8 @@ class PostCardViewCompact extends StatelessWidget {
WidgetSpan(
child: Icon(
Icons.star_rounded,
color: indicateRead && postViewMedia.postView.read ? Colors.purple.withOpacity(0.55) : Colors.purple,
color:
indicateRead && postViewMedia.postView.read ? context.read<ThunderBloc>().state.saveColor.color.withOpacity(0.55) : context.read<ThunderBloc>().state.saveColor.color,
size: 17 * textScaleFactor,
semanticLabel: 'Saved',
),
Expand Down
45 changes: 45 additions & 0 deletions lib/core/enums/action_color.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

class ActionColor {
static const String orange = '0xFFF57C00'; // Colors.orange.shade700
static const String blue = '0xFF1976D2'; // Colors.blue.shade700
static const String purple = '0xFF7B1FA2'; // Colors.purple.shade700
static const String teal = '0xFF4DB6AC'; // Colors.teal.shade300
static const String green = '0xFF388E3C'; // Colors.green.shade700
static const String red = '0xFFD32F2F'; // Colors.red.shade700

final String colorRaw;

Color get color => Color(int.parse(colorRaw));

const ActionColor.fromString({required this.colorRaw});

@override
String toString() => color.value.toString();

String label(BuildContext context) {
final AppLocalizations l10n = AppLocalizations.of(context)!;

return switch (colorRaw) {
orange => l10n.orange,
blue => l10n.blue,
purple => l10n.purple,
teal => l10n.teal,
green => l10n.green,
red => l10n.red,
_ => throw Exception('Unknown color'),
};
}

static List<ActionColor> getPossibleValues(ActionColor currentValue) {
return [
currentValue.colorRaw == orange ? currentValue : const ActionColor.fromString(colorRaw: ActionColor.orange),
currentValue.colorRaw == blue ? currentValue : const ActionColor.fromString(colorRaw: ActionColor.blue),
currentValue.colorRaw == purple ? currentValue : const ActionColor.fromString(colorRaw: ActionColor.purple),
currentValue.colorRaw == teal ? currentValue : const ActionColor.fromString(colorRaw: ActionColor.teal),
currentValue.colorRaw == green ? currentValue : const ActionColor.fromString(colorRaw: ActionColor.green),
currentValue.colorRaw == red ? currentValue : const ActionColor.fromString(colorRaw: ActionColor.red),
];
}
}
Loading

0 comments on commit 405491c

Please sign in to comment.