2023-07-13 17:18:09 +02:00
|
|
|
import type { PropsWithChildren } from 'react';
|
|
|
|
import React from 'react';
|
|
|
|
|
|
|
|
import { Router as OriginalRouter } from 'react-router';
|
|
|
|
|
2023-10-24 15:24:57 +02:00
|
|
|
import type {
|
|
|
|
LocationDescriptor,
|
|
|
|
LocationDescriptorObject,
|
|
|
|
Path,
|
|
|
|
} from 'history';
|
2023-10-19 19:44:55 +02:00
|
|
|
import { createBrowserHistory } from 'history';
|
|
|
|
|
2023-07-13 17:18:09 +02:00
|
|
|
import { layoutFromWindow } from 'flavours/glitch/is_mobile';
|
|
|
|
|
2023-07-17 17:32:46 +02:00
|
|
|
interface MastodonLocationState {
|
|
|
|
fromMastodon?: boolean;
|
|
|
|
mastodonModalKey?: string;
|
|
|
|
}
|
2023-10-19 19:44:55 +02:00
|
|
|
type HistoryPath = Path | LocationDescriptor<MastodonLocationState>;
|
2023-07-17 17:32:46 +02:00
|
|
|
|
|
|
|
const browserHistory = createBrowserHistory<
|
|
|
|
MastodonLocationState | undefined
|
|
|
|
>();
|
2023-07-13 17:18:09 +02:00
|
|
|
const originalPush = browserHistory.push.bind(browserHistory);
|
2023-07-17 17:32:46 +02:00
|
|
|
const originalReplace = browserHistory.replace.bind(browserHistory);
|
|
|
|
|
2023-10-24 15:24:57 +02:00
|
|
|
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;
|
2023-10-19 19:44:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
browserHistory.push = (path: HistoryPath, state?: MastodonLocationState) => {
|
2023-10-24 15:24:57 +02:00
|
|
|
const location = normalizePath(path, state);
|
2023-07-13 17:18:09 +02:00
|
|
|
|
2023-10-24 15:24:57 +02:00
|
|
|
location.state = location.state ?? {};
|
|
|
|
location.state.fromMastodon = true;
|
2023-10-19 19:44:55 +02:00
|
|
|
|
2023-10-24 15:24:57 +02:00
|
|
|
originalPush(location);
|
2023-07-13 17:18:09 +02:00
|
|
|
};
|
|
|
|
|
2023-10-19 19:44:55 +02:00
|
|
|
browserHistory.replace = (path: HistoryPath, state?: MastodonLocationState) => {
|
2023-10-24 15:24:57 +02:00
|
|
|
const location = normalizePath(path, state);
|
2023-07-17 17:32:46 +02:00
|
|
|
|
2023-10-24 15:24:57 +02:00
|
|
|
if (!location.pathname) return;
|
2023-10-19 19:44:55 +02:00
|
|
|
|
2023-10-24 15:24:57 +02:00
|
|
|
if (browserHistory.location.state?.fromMastodon) {
|
|
|
|
location.state = location.state ?? {};
|
|
|
|
location.state.fromMastodon = true;
|
2023-07-17 17:32:46 +02:00
|
|
|
}
|
2023-10-24 15:24:57 +02:00
|
|
|
|
|
|
|
originalReplace(location);
|
2023-07-17 17:32:46 +02:00
|
|
|
};
|
|
|
|
|
2023-07-13 17:18:09 +02:00
|
|
|
export const Router: React.FC<PropsWithChildren> = ({ children }) => {
|
|
|
|
return <OriginalRouter history={browserHistory}>{children}</OriginalRouter>;
|
|
|
|
};
|