diff --git a/app/javascript/mastodon/api_types/accounts.ts b/app/javascript/mastodon/api_types/accounts.ts index a9464b1a47..4a82a3548d 100644 --- a/app/javascript/mastodon/api_types/accounts.ts +++ b/app/javascript/mastodon/api_types/accounts.ts @@ -29,6 +29,7 @@ export interface ApiAccountOtherSettingsJSON { | 'mutuals_only' | 'block'; subscription_policy: 'allow' | 'followers_only' | 'block'; + bluesky: boolean; } export interface ApiServerFeaturesJSON { diff --git a/app/javascript/mastodon/features/account/components/bluesky_pill.jsx b/app/javascript/mastodon/features/account/components/bluesky_pill.jsx new file mode 100644 index 0000000000..dabbf61c68 --- /dev/null +++ b/app/javascript/mastodon/features/account/components/bluesky_pill.jsx @@ -0,0 +1,61 @@ +import PropTypes from 'prop-types'; +import { useState, useRef, useCallback } from 'react'; + +import { FormattedMessage } from 'react-intl'; + + +import classNames from 'classnames'; + +import Overlay from 'react-overlays/Overlay'; + +import BadgeIcon from '@/material-icons/400-24px/badge.svg?react'; +import { Button } from 'mastodon/components/button'; +import { Icon } from 'mastodon/components/icon'; + +export const BlueskyPill = ({ domain, username, isSelf }) => { + const [open, setOpen] = useState(false); + const triggerRef = useRef(null); + + const handleClick = useCallback(() => { + setOpen(!open); + }, [open, setOpen]); + + const handleBlueskyProfileOpenClick = useCallback(() => { + window.open(`https://bsky.app/profile/${replacedUsername}.${replacedDomain}.ap.brid.gy`, '_blank'); + }); + + const replacedUsername = username.replaceAll('_', '-'); + const replacedDomain = domain.replaceAll('_', '-'); + + return ( + <> + bluesky + + + {({ props }) => ( + + + + + + + + {isSelf ? : } + @{replacedUsername}.{replacedDomain}.ap.brid.gy + + + {isSelf ? : } + + + + )} + + > + ); +}; + +BlueskyPill.propTypes = { + username: PropTypes.string.isRequired, + domain: PropTypes.string.isRequired, + isSelf: PropTypes.bool, +}; diff --git a/app/javascript/mastodon/features/account/components/header.jsx b/app/javascript/mastodon/features/account/components/header.jsx index f2fb646df8..132ebb838e 100644 --- a/app/javascript/mastodon/features/account/components/header.jsx +++ b/app/javascript/mastodon/features/account/components/header.jsx @@ -34,6 +34,7 @@ import { WithRouterPropTypes } from 'mastodon/utils/react_router'; import AccountNoteContainer from '../containers/account_note_container'; import FollowRequestNoteContainer from '../containers/follow_request_note_container'; +import { BlueskyPill } from './bluesky_pill'; import { DomainPill } from './domain_pill'; const messages = defineMessages({ @@ -468,6 +469,7 @@ class Header extends ImmutablePureComponent { @{username}@{domain} + {account.getIn(['other_settings', 'bluesky']) && } {lockedIcon} diff --git a/app/javascript/mastodon/models/account.ts b/app/javascript/mastodon/models/account.ts index 6681b9df12..4a9bba4c26 100644 --- a/app/javascript/mastodon/models/account.ts +++ b/app/javascript/mastodon/models/account.ts @@ -60,6 +60,7 @@ const AccountOtherSettingsFactory = ImmutableRecord({ allow_quote: true, emoji_reaction_policy: 'allow', subscription_policy: 'allow', + bluesky: false, }); // ServerFeatures diff --git a/app/models/concerns/account/interactions.rb b/app/models/concerns/account/interactions.rb index 979b2278dc..2566b7ea39 100644 --- a/app/models/concerns/account/interactions.rb +++ b/app/models/concerns/account/interactions.rb @@ -220,6 +220,11 @@ module Account::Interactions following?(other_account) && followed_by?(other_account) end + def bluesky_connected? + bridge_account = Account.find_by(domain: 'bsky.brid.gy', username: 'bsky.brid.gy') + bridge_account && followed_by?(bridge_account) + end + def blocking?(other_account) block_relationships.exists?(target_account: other_account) end diff --git a/app/models/concerns/account/other_settings.rb b/app/models/concerns/account/other_settings.rb index 7968f857ff..24b343ea48 100644 --- a/app/models/concerns/account/other_settings.rb +++ b/app/models/concerns/account/other_settings.rb @@ -79,6 +79,13 @@ module Account::OtherSettings show_emoji_reaction?(account) end + def bluesky_enabled? + return bluesky_connected? if local? && !suspended? + return settings['bluesky'] if settings.present? && settings.key?('bluesky') + + false + end + def public_settings # Please update `app/javascript/mastodon/api_types/accounts.ts` when making changes to the attributes { @@ -90,6 +97,7 @@ module Account::OtherSettings 'translatable_private' => translatable_private?, 'allow_quote' => allow_quote?, 'emoji_reaction_policy' => Setting.enable_emoji_reaction ? emoji_reaction_policy.to_s : 'block', + 'bluesky' => bluesky_enabled?, } end
{isSelf ? : }