diff --git a/app/javascript/mastodon/features/status/components/action_bar.jsx b/app/javascript/mastodon/features/status/components/action_bar.jsx
index dd2ea549b..50cfd4773 100644
--- a/app/javascript/mastodon/features/status/components/action_bar.jsx
+++ b/app/javascript/mastodon/features/status/components/action_bar.jsx
@@ -326,9 +326,6 @@ class ActionBar extends PureComponent {
const bookmarkTitle = intl.formatMessage(status.get('bookmarked') ? messages.removeBookmark : messages.bookmark);
const favouriteTitle = intl.formatMessage(status.get('favourited') ? messages.removeFavourite : messages.favourite);
- const bookmarkTitle = intl.formatMessage(status.get('bookmarked') ? messages.removeBookmark : messages.bookmark);
- const favouriteTitle = intl.formatMessage(status.get('favourited') ? messages.removeFavourite : messages.favourite);
-
return (
diff --git a/app/javascript/mastodon/features/ui/index.jsx b/app/javascript/mastodon/features/ui/index.jsx
index 8d2a2193e..4dded60e5 100644
--- a/app/javascript/mastodon/features/ui/index.jsx
+++ b/app/javascript/mastodon/features/ui/index.jsx
@@ -149,9 +149,8 @@ class SwitchingColumnsArea extends PureComponent {
redirect =
;
} else if (trendsEnabled && landingPage === 'trends') {
redirect =
;
- }
- // Hometown: if signed-out landing page is the about page, don't render the app shell, just redirect
} else if (window.location.pathname === '/' || window.location.pathname === '') {
+ // Hometown: if signed-out landing page is the about page, don't render the app shell, just redirect
window.location = '/about';
return null;
} else if (localLiveFeedAccess === 'public' && landingPage === 'local_feed') {
diff --git a/app/javascript/mastodon/hooks/useLinks.ts b/app/javascript/mastodon/hooks/useLinks.ts
deleted file mode 100644
index c99f3f419..000000000
--- a/app/javascript/mastodon/hooks/useLinks.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-import { useCallback } from 'react';
-
-import { useHistory } from 'react-router-dom';
-
-import { isFulfilled, isRejected } from '@reduxjs/toolkit';
-
-import { openURL } from 'mastodon/actions/search';
-import { useAppDispatch } from 'mastodon/store';
-
-const isMentionClick = (element: HTMLAnchorElement) =>
- element.classList.contains('mention');
-
-const isHashtagClick = (element: HTMLAnchorElement) =>
- element.textContent?.[0] === '#' ||
- element.previousSibling?.textContent?.endsWith('#');
-
-export const useLinks = () => {
- const history = useHistory();
- const dispatch = useAppDispatch();
-
- const handleHashtagClick = useCallback(
- (element: HTMLAnchorElement) => {
- const { textContent } = element;
-
- if (!textContent) return;
-
- history.push(`/tags/${textContent.replace(/^#/, '')}`);
- },
- [history],
- );
-
- const handleMentionClick = useCallback(
- async (element: HTMLAnchorElement) => {
- const result = await dispatch(openURL({ url: element.href }));
-
- if (isFulfilled(result)) {
- if (result.payload.accounts[0]) {
- history.push(`/@${result.payload.accounts[0].acct}`);
- } else if (result.payload.statuses[0]) {
- history.push(
- `/@${result.payload.statuses[0].account.acct}/${result.payload.statuses[0].id}`,
- );
- } else {
- window.location.href = element.href;
- }
- } else if (isRejected(result)) {
- window.location.href = element.href;
- }
- },
- [dispatch, history],
- );
-
- const handleClick = useCallback(
- (e: React.MouseEvent) => {
- const target = (e.target as HTMLElement).closest('a');
-
- if (!target || e.button !== 0 || e.ctrlKey || e.metaKey) {
- return;
- }
-
- if (isMentionClick(target)) {
- e.preventDefault();
- void handleMentionClick(target);
- } else if (isHashtagClick(target)) {
- e.preventDefault();
- handleHashtagClick(target);
- }
- },
- [handleMentionClick, handleHashtagClick],
- );
-
- return handleClick;
-};
diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js
deleted file mode 100644
index 8a57e1b77..000000000
--- a/app/javascript/mastodon/initial_state.js
+++ /dev/null
@@ -1,148 +0,0 @@
-// @ts-check
-
-
-/**
- * @typedef {[code: string, name: string, localName: string]} InitialStateLanguage
- */
-
-/**
- * @typedef InitialStateMeta
- * @property {string} access_token
- * @property {boolean=} advanced_layout
- * @property {boolean} auto_play_gif
- * @property {boolean} activity_api_enabled
- * @property {string} admin
- * @property {boolean=} boost_modal
- * @property {boolean=} delete_modal
- * @property {boolean=} missing_alt_text_modal
- * @property {boolean=} disable_swiping
- * @property {boolean=} disable_hover_cards
- * @property {string=} disabled_account_id
- * @property {string} display_media
- * @property {string} domain
- * @property {boolean=} expand_spoilers
- * @property {boolean=} expand_usernames
- * @property {boolean} limited_federation_mode
- * @property {string} locale
- * @property {string | null} mascot
- * @property {string=} me
- * @property {string=} moved_to_account_id
- * @property {string=} owner
- * @property {boolean} profile_directory
- * @property {boolean} registrations_open
- * @property {boolean} reduce_motion
- * @property {string} repository
- * @property {boolean} search_enabled
- * @property {boolean} trends_enabled
- * @property {boolean} single_user_mode
- * @property {string} source_url
- * @property {string} streaming_api_base_url
- * @property {boolean} timeline_preview
- * @property {string} title
- * @property {boolean} show_trends
- * @property {boolean} trends_as_landing_page
- * @property {boolean} use_blurhash
- * @property {boolean=} use_pending_items
- * @property {string} version
- * @property {string} sso_redirect
- * @property {string} status_page_url
- * @property {boolean} terms_of_service_enabled
- */
-
-/**
- * @typedef Role
- * @property {string} id
- * @property {string} name
- * @property {string} permissions
- * @property {string} color
- * @property {boolean} highlighted
- */
-
-/**
- * @typedef InitialState
- * @property {Record
} accounts
- * @property {InitialStateLanguage[]} languages
- * @property {boolean=} critical_updates_pending
- * @property {InitialStateMeta} meta
- * @property {number} max_toot_chars
- * @property {Role?} role
- */
-
-const element = document.getElementById('initial-state');
-/** @type {InitialState | undefined} */
-const initialState = element?.textContent && JSON.parse(element.textContent);
-
-/** @type {string} */
-const initialPath = document.querySelector("head meta[name=initialPath]")?.getAttribute("content") ?? '';
-/** @type {boolean} */
-export const hasMultiColumnPath = initialPath === '/'
- || initialPath === '/getting-started'
- || initialPath === '/home'
- || initialPath.startsWith('/deck');
-
-/**
- * @template {keyof InitialStateMeta} K
- * @param {K} prop
- * @returns {InitialStateMeta[K] | undefined}
- */
-const getMeta = (prop) => initialState?.meta && initialState.meta[prop];
-
-export const activityApiEnabled = getMeta('activity_api_enabled');
-export const autoPlayGif = getMeta('auto_play_gif');
-export const boostModal = getMeta('boost_modal');
-export const deleteModal = getMeta('delete_modal');
-export const maxChars = (initialState && initialState.max_toot_chars) || 500;
-export const missingAltTextModal = getMeta('missing_alt_text_modal');
-export const disableSwiping = getMeta('disable_swiping');
-export const disableHoverCards = getMeta('disable_hover_cards');
-export const disabledAccountId = getMeta('disabled_account_id');
-export const displayMedia = getMeta('display_media');
-export const domain = getMeta('domain');
-export const expandSpoilers = getMeta('expand_spoilers');
-// Hometown: expand usernames
-export const expandUsernames = getMeta('expand_usernames');
-export const forceSingleColumn = !getMeta('advanced_layout');
-export const limitedFederationMode = getMeta('limited_federation_mode');
-export const mascot = getMeta('mascot');
-export const me = getMeta('me');
-export const movedToAccountId = getMeta('moved_to_account_id');
-export const owner = getMeta('owner');
-export const profile_directory = getMeta('profile_directory');
-export const reduceMotion = getMeta('reduce_motion');
-export const registrationsOpen = getMeta('registrations_open');
-export const repository = getMeta('repository');
-export const searchEnabled = getMeta('search_enabled');
-export const trendsEnabled = getMeta('trends_enabled');
-export const showTrends = getMeta('show_trends');
-export const singleUserMode = getMeta('single_user_mode');
-export const source_url = getMeta('source_url');
-export const timelinePreview = getMeta('timeline_preview');
-export const title = getMeta('title');
-export const trendsAsLanding = getMeta('trends_as_landing_page');
-export const useBlurhash = getMeta('use_blurhash');
-export const usePendingItems = getMeta('use_pending_items');
-export const version = getMeta('version');
-export const criticalUpdatesPending = initialState?.critical_updates_pending;
-export const statusPageUrl = getMeta('status_page_url');
-export const sso_redirect = getMeta('sso_redirect');
-export const termsOfServiceEnabled = getMeta('terms_of_service_enabled');
-
-const displayNames = Intl.DisplayNames && new Intl.DisplayNames(getMeta('locale'), {
- type: 'language',
- fallback: 'none',
- languageDisplay: 'standard',
-});
-
-export const languages = initialState?.languages?.map(lang => {
- // zh-YUE is not a valid CLDR unicode_language_id
- return [lang[0], displayNames?.of(lang[0].replace('zh-YUE', 'yue')) || lang[1], lang[2]];
-});
-
-/**
- * @returns {string | undefined}
- */
-export function getAccessToken() {
- return getMeta('access_token');
-}
-
-export default initialState;
diff --git a/app/javascript/mastodon/performance.js b/app/javascript/mastodon/performance.js
deleted file mode 100644
index 1b2092cfc..000000000
--- a/app/javascript/mastodon/performance.js
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// Tools for performance debugging, only enabled in development mode.
-// Open up Chrome Dev Tools, then Timeline, then User Timing to see output.
-
-import * as marky from 'marky';
-
-import { isDevelopment } from './utils/environment';
-
-export function start(name) {
- if (isDevelopment()) {
- marky.mark(name);
- }
-}
-
-export function stop(name) {
- if (isDevelopment()) {
- marky.stop(name);
- }
-}