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 && (
+
+
+
+ )}