You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
70 lines
2.0 KiB
70 lines
2.0 KiB
import PropTypes from 'prop-types'; |
|
import { createContext, useContext } from 'react'; |
|
|
|
import hoistStatics from 'hoist-non-react-statics'; |
|
|
|
import type { InitialState } from 'mastodon/initial_state'; |
|
|
|
export interface IdentityContextType { |
|
signedIn: boolean; |
|
accountId: string | undefined; |
|
disabledAccountId: string | undefined; |
|
permissions: number; |
|
} |
|
|
|
export const identityContextPropShape = PropTypes.shape({ |
|
signedIn: PropTypes.bool.isRequired, |
|
accountId: PropTypes.string, |
|
disabledAccountId: PropTypes.string, |
|
}).isRequired; |
|
|
|
export const createIdentityContext = (state: InitialState) => ({ |
|
signedIn: !!state.meta.me, |
|
accountId: state.meta.me, |
|
disabledAccountId: state.meta.disabled_account_id, |
|
permissions: state.role?.permissions ?? 0, |
|
}); |
|
|
|
export const IdentityContext = createContext<IdentityContextType>({ |
|
signedIn: false, |
|
permissions: 0, |
|
accountId: undefined, |
|
disabledAccountId: undefined, |
|
}); |
|
|
|
export const useIdentity = () => useContext(IdentityContext); |
|
|
|
export interface IdentityProps { |
|
ref?: unknown; |
|
wrappedComponentRef?: unknown; |
|
} |
|
|
|
/* Injects an `identity` props into the wrapped component to be able to use the new context in class components */ |
|
export function withIdentity< |
|
ComponentType extends React.ComponentType<IdentityProps>, |
|
>(Component: ComponentType) { |
|
const displayName = `withIdentity(${Component.displayName ?? Component.name})`; |
|
const C = (props: React.ComponentProps<ComponentType>) => { |
|
const { wrappedComponentRef, ...remainingProps } = props; |
|
|
|
return ( |
|
<IdentityContext.Consumer> |
|
{(context) => { |
|
return ( |
|
// @ts-expect-error - Dynamic covariant generic components are tough to type. |
|
<Component |
|
{...remainingProps} |
|
identity={context} |
|
ref={wrappedComponentRef} |
|
/> |
|
); |
|
}} |
|
</IdentityContext.Consumer> |
|
); |
|
}; |
|
|
|
C.displayName = displayName; |
|
C.WrappedComponent = Component; |
|
|
|
return hoistStatics(C, Component); |
|
}
|
|
|