@@ -40,9 +50,12 @@ export const EmbeddedStatus: React.FC<{ statusId: string }> = ({
-
{(poll || mediaAttachmentsSize > 0) && (
diff --git a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx
new file mode 100644
index 0000000000..4e47205e81
--- /dev/null
+++ b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx
@@ -0,0 +1,144 @@
+import { useCallback, useRef } from 'react';
+import { useHistory } from 'react-router-dom';
+
+const handleMentionClick = (history: unknown, mention: unknown, e: Event) => {
+ if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
+ e.preventDefault();
+ history.push(`/@${mention.get('acct')}`);
+ }
+};
+
+const handleHashtagClick = (history: unknown, hashtag: string, e: Event) => {
+ if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
+ e.preventDefault();
+ history.push(`/tags/${hashtag.replace(/^#/, '')}`);
+ }
+};
+
+export const EmbeddedStatusContent: React.FC<{
+ content: string;
+ mentions: unknown;
+ language: string;
+ onClick?: unknown;
+ className?: string;
+}> = ({ content, mentions, language, onClick, className }) => {
+ const clickCoordinatesRef = useRef();
+ const history = useHistory();
+
+ const handleMouseDown = useCallback(
+ ({ clientX, clientY }) => {
+ clickCoordinatesRef.current = [clientX, clientY];
+ },
+ [clickCoordinatesRef],
+ );
+
+ const handleMouseUp = useCallback(
+ ({ clientX, clientY, target, button }) => {
+ const [startX, startY] = clickCoordinatesRef.current ?? [0, 0];
+ const [deltaX, deltaY] = [
+ Math.abs(clientX - startX),
+ Math.abs(clientY - startY),
+ ];
+
+ let element = target;
+
+ while (element) {
+ if (
+ element.localName === 'button' ||
+ element.localName === 'a' ||
+ element.localName === 'label'
+ ) {
+ return;
+ }
+
+ element = element.parentNode;
+ }
+
+ if (deltaX + deltaY < 5 && button === 0 && onClick) {
+ onClick();
+ }
+
+ clickCoordinatesRef.current = null;
+ },
+ [clickCoordinatesRef, onClick],
+ );
+
+ const handleMouseEnter = useCallback(({ currentTarget }) => {
+ const emojis = currentTarget.querySelectorAll('.custom-emoji');
+
+ for (const emoji of emojis) {
+ emoji.src = emoji.getAttribute('data-original');
+ }
+ }, []);
+
+ const handleMouseLeave = useCallback(({ currentTarget }) => {
+ const emojis = currentTarget.querySelectorAll('.custom-emoji');
+
+ for (const emoji of emojis) {
+ emoji.src = emoji.getAttribute('data-static');
+ }
+ }, []);
+
+ const handleContentRef = useCallback(
+ (node) => {
+ if (!node) {
+ return;
+ }
+
+ const links = node.querySelectorAll('a');
+
+ for (const link of links) {
+ if (link.classList.contains('status-link')) {
+ continue;
+ }
+
+ link.classList.add('status-link');
+
+ const mention = mentions.find((item) => link.href === item.get('url'));
+
+ if (mention) {
+ link.addEventListener(
+ 'click',
+ handleMentionClick.bind(null, history, mention),
+ false,
+ );
+ link.setAttribute('title', `@${mention.get('acct')}`);
+ link.setAttribute('href', `/@${mention.get('acct')}`);
+ } else if (
+ link.textContent[0] === '#' ||
+ (link.previousSibling &&
+ link.previousSibling.textContent &&
+ link.previousSibling.textContent[
+ link.previousSibling.textContent.length - 1
+ ] === '#')
+ ) {
+ link.addEventListener(
+ 'click',
+ handleHashtagClick.bind(null, history, link.text),
+ false,
+ );
+ link.setAttribute('href', `/tags/${link.text.replace(/^#/, '')}`);
+ } else {
+ link.setAttribute('title', link.href);
+ link.classList.add('unhandled-link');
+ }
+ }
+ },
+ [mentions, history],
+ );
+
+ return (
+
+ );
+};
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index 3435d6223b..f0ad6f1551 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -671,9 +671,13 @@
"report.unfollow_explanation": "You are following this account. To not see their posts in your home feed anymore, unfollow them.",
"report_notification.attached_statuses": "{count, plural, one {{count} post} other {{count} posts}} attached",
"report_notification.categories.legal": "Legal",
+ "report_notification.categories.legal_sentence": "illegal content",
"report_notification.categories.other": "Other",
+ "report_notification.categories.other_sentence": "other",
"report_notification.categories.spam": "Spam",
+ "report_notification.categories.spam_sentence": "spam",
"report_notification.categories.violation": "Rule violation",
+ "report_notification.categories.violation_sentence": "rule violation",
"report_notification.open": "Open report",
"search.no_recent_searches": "No recent searches",
"search.placeholder": "Search",
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 5d69374db5..184d1fc29a 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -10355,8 +10355,8 @@ noscript {
}
}
- &__follow &__icon,
- &__follow-request &__icon {
+ &--follow &__icon,
+ &--follow-request &__icon {
color: $highlight-text-color;
}
@@ -10447,9 +10447,15 @@ noscript {
}
&__content {
+ display: -webkit-box;
font-size: 15px;
line-height: 22px;
color: $dark-text-color;
+ cursor: pointer;
+ -webkit-line-clamp: 4;
+ -webkit-box-orient: vertical;
+ max-height: 4 * 22px;
+ overflow: hidden;
p,
a {