diff --git a/.nvmrc b/.nvmrc index f1c8f6b0d0..6e77d0a749 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22.18 +22.19 diff --git a/Gemfile.lock b/Gemfile.lock index bc8b8396d3..93ed9eb601 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -172,7 +172,7 @@ GEM cocoon (1.2.15) color_diff (0.1) concurrent-ruby (1.3.5) - connection_pool (2.5.3) + connection_pool (2.5.4) cose (1.3.1) cbor (~> 0.5.9) openssl-signature_algorithm (~> 1.0) @@ -615,7 +615,7 @@ GEM parslet (2.0.0) pastel (0.8.0) tty-color (~> 0.5) - pg (1.6.1) + pg (1.6.2) pghero (3.7.0) activerecord (>= 7.1) playwright-ruby-client (1.54.1) diff --git a/app/controllers/settings/preferences/posting_defaults_controller.rb b/app/controllers/settings/preferences/posting_defaults_controller.rb new file mode 100644 index 0000000000..53fee0e5ca --- /dev/null +++ b/app/controllers/settings/preferences/posting_defaults_controller.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class Settings::Preferences::PostingDefaultsController < Settings::Preferences::BaseController + private + + def after_update_redirect_path + settings_preferences_posting_defaults_path + end +end diff --git a/app/javascript/mastodon/components/status/reblog_button.tsx b/app/javascript/mastodon/components/status/reblog_button.tsx index 864b0120e8..afc208e032 100644 --- a/app/javascript/mastodon/components/status/reblog_button.tsx +++ b/app/javascript/mastodon/components/status/reblog_button.tsx @@ -23,8 +23,8 @@ import { useAppSelector, } from '@/mastodon/store'; import { isFeatureEnabled } from '@/mastodon/utils/environment'; -import FormatQuote from '@/material-icons/400-24px/format_quote.svg?react'; -import FormatQuoteOff from '@/material-icons/400-24px/format_quote_off.svg?react'; +import FormatQuote from '@/material-icons/400-24px/format_quote-fill.svg?react'; +import FormatQuoteOff from '@/material-icons/400-24px/format_quote_off-fill.svg?react'; import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react'; import RepeatActiveIcon from '@/svg-icons/repeat_active.svg?react'; import RepeatDisabledIcon from '@/svg-icons/repeat_disabled.svg?react'; @@ -44,7 +44,7 @@ const messages = defineMessages({ quote: { id: 'status.quote', defaultMessage: 'Quote' }, quote_cannot: { id: 'status.cannot_quote', - defaultMessage: 'Author has disabled quoting on this post', + defaultMessage: 'Quotes are disabled on this post', }, quote_followers_only: { id: 'status.quote_followers_only', diff --git a/app/javascript/mastodon/features/notifications/components/notification.jsx b/app/javascript/mastodon/features/notifications/components/notification.jsx index 7f522b6392..7151f17100 100644 --- a/app/javascript/mastodon/features/notifications/components/notification.jsx +++ b/app/javascript/mastodon/features/notifications/components/notification.jsx @@ -10,7 +10,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import EditIcon from '@/material-icons/400-24px/edit.svg?react'; import FlagIcon from '@/material-icons/400-24px/flag-fill.svg?react'; -import FormatQuoteIcon from '@/material-icons/400-24px/format_quote.svg?react'; +import FormatQuoteIcon from '@/material-icons/400-24px/format_quote-fill.svg?react'; import HomeIcon from '@/material-icons/400-24px/home-fill.svg?react'; import InsertChartIcon from '@/material-icons/400-24px/insert_chart.svg?react'; import PersonIcon from '@/material-icons/400-24px/person-fill.svg?react'; diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_quote.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_quote.tsx index 595bed806c..9772966ad5 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/notification_quote.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_quote.tsx @@ -1,6 +1,6 @@ import { FormattedMessage } from 'react-intl'; -import FormatQuoteIcon from '@/material-icons/400-24px/format_quote.svg?react'; +import FormatQuoteIcon from '@/material-icons/400-24px/format_quote-fill.svg?react'; import type { NotificationGroupQuote } from 'mastodon/models/notification_group'; import type { LabelRenderer } from './notification_group_with_status'; diff --git a/app/javascript/mastodon/features/status/components/card.jsx b/app/javascript/mastodon/features/status/components/card.jsx index f8d5a26aff..308555b77f 100644 --- a/app/javascript/mastodon/features/status/components/card.jsx +++ b/app/javascript/mastodon/features/status/components/card.jsx @@ -37,18 +37,20 @@ const getHostname = url => { const domParser = new DOMParser(); -const addAutoPlay = html => { +const handleIframeUrl = (html, url, providerName) => { const document = domParser.parseFromString(html, 'text/html').documentElement; const iframe = document.querySelector('iframe'); + const startTime = new URL(url).searchParams.get('t') if (iframe) { - if (iframe.src.indexOf('?') !== -1) { - iframe.src += '&'; - } else { - iframe.src += '?'; - } + const iframeUrl = new URL(iframe.src) - iframe.src += 'autoplay=1&auto_play=1'; + iframeUrl.searchParams.set('autoplay', 1) + iframeUrl.searchParams.set('auto_play', 1) + + if (startTime && providerName === "YouTube") iframeUrl.searchParams.set('start', startTime) + + iframe.src = iframeUrl.href // DOM parser creates html/body elements around original HTML fragment, // so we need to get innerHTML out of the body and not the entire document @@ -114,7 +116,7 @@ export default class Card extends PureComponent { renderVideo () { const { card } = this.props; - const content = { __html: addAutoPlay(card.get('html')) }; + const content = { __html: handleIframeUrl(card.get('html'), card.get('url'), card.get('provider_name')) }; return (
state.statuses, + (_state, statusId?: string) => !!statusId, + (state) => state.compose.get('quoted_status_id') as string | null, + ], + (statuses, isEditing, statusId) => { + if (isEditing || !statusId) return false; + + const status = statuses.get(statusId); + if (!status) { + return false; + } + + return status.get('visibility') === 'private'; + }, +); + export const VisibilityModal: FC = forwardRef( // eslint-disable-next-line @typescript-eslint/no-unused-vars ({ onClose, onChange, statusId }, _ref) => { @@ -110,24 +128,12 @@ export const VisibilityModal: FC = forwardRef( const disableVisibility = !!statusId; const disableQuotePolicy = visibility === 'private' || visibility === 'direct'; + const disablePublicVisibilities: boolean = useAppSelector( + selectDisablePublicVisibilities, + ); - const visibilityItems = useMemo[]>( - () => [ - { - value: 'public', - text: intl.formatMessage(privacyMessages.public_short), - meta: intl.formatMessage(privacyMessages.public_long), - icon: 'globe', - iconComponent: PublicIcon, - }, - { - value: 'unlisted', - text: intl.formatMessage(privacyMessages.unlisted_short), - meta: intl.formatMessage(privacyMessages.unlisted_long), - extra: intl.formatMessage(privacyMessages.unlisted_extra), - icon: 'unlock', - iconComponent: QuietTimeIcon, - }, + const visibilityItems = useMemo[]>(() => { + const items: SelectItem[] = [ { value: 'private', text: intl.formatMessage(privacyMessages.private_short), @@ -142,9 +148,30 @@ export const VisibilityModal: FC = forwardRef( icon: 'at', iconComponent: AlternateEmailIcon, }, - ], - [intl], - ); + ]; + + if (!disablePublicVisibilities) { + items.unshift( + { + value: 'public', + text: intl.formatMessage(privacyMessages.public_short), + meta: intl.formatMessage(privacyMessages.public_long), + icon: 'globe', + iconComponent: PublicIcon, + }, + { + value: 'unlisted', + text: intl.formatMessage(privacyMessages.unlisted_short), + meta: intl.formatMessage(privacyMessages.unlisted_long), + extra: intl.formatMessage(privacyMessages.unlisted_extra), + icon: 'unlock', + iconComponent: QuietTimeIcon, + }, + ); + } + + return items; + }, [intl, disablePublicVisibilities]); const quoteItems = useMemo[]>( () => [ { value: 'public', text: intl.formatMessage(messages.quotePublic) }, @@ -198,10 +225,10 @@ export const VisibilityModal: FC = forwardRef(
( - {chunks} + {chunks} ), }} tagName='p' @@ -216,7 +243,7 @@ export const VisibilityModal: FC = forwardRef( > = forwardRef( />

)} + {!statusId && disablePublicVisibilities && ( +

+ +

+ )}