diff --git a/app/javascript/mastodon/components/status/action_bar.tsx b/app/javascript/mastodon/components/status/action_bar.tsx index d3ca0e95e61..d111922f0e1 100644 --- a/app/javascript/mastodon/components/status/action_bar.tsx +++ b/app/javascript/mastodon/components/status/action_bar.tsx @@ -53,10 +53,10 @@ interface StatusActionBarProps { const messages = defineMessages({ replyAll: { id: 'status.replyAll', defaultMessage: 'Reply to thread' }, - favourite: { id: 'status.favourite', defaultMessage: 'Favorite' }, + favourite: { id: 'status.like', defaultMessage: 'Like' }, removeFavourite: { - id: 'status.remove_favourite', - defaultMessage: 'Remove from favorites', + id: 'status.unlike', + defaultMessage: 'Unlike', }, }); @@ -184,11 +184,11 @@ export const StatusActionBar: React.FC = ({ onClick={handleBookmarkClick} > {!status.bookmarked ? ( - + ) : ( )} diff --git a/app/javascript/mastodon/components/status/legacy/action_bar/index.jsx b/app/javascript/mastodon/components/status/legacy/action_bar/index.jsx index d93f552b38f..76ce2f2d3f7 100644 --- a/app/javascript/mastodon/components/status/legacy/action_bar/index.jsx +++ b/app/javascript/mastodon/components/status/legacy/action_bar/index.jsx @@ -28,9 +28,10 @@ import { BoostButton } from '../boost_button'; import { RemoveQuoteHint } from './remove_quote_hint'; import { quoteItemState } from '../../boost_button_utils'; import { selectStatusConditions } from '@/mastodon/selectors/statuses'; +import { isRedesignEnabled } from '@/mastodon/utils/environment'; -const messages = defineMessages({ +const baseMessages = defineMessages({ delete: { id: 'status.delete', defaultMessage: 'Delete' }, redraft: { id: 'status.redraft', defaultMessage: 'Delete & re-draft' }, edit: { id: 'status.edit', defaultMessage: 'Edit' }, @@ -67,6 +68,15 @@ const messages = defineMessages({ quotePolicyChange: { id: 'status.quote_policy_change', defaultMessage: 'Change who can quote' }, }); +const redesignMessages = defineMessages({ + favourite: { id: 'status.like', defaultMessage: 'Like' }, + removeFavourite: { id: 'status.unlike', defaultMessage: 'Unlike' }, + bookmark: { id: 'status.save', defaultMessage: 'Save' }, + removeBookmark: { id: 'status.remove_from_saved', defaultMessage: 'Remove from Saved' }, +}); + +const messages = isRedesignEnabled() ? {...baseMessages, ...redesignMessages} : baseMessages; + const mapStateToProps = (state, { status }) => { const quotedStatusId = status.getIn(['quote', 'quoted_status']); return ({ diff --git a/app/javascript/mastodon/features/annual_report/highlighted_post.tsx b/app/javascript/mastodon/features/annual_report/highlighted_post.tsx index 6206e5f8985..51355a05e4b 100644 --- a/app/javascript/mastodon/features/annual_report/highlighted_post.tsx +++ b/app/javascript/mastodon/features/annual_report/highlighted_post.tsx @@ -11,6 +11,7 @@ import { FormattedMessage } from 'react-intl'; import classNames from 'classnames'; +import { isRedesignEnabled } from '@/mastodon/utils/environment'; import { Status } from 'mastodon/components/status'; import { InterceptStatusClicks } from 'mastodon/components/status/intercept_status_clicks'; import type { TopStatuses } from 'mastodon/models/annual_report'; @@ -65,7 +66,13 @@ export const HighlightedPost: React.FC<{ /> ); } else if (by_favourites) { - label = ( + label = isRedesignEnabled() ? ( + + ) : ( = ({ const pinned = !!columnId; - const emptyMessage = ( + const emptyMessage = isRedesignEnabled() ? ( + + ) : ( ); + const title = intl.formatMessage( + isRedesignEnabled() ? messages.heading_redesign : messages.heading, + ); + return ( - + {isRedesignEnabled() ? ( + = ({ = ({ /> - {intl.formatMessage(messages.heading)} + {title} diff --git a/app/javascript/mastodon/features/favourites/index.tsx b/app/javascript/mastodon/features/favourites/index.tsx index 5937ab56e05..d3b97f7442f 100644 --- a/app/javascript/mastodon/features/favourites/index.tsx +++ b/app/javascript/mastodon/features/favourites/index.tsx @@ -78,7 +78,12 @@ const Favourites: React.FC<{ multiColumn?: boolean }> = ({ multiColumn }) => { ); } - const emptyMessage = ( + const emptyMessage = isRedesignEnabled() ? ( + + ) : ( f - + + {isRedesignEnabled() ? ( + + ) : ( + + )} + b @@ -170,7 +176,13 @@ class KeyboardShortcuts extends ImmutablePureComponent { g+f - + + {isRedesignEnabled() ? ( + + ) : ( + + )} + g+u diff --git a/app/javascript/mastodon/features/notifications/components/notification.jsx b/app/javascript/mastodon/features/notifications/components/notification.jsx index 08327c80b4c..621633c4228 100644 --- a/app/javascript/mastodon/features/notifications/components/notification.jsx +++ b/app/javascript/mastodon/features/notifications/components/notification.jsx @@ -31,9 +31,11 @@ import FollowRequestContainer from '../containers/follow_request_container'; import { ModerationWarning } from './moderation_warning'; import { RelationshipsSeveranceEvent } from './relationships_severance_event'; import Report from './report'; +import { isRedesignEnabled } from '@/mastodon/utils/environment'; const messages = defineMessages({ favourite: { id: 'notification.favourite', defaultMessage: '{name} favorited your post' }, + favourite_redesign: { id: 'notification.like', defaultMessage: '{name} liked your post' }, follow: { id: 'notification.follow', defaultMessage: '{name} followed you' }, ownPoll: { id: 'notification.own_poll', defaultMessage: 'Your poll has ended' }, poll: { id: 'notification.poll', defaultMessage: 'A poll you voted in has ended' }, @@ -182,14 +184,16 @@ class Notification extends ImmutablePureComponent { renderFavourite (notification, link) { const { intl, unread } = this.props; + const likeMessage = isRedesignEnabled() ? messages.favourite_redesign : messages.favourite; + return ( -
+
- +
diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_favourite.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_favourite.tsx index 23ead604ba7..d09a7fd9fac 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/notification_favourite.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_favourite.tsx @@ -1,7 +1,8 @@ -import { FormattedMessage } from 'react-intl'; +import { defineMessages, FormattedMessage } from 'react-intl'; import { Link } from 'react-router-dom'; +import { isRedesignEnabled } from '@/mastodon/utils/environment'; import StarIcon from '@/material-icons/400-24px/star-fill.svg?react'; import type { NotificationGroupFavourite } from 'mastodon/models/notification_group'; import { useAppSelector } from 'mastodon/store'; @@ -9,20 +10,59 @@ import { useAppSelector } from 'mastodon/store'; import type { LabelRenderer } from './notification_group_with_status'; import { NotificationGroupWithStatus } from './notification_group_with_status'; +const messagesLegacy = defineMessages({ + like: { + id: 'notification.favourite', + defaultMessage: '{name} favorited your post', + }, + likeByMultiple: { + id: 'notification.favourite.name_and_others_with_link', + defaultMessage: + '{name} and {count, plural, one {# other} other {# others}} favorited your post', + }, + messageLike: { + id: 'notification.favourite_pm', + defaultMessage: '{name} favorited your private mention', + }, + messageLikeByMultiple: { + id: 'notification.favourite_pm.name_and_others_with_link', + defaultMessage: + '{name} and {count, plural, one {# other} other {# others}} favorited your private mention', + }, +}); + +const messagesRedesign = defineMessages({ + like: { + id: 'notification.like', + defaultMessage: '{name} liked your post', + }, + likeByMultiple: { + id: 'notification.like.name_and_others_with_link', + defaultMessage: + '{name} and {count, plural, one {# other} other {# others}} liked your post', + }, + messageLike: { + id: 'notification.like_message', + defaultMessage: '{name} liked your message', + }, + messageLikeByMultiple: { + id: 'notification.like_message.name_and_others_with_link', + defaultMessage: + '{name} and {count, plural, one {# other} other {# others}} liked your message', + }, +}); + +const messages = isRedesignEnabled() ? messagesRedesign : messagesLegacy; + const labelRenderer: LabelRenderer = (displayedName, total, seeMoreHref) => { if (total === 1) return ( - + ); return ( ); return ( diff --git a/app/javascript/mastodon/features/status/components/action_bar.jsx b/app/javascript/mastodon/features/status/components/action_bar.jsx index 13aa0c7876b..6d8831bb5ea 100644 --- a/app/javascript/mastodon/features/status/components/action_bar.jsx +++ b/app/javascript/mastodon/features/status/components/action_bar.jsx @@ -23,8 +23,9 @@ import { me, quickBoosting } from '@/mastodon/initial_state'; import { BoostButton } from '@/mastodon/components/status/legacy/boost_button'; import { quoteItemState } from '@/mastodon/components/status/boost_button_utils'; import { selectStatusConditions } from '@/mastodon/selectors/statuses'; +import { isRedesignEnabled } from '@/mastodon/utils/environment'; -const messages = defineMessages({ +const baseMessages = defineMessages({ delete: { id: 'status.delete', defaultMessage: 'Delete' }, redraft: { id: 'status.redraft', defaultMessage: 'Delete & re-draft' }, edit: { id: 'status.edit', defaultMessage: 'Edit' }, @@ -58,6 +59,15 @@ const messages = defineMessages({ quotePolicyChange: { id: 'status.quote_policy_change', defaultMessage: 'Change who can quote' }, }); +const redesignMessages = defineMessages({ + favourite: { id: 'status.like', defaultMessage: 'Like' }, + removeFavourite: { id: 'status.unlike', defaultMessage: 'Unlike' }, + bookmark: { id: 'status.save', defaultMessage: 'Save' }, + removeBookmark: { id: 'status.remove_from_saved', defaultMessage: 'Remove from Saved' }, +}) + +const messages = isRedesignEnabled() ? {...baseMessages, ...redesignMessages} : baseMessages; + const mapStateToProps = (state, { status }) => { const quotedStatusId = status.getIn(['quote', 'quoted_status']); return ({ diff --git a/app/javascript/mastodon/features/status/components/detailed_status.tsx b/app/javascript/mastodon/features/status/components/detailed_status.tsx index e04f27ca9ad..980462c3b31 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.tsx +++ b/app/javascript/mastodon/features/status/components/detailed_status.tsx @@ -18,6 +18,7 @@ import type { StatusLike } from '@/mastodon/components/status/legacy/hashtag_bar import { getHashtagBarForStatus } from '@/mastodon/components/status/legacy/hashtag_bar'; import { PictureInPicturePlaceholder } from '@/mastodon/components/status/legacy/picture_in_picture_placeholder'; import { QuotedStatus } from '@/mastodon/components/status/legacy/quoted'; +import { isRedesignEnabled } from '@/mastodon/utils/environment'; import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; import { AnimatedNumber } from 'mastodon/components/animated_number'; import { Avatar } from 'mastodon/components/avatar'; @@ -391,18 +392,33 @@ export const DetailedStatus: React.FC<{ to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/favourites`} className='detailed-status__link' > - - - - ), - }} - /> + {isRedesignEnabled() ? ( + + + + ), + }} + /> + ) : ( + + + + ), + }} + /> + )} ); diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index b120c64dc3f..c786179c236 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -319,6 +319,7 @@ "annual_report.summary.followers.new_followers": "{count, plural, one {new follower} other {new followers}}", "annual_report.summary.highlighted_post.boost_count": "This post was boosted {count, plural, one {once} other {# times}}.", "annual_report.summary.highlighted_post.favourite_count": "This post was favorited {count, plural, one {once} other {# times}}.", + "annual_report.summary.highlighted_post.like_count": "This post was liked {count, plural, one {once} other {# times}}.", "annual_report.summary.highlighted_post.reply_count": "This post got {count, plural, one {one reply} other {# replies}}.", "annual_report.summary.highlighted_post.title": "Most popular post", "annual_report.summary.most_used_app.most_used_app": "most used app", @@ -786,6 +787,8 @@ "empty_column.followed_tags": "You have not followed any hashtags yet. When you do, they will show up here.", "empty_column.hashtag": "There is nothing in this hashtag yet.", "empty_column.home": "Your home timeline is empty! Follow more people to fill it up.", + "empty_column.liked_posts": "You don't have any liked posts yet. When you like one, it will show up here.", + "empty_column.likes": "No one has liked this post yet. When someone does, they will show up here.", "empty_column.list": "There is nothing in this list yet. When members of this list publish new posts, they will appear here.", "empty_column.mutes": "You haven't muted any users yet.", "empty_column.notification_requests": "All clear! There is nothing here. When you receive new notifications, they will appear here according to your settings.", @@ -956,6 +959,8 @@ "keyboard_shortcuts.keys.page_down": "Page Down", "keyboard_shortcuts.keys.page_up": "Page Up", "keyboard_shortcuts.legend": "Display this legend", + "keyboard_shortcuts.like": "Like post", + "keyboard_shortcuts.liked_posts": "Open liked posts", "keyboard_shortcuts.load_more": "Focus \"Load more\" button", "keyboard_shortcuts.local": "Open local timeline", "keyboard_shortcuts.mention": "Mention author", @@ -1093,6 +1098,10 @@ "notification.label.private_reply": "Private reply", "notification.label.quote": "{name} quoted your post", "notification.label.reply": "Reply", + "notification.like": "{name} liked your post", + "notification.like.name_and_others_with_link": "{name} and {count, plural, one {# other} other {# others}} liked your post", + "notification.like_message": "{name} liked your message", + "notification.like_message.name_and_others_with_link": "{name} and {count, plural, one {# other} other {# others}} liked your message", "notification.mention": "Mention", "notification.mentioned_you": "{name} mentioned you", "notification.moderation-warning.learn_more": "Learn more", @@ -1401,6 +1410,7 @@ "status.header.to_followers": "{author} to Followers {count, plural, =0 {} one {+ # other} other {+ # others}}", "status.history.created": "{name} created {date}", "status.history.edited": "{name} edited {date}", + "status.like": "Like", "status.likes_count": "{count, plural, one {{counter} like} other {{counter} likes}}", "status.likes_title": "Post Likes", "status.link_preview.authors": "{count, plural, one {Find the author in the Fediverse:} other {Find the authors in the Fediverse:}}", @@ -1450,6 +1460,7 @@ "status.redraft": "Delete & re-draft", "status.remove_bookmark": "Remove bookmark", "status.remove_favourite": "Remove from favorites", + "status.remove_from_saved": "Remove from Saved", "status.remove_quote": "Remove", "status.replied_in_thread": "Replied in thread", "status.replied_to": "Replied to {name}", @@ -1459,6 +1470,7 @@ "status.report": "Report @{name}", "status.request_quote": "Request to quote", "status.revoke_quote": "Remove my post from @{name}’s post", + "status.save": "Save", "status.sensitive_warning": "Sensitive content", "status.share": "Share", "status.show_less_all": "Show less for all", @@ -1472,6 +1484,7 @@ "status.translate": "Translate", "status.translated_from_with": "Translated from {lang} using {provider}", "status.uncached_media_warning": "Preview not available", + "status.unlike": "Unlike", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", "status.view_post": "View full post",