Fix history handling not properly handling states after update to react-router v5 (#27526)
This commit is contained in:
		
					parent
					
						
							
								6cf9f1211b
							
						
					
				
			
			
				commit
				
					
						15182d1e5e
					
				
			
		
					 1 changed files with 43 additions and 23 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue