Skip to content

Commit

Permalink
Fix history handling not properly handling states after update to rea…
Browse files Browse the repository at this point in the history
…ct-router v5 (mastodon#27526)
  • Loading branch information
ClearlyClaire authored Oct 24, 2023
1 parent 6cf9f12 commit 15182d1
Showing 1 changed file with 43 additions and 23 deletions.
66 changes: 43 additions & 23 deletions app/javascript/mastodon/components/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import React from 'react';

import { Router as OriginalRouter } from 'react-router';

import type { LocationDescriptor, Path } from 'history';
import type {
LocationDescriptor,
LocationDescriptorObject,
Path,
} from 'history';
import { createBrowserHistory } from 'history';

import { layoutFromWindow } from 'mastodon/is_mobile';
Expand All @@ -20,39 +24,55 @@ const browserHistory = createBrowserHistory<
const originalPush = browserHistory.push.bind(browserHistory);
const originalReplace = browserHistory.replace.bind(browserHistory);

function extractRealPath(path: HistoryPath) {
if (typeof path === 'string') return path;
else return path.pathname;
function normalizePath(
path: HistoryPath,
state?: MastodonLocationState,
): LocationDescriptorObject<MastodonLocationState> {
const location = typeof path === 'string' ? { pathname: path } : { ...path };

if (location.state === undefined && state !== undefined) {
location.state = state;
} else if (
location.state !== undefined &&
state !== undefined &&
process.env.NODE_ENV === 'development'
) {
// eslint-disable-next-line no-console
console.log(
'You should avoid providing a 2nd state argument to push when the 1st argument is a location-like object that already has state; it is ignored',
);
}

if (
layoutFromWindow() === 'multi-column' &&
!location.pathname?.startsWith('/deck')
) {
location.pathname = `/deck${location.pathname}`;
}

return location;
}

browserHistory.push = (path: HistoryPath, state?: MastodonLocationState) => {
state = state ?? {};
state.fromMastodon = true;
const location = normalizePath(path, state);

const realPath = extractRealPath(path);
if (!realPath) return;
location.state = location.state ?? {};
location.state.fromMastodon = true;

if (layoutFromWindow() === 'multi-column' && !realPath.startsWith('/deck')) {
originalPush(`/deck${realPath}`, state);
} else {
originalPush(path, state);
}
originalPush(location);
};

browserHistory.replace = (path: HistoryPath, state?: MastodonLocationState) => {
if (browserHistory.location.state?.fromMastodon) {
state = state ?? {};
state.fromMastodon = true;
}
const location = normalizePath(path, state);

const realPath = extractRealPath(path);
if (!realPath) return;
if (!location.pathname) return;

if (layoutFromWindow() === 'multi-column' && !realPath.startsWith('/deck')) {
originalReplace(`/deck${realPath}`, state);
} else {
originalReplace(path, state);
if (browserHistory.location.state?.fromMastodon) {
location.state = location.state ?? {};
location.state.fromMastodon = true;
}

originalReplace(location);
};

export const Router: React.FC<PropsWithChildren> = ({ children }) => {
Expand Down

0 comments on commit 15182d1

Please sign in to comment.