From cdb26a40d42c324b7df9bfcc18e2b8988159e671 Mon Sep 17 00:00:00 2001
From: diondiondion
Date: Fri, 18 Sep 2026 14:25:54 +0000
Subject: [PATCH] Redesign: Re-add navigation callouts for forced-single-column
mode and moved account (#40589)
---
.../components/callout/redesign.module.scss | 10 ++
.../navigation_panel/redesign/index.tsx | 32 +++-
.../redesign/list_section.module.scss | 5 +
.../redesign/logged_out_info.tsx | 150 ++++++++++++++----
.../redesign/styles.module.scss | 4 +
app/javascript/mastodon/locales/en.json | 1 +
6 files changed, 173 insertions(+), 29 deletions(-)
diff --git a/app/javascript/mastodon/components/callout/redesign.module.scss b/app/javascript/mastodon/components/callout/redesign.module.scss
index e0dbbb3daf3..a1100584697 100644
--- a/app/javascript/mastodon/components/callout/redesign.module.scss
+++ b/app/javascript/mastodon/components/callout/redesign.module.scss
@@ -3,6 +3,7 @@
.rootLarge,
.rootSmall {
align-items: center;
+ color: var(--color-text-primary);
background-color: var(--color-bg-highlight);
border-radius: var(--radius-3);
box-sizing: border-box;
@@ -20,6 +21,15 @@
.textWrapper {
flex-grow: 1;
+
+ a {
+ color: inherit;
+
+ &:hover,
+ &:focus-visible {
+ text-decoration: none;
+ }
+ }
}
.icon {
diff --git a/app/javascript/mastodon/features/navigation_panel/redesign/index.tsx b/app/javascript/mastodon/features/navigation_panel/redesign/index.tsx
index 6cd61227cd2..de5e5da5d02 100644
--- a/app/javascript/mastodon/features/navigation_panel/redesign/index.tsx
+++ b/app/javascript/mastodon/features/navigation_panel/redesign/index.tsx
@@ -19,9 +19,12 @@ import FediIcon from '@/images/icons/icon_fediverse.svg?react';
import { fetchLists } from '@/mastodon/actions/lists';
import { closeNavigation } from '@/mastodon/actions/navigation';
import { fetchFollowedHashtags } from '@/mastodon/actions/tags_typed';
+import { Callout } from '@/mastodon/components/callout/redesign';
import { FOCUS_TARGET } from '@/mastodon/components/navigation_focus_target';
import { useScrollSensor } from '@/mastodon/hooks/useScrollSensor';
import { useIdentity } from '@/mastodon/identity_context';
+import { disabledAccountId } from '@/mastodon/initial_state';
+import { transientSingleColumn } from '@/mastodon/is_mobile';
import { openNewComposer } from '@/mastodon/reducers/slices/composer';
import { getOrderedLists } from '@/mastodon/selectors/lists';
import { selectUnreadNotificationGroupsCount } from '@/mastodon/selectors/notifications';
@@ -31,7 +34,7 @@ import { NavigationAccountCardAndMenu } from './account_card_and_menu';
import { NavigationFooterLinks } from './footer_links';
import { NavigationHeader } from './header';
import { ListSection } from './list_section';
-import { LoggedOutInfo } from './logged_out_info';
+import { DisabledAccountBanner, LoggedOutInfo } from './logged_out_info';
import { NavigationLink } from './navigation_link';
import classes from './styles.module.scss';
@@ -74,6 +77,13 @@ function useFollowedHashtags() {
return { followedHashtags: tags };
}
+const isFediverseFeedsLinkActive = (
+ match: unknown,
+ { pathname }: { pathname: string },
+) => {
+ return !!match || pathname.startsWith('/public');
+};
+
const MAX_HASHTAG_COUNT = 5;
export const RedesignNavigationPanel: React.FC<{
@@ -121,6 +131,7 @@ export const RedesignNavigationPanel: React.FC<{
{signedIn && (
<>
+ {transientSingleColumn && }
-
+ {disabledAccountId ? : }
);
};
+
+const TransientSingleColumnCallout: React.FC = () => (
+
+
+
+
+
+
+
+);
diff --git a/app/javascript/mastodon/features/navigation_panel/redesign/list_section.module.scss b/app/javascript/mastodon/features/navigation_panel/redesign/list_section.module.scss
index abc82c9e391..c528a5b0a5c 100644
--- a/app/javascript/mastodon/features/navigation_panel/redesign/list_section.module.scss
+++ b/app/javascript/mastodon/features/navigation_panel/redesign/list_section.module.scss
@@ -1,4 +1,5 @@
@use '@/styles/mastodon/mixins';
+@use '@/styles/mastodon/variables';
@use './navigation_link.module.scss' as navigation-link;
.root {
@@ -26,6 +27,10 @@
@include mixins.type-meta;
color: var(--color-text-secondary);
+
+ @media (width < variables.$mobile-menu-breakpoint) {
+ min-height: 40px;
+ }
}
.toggleIcon {
diff --git a/app/javascript/mastodon/features/navigation_panel/redesign/logged_out_info.tsx b/app/javascript/mastodon/features/navigation_panel/redesign/logged_out_info.tsx
index 289e5ac40b7..acde1ec3512 100644
--- a/app/javascript/mastodon/features/navigation_panel/redesign/logged_out_info.tsx
+++ b/app/javascript/mastodon/features/navigation_panel/redesign/logged_out_info.tsx
@@ -1,14 +1,48 @@
-import { useEffect } from 'react';
+import { useCallback, useEffect } from 'react';
import { FormattedMessage } from 'react-intl';
+import { Link } from 'react-router-dom';
+
+import { WarningIcon } from '@phosphor-icons/react';
+
+import { openModal } from '@/mastodon/actions/modal';
import { fetchServer } from '@/mastodon/actions/server';
import { Button } from '@/mastodon/components/button/redesign';
+import { Callout } from '@/mastodon/components/callout/redesign';
import { Skeleton } from '@/mastodon/components/skeleton';
+import {
+ disabledAccountId,
+ domain,
+ movedToAccountId,
+} from '@/mastodon/initial_state';
import { useAppDispatch, useAppSelector } from '@/mastodon/store';
import classes from './logged_out_info.module.scss';
+const NavigationFooterLayout: React.FC<{
+ isLoading?: boolean;
+ description: React.ReactNode;
+ children: React.ReactNode;
+}> = ({ description, isLoading, children }) => (
+ <>
+
+ {isLoading ? (
+ <>
+
+
+
+
+
+ >
+ ) : (
+ description
+ )}
+
+ {children}
+ >
+);
+
export const LoggedOutInfo: React.FC = () => {
const dispatch = useAppDispatch();
const { item: serverItem, isLoading } = useAppSelector(
@@ -20,31 +54,93 @@ export const LoggedOutInfo: React.FC = () => {
}, [dispatch]);
return (
- <>
-
- {isLoading ? (
- <>
-
-
-
-
-
- >
- ) : (
- serverItem?.description
- )}
-
-
-
-
-
- >
+ {serverItem?.description ?? ''}
}
+ isLoading={isLoading}
+ >
+
+
+
+ );
+};
+
+export const DisabledAccountBanner: React.FC = () => {
+ const disabledAccount = useAppSelector((state) =>
+ disabledAccountId ? state.accounts.get(disabledAccountId) : undefined,
+ );
+ const movedToAccount = useAppSelector((state) =>
+ movedToAccountId ? state.accounts.get(movedToAccountId) : undefined,
+ );
+ const dispatch = useAppDispatch();
+
+ const handleLogOutClick = useCallback(
+ (e: React.MouseEvent) => {
+ e.preventDefault();
+ e.stopPropagation();
+
+ dispatch(openModal({ modalType: 'CONFIRM_LOG_OUT', modalProps: {} }));
+
+ return false;
+ },
+ [dispatch],
+ );
+
+ const disabledAccountLink = (
+
+ {disabledAccount?.acct}@{domain}
+
+ );
+
+ return (
+
+ {movedToAccount ? (
+
+ {movedToAccount.acct.includes('@')
+ ? movedToAccount.acct
+ : `${movedToAccount.acct}@${domain}`}
+
+ ),
+ }}
+ />
+ ) : (
+
+ )}
+
+ }
+ >
+
+
+
);
};
diff --git a/app/javascript/mastodon/features/navigation_panel/redesign/styles.module.scss b/app/javascript/mastodon/features/navigation_panel/redesign/styles.module.scss
index 5e7d69d4f82..2e30383c0a8 100644
--- a/app/javascript/mastodon/features/navigation_panel/redesign/styles.module.scss
+++ b/app/javascript/mastodon/features/navigation_panel/redesign/styles.module.scss
@@ -54,3 +54,7 @@
gap: var(--space-1);
margin-bottom: var(--space-2);
}
+
+.callout {
+ margin-inline: var(--space-4);
+}
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index 6ceb41f94df..b3eaccd55b2 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -1048,6 +1048,7 @@
"navigation_bar.more": "More",
"navigation_bar.mutes": "Muted users",
"navigation_bar.opened_in_classic_interface": "Posts, accounts, and other specific pages are opened by default in the classic web interface.",
+ "navigation_bar.opened_in_single_column_layout": "Posts, profiles, and other pages are opened in the single-column layout by default.",
"navigation_bar.powered_by_mastodon": "powered by {logo}Mastodon",
"navigation_bar.preferences": "Preferences",
"navigation_bar.privacy_and_reach": "Privacy and reach",