Fix history handling not properly handling states after update to react-router v5 (#27526)
This commit is contained in:
		
							parent
							
								
									6cf9f1211b
								
							
						
					
					
						commit
						15182d1e5e
					
				@ -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';
 | 
			
		||||
@ -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) => {
 | 
			
		||||
  const location = normalizePath(path, state);
 | 
			
		||||
 | 
			
		||||
  if (!location.pathname) return;
 | 
			
		||||
 | 
			
		||||
  if (browserHistory.location.state?.fromMastodon) {
 | 
			
		||||
    state = state ?? {};
 | 
			
		||||
    state.fromMastodon = true;
 | 
			
		||||
    location.state = location.state ?? {};
 | 
			
		||||
    location.state.fromMastodon = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const realPath = extractRealPath(path);
 | 
			
		||||
  if (!realPath) return;
 | 
			
		||||
 | 
			
		||||
  if (layoutFromWindow() === 'multi-column' && !realPath.startsWith('/deck')) {
 | 
			
		||||
    originalReplace(`/deck${realPath}`, state);
 | 
			
		||||
  } else {
 | 
			
		||||
    originalReplace(path, state);
 | 
			
		||||
  }
 | 
			
		||||
  originalReplace(location);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const Router: React.FC<PropsWithChildren> = ({ children }) => {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user