diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index f63a3ebf39..c3c41f3c5d 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config --auto-gen-only-exclude --no-offense-counts --no-auto-gen-timestamp` -# using RuboCop version 1.75.1. +# using RuboCop version 1.75.2. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -58,12 +58,6 @@ Style/FormatStringToken: Style/GuardClause: Enabled: false -# This cop supports unsafe autocorrection (--autocorrect-all). -Style/HashTransformValues: - Exclude: - - 'app/serializers/rest/web_push_subscription_serializer.rb' - - 'app/services/import_service.rb' - # Configuration parameters: AllowedMethods. # AllowedMethods: respond_to_missing? Style/OptionalBooleanParameter: diff --git a/Gemfile.lock b/Gemfile.lock index 86cfaa3132..1ed4b71318 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -201,7 +201,7 @@ GEM domain_name (0.6.20240107) doorkeeper (5.8.2) railties (>= 5) - dotenv (3.1.7) + dotenv (3.1.8) drb (2.2.1) elasticsearch (7.17.11) elasticsearch-api (= 7.17.11) diff --git a/app/javascript/mastodon/components/account.tsx b/app/javascript/mastodon/components/account.tsx index 55f1e6fb91..f6241504f6 100644 --- a/app/javascript/mastodon/components/account.tsx +++ b/app/javascript/mastodon/components/account.tsx @@ -1,4 +1,4 @@ -import { useCallback } from 'react'; +import { useCallback, useMemo } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; @@ -12,6 +12,7 @@ import { muteAccount, unmuteAccount, } from 'mastodon/actions/accounts'; +import { openModal } from 'mastodon/actions/modal'; import { initMuteModal } from 'mastodon/actions/mutes'; import { Avatar } from 'mastodon/components/avatar'; import { Button } from 'mastodon/components/button'; @@ -23,7 +24,7 @@ import { RelativeTimestamp } from 'mastodon/components/relative_timestamp'; import { ShortNumber } from 'mastodon/components/short_number'; import { Skeleton } from 'mastodon/components/skeleton'; import { VerifiedBadge } from 'mastodon/components/verified_badge'; -import { me } from 'mastodon/initial_state'; +import type { MenuItem } from 'mastodon/models/dropdown_menu'; import { useAppSelector, useAppDispatch } from 'mastodon/store'; const messages = defineMessages({ @@ -46,6 +47,14 @@ const messages = defineMessages({ mute: { id: 'account.mute_short', defaultMessage: 'Mute' }, block: { id: 'account.block_short', defaultMessage: 'Block' }, more: { id: 'status.more', defaultMessage: 'More' }, + addToLists: { + id: 'account.add_or_remove_from_list', + defaultMessage: 'Add or Remove from lists', + }, + openOriginalPage: { + id: 'account.open_original_page', + defaultMessage: 'Open original page', + }, }); export const Account: React.FC<{ @@ -60,6 +69,7 @@ export const Account: React.FC<{ const account = useAppSelector((state) => state.accounts.get(id)); const relationship = useAppSelector((state) => state.relationships.get(id)); const dispatch = useAppDispatch(); + const accountUrl = account?.url; const handleBlock = useCallback(() => { if (relationship?.blocking) { @@ -77,13 +87,62 @@ export const Account: React.FC<{ } }, [dispatch, id, account, relationship]); - const handleMuteNotifications = useCallback(() => { - dispatch(muteAccount(id, true)); - }, [dispatch, id]); + const menu = useMemo(() => { + let arr: MenuItem[] = []; - const handleUnmuteNotifications = useCallback(() => { - dispatch(muteAccount(id, false)); - }, [dispatch, id]); + if (defaultAction === 'mute') { + const handleMuteNotifications = () => { + dispatch(muteAccount(id, true)); + }; + + const handleUnmuteNotifications = () => { + dispatch(muteAccount(id, false)); + }; + + arr = [ + { + text: intl.formatMessage( + relationship?.muting_notifications + ? messages.unmute_notifications + : messages.mute_notifications, + ), + action: relationship?.muting_notifications + ? handleUnmuteNotifications + : handleMuteNotifications, + }, + ]; + } else if (defaultAction !== 'block') { + const handleAddToLists = () => { + dispatch( + openModal({ + modalType: 'LIST_ADDER', + modalProps: { + accountId: id, + }, + }), + ); + }; + + arr = [ + { + text: intl.formatMessage(messages.addToLists), + action: handleAddToLists, + }, + ]; + + if (accountUrl) { + arr.unshift( + { + text: intl.formatMessage(messages.openOriginalPage), + href: accountUrl, + }, + null, + ); + } + } + + return arr; + }, [dispatch, intl, id, accountUrl, relationship, defaultAction]); if (hidden) { return ( @@ -94,68 +153,42 @@ export const Account: React.FC<{ ); } - let buttons; + let button: React.ReactNode, dropdown: React.ReactNode; - if (account && account.id !== me && relationship) { - const { requested, blocking, muting } = relationship; - - if (requested) { - buttons = ; - } else if (blocking) { - buttons = ( -