Fix history handling not properly handling states after update to react-router v5 (#27526)
parent
6cf9f1211b
commit
15182d1e5e
|
@ -3,7 +3,11 @@ import React from 'react';
|
||||||
|
|
||||||
import { Router as OriginalRouter } from 'react-router';
|
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 { createBrowserHistory } from 'history';
|
||||||
|
|
||||||
import { layoutFromWindow } from 'mastodon/is_mobile';
|
import { layoutFromWindow } from 'mastodon/is_mobile';
|
||||||
|
@ -20,39 +24,55 @@ const browserHistory = createBrowserHistory<
|
||||||
const originalPush = browserHistory.push.bind(browserHistory);
|
const originalPush = browserHistory.push.bind(browserHistory);
|
||||||
const originalReplace = browserHistory.replace.bind(browserHistory);
|
const originalReplace = browserHistory.replace.bind(browserHistory);
|
||||||
|
|
||||||
function extractRealPath(path: HistoryPath) {
|
function normalizePath(
|
||||||
if (typeof path === 'string') return path;
|
path: HistoryPath,
|
||||||
else return path.pathname;
|
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) => {
|
browserHistory.push = (path: HistoryPath, state?: MastodonLocationState) => {
|
||||||
state = state ?? {};
|
const location = normalizePath(path, state);
|
||||||
state.fromMastodon = true;
|
|
||||||
|
|
||||||
const realPath = extractRealPath(path);
|
location.state = location.state ?? {};
|
||||||
if (!realPath) return;
|
location.state.fromMastodon = true;
|
||||||
|
|
||||||
if (layoutFromWindow() === 'multi-column' && !realPath.startsWith('/deck')) {
|
originalPush(location);
|
||||||
originalPush(`/deck${realPath}`, state);
|
|
||||||
} else {
|
|
||||||
originalPush(path, state);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
browserHistory.replace = (path: HistoryPath, state?: MastodonLocationState) => {
|
browserHistory.replace = (path: HistoryPath, state?: MastodonLocationState) => {
|
||||||
|
const location = normalizePath(path, state);
|
||||||
|
|
||||||
|
if (!location.pathname) return;
|
||||||
|
|
||||||
if (browserHistory.location.state?.fromMastodon) {
|
if (browserHistory.location.state?.fromMastodon) {
|
||||||
state = state ?? {};
|
location.state = location.state ?? {};
|
||||||
state.fromMastodon = true;
|
location.state.fromMastodon = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const realPath = extractRealPath(path);
|
originalReplace(location);
|
||||||
if (!realPath) return;
|
|
||||||
|
|
||||||
if (layoutFromWindow() === 'multi-column' && !realPath.startsWith('/deck')) {
|
|
||||||
originalReplace(`/deck${realPath}`, state);
|
|
||||||
} else {
|
|
||||||
originalReplace(path, state);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Router: React.FC<PropsWithChildren> = ({ children }) => {
|
export const Router: React.FC<PropsWithChildren> = ({ children }) => {
|
||||||
|
|
Loading…
Reference in New Issue