kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
Merge branch 'nip19-routes' into 'main'
NIP-19 routes See merge request soapbox-pub/soapbox!2988environments/review-main-yi2y9f/deployments/4538
commit
d4beb15d71
|
@ -401,7 +401,6 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
const ownAccount = status.account.id === me;
|
const ownAccount = status.account.id === me;
|
||||||
const username = status.account.username;
|
const username = status.account.username;
|
||||||
const account = status.account;
|
const account = status.account;
|
||||||
const domain = account.fqn.split('@')[1];
|
|
||||||
|
|
||||||
const menu: Menu = [];
|
const menu: Menu = [];
|
||||||
|
|
||||||
|
@ -455,6 +454,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (features.federating && !account.local) {
|
if (features.federating && !account.local) {
|
||||||
|
const { hostname: domain } = new URL(status.uri);
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.external, { domain }),
|
text: intl.formatMessage(messages.external, { domain }),
|
||||||
action: handleExternalClick,
|
action: handleExternalClick,
|
||||||
|
|
|
@ -25,10 +25,11 @@ function useEntityLookup<TEntity extends Entity>(
|
||||||
const { schema = z.custom<TEntity>() } = opts;
|
const { schema = z.custom<TEntity>() } = opts;
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
const [fetchedEntity, setFetchedEntity] = useState<TEntity | undefined>();
|
||||||
const [isFetching, setPromise] = useLoading(true);
|
const [isFetching, setPromise] = useLoading(true);
|
||||||
const [error, setError] = useState<unknown>();
|
const [error, setError] = useState<unknown>();
|
||||||
|
|
||||||
const entity = useAppSelector(state => findEntity(state, entityType, lookupFn));
|
const entity = useAppSelector(state => findEntity(state, entityType, lookupFn) ?? fetchedEntity);
|
||||||
const isEnabled = opts.enabled ?? true;
|
const isEnabled = opts.enabled ?? true;
|
||||||
const isLoading = isFetching && !entity;
|
const isLoading = isFetching && !entity;
|
||||||
|
|
||||||
|
@ -36,6 +37,7 @@ function useEntityLookup<TEntity extends Entity>(
|
||||||
try {
|
try {
|
||||||
const response = await setPromise(entityFn());
|
const response = await setPromise(entityFn());
|
||||||
const entity = schema.parse(response.data);
|
const entity = schema.parse(response.data);
|
||||||
|
setFetchedEntity(entity);
|
||||||
dispatch(importEntities([entity], entityType));
|
dispatch(importEntities([entity], entityType));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setError(e);
|
setError(e);
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { nip19 } from 'nostr-tools';
|
||||||
|
import React from 'react';
|
||||||
|
import { Redirect } from 'react-router-dom';
|
||||||
|
|
||||||
|
import MissingIndicator from 'soapbox/components/missing-indicator';
|
||||||
|
|
||||||
|
interface INIP19Redirect {
|
||||||
|
params: {
|
||||||
|
bech32: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const Bech32Redirect: React.FC<INIP19Redirect> = ({ params }) => {
|
||||||
|
try {
|
||||||
|
const result = nip19.decode(params.bech32);
|
||||||
|
|
||||||
|
switch (result.type) {
|
||||||
|
case 'npub':
|
||||||
|
case 'nprofile':
|
||||||
|
return <Redirect to={`/@${params.bech32}`} />;
|
||||||
|
case 'note':
|
||||||
|
return <Redirect to={`/posts/${result.data}`} />;
|
||||||
|
case 'nevent':
|
||||||
|
return <Redirect to={`/posts/${result.data.id}`} />;
|
||||||
|
default:
|
||||||
|
return <MissingIndicator />;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
return <MissingIndicator />;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Bech32Redirect;
|
|
@ -140,6 +140,7 @@ import {
|
||||||
EditIdentity,
|
EditIdentity,
|
||||||
Domains,
|
Domains,
|
||||||
NostrRelays,
|
NostrRelays,
|
||||||
|
Bech32Redirect,
|
||||||
} from './util/async-components';
|
} from './util/async-components';
|
||||||
import GlobalHotkeys from './util/global-hotkeys';
|
import GlobalHotkeys from './util/global-hotkeys';
|
||||||
import { WrappedRoute } from './util/react-router-helpers';
|
import { WrappedRoute } from './util/react-router-helpers';
|
||||||
|
@ -284,6 +285,7 @@ const SwitchingColumnsArea: React.FC<ISwitchingColumnsArea> = ({ children }) =>
|
||||||
{features.events && <WrappedRoute path='/@:username/events/:statusId' publicRoute exact page={EventPage} component={EventInformation} content={children} />}
|
{features.events && <WrappedRoute path='/@:username/events/:statusId' publicRoute exact page={EventPage} component={EventInformation} content={children} />}
|
||||||
{features.events && <WrappedRoute path='/@:username/events/:statusId/discussion' publicRoute exact page={EventPage} component={EventDiscussion} content={children} />}
|
{features.events && <WrappedRoute path='/@:username/events/:statusId/discussion' publicRoute exact page={EventPage} component={EventDiscussion} content={children} />}
|
||||||
<Redirect from='/@:username/:statusId' to='/@:username/posts/:statusId' />
|
<Redirect from='/@:username/:statusId' to='/@:username/posts/:statusId' />
|
||||||
|
<WrappedRoute path='/posts/:statusId' publicRoute exact page={DefaultPage} component={Status} content={children} />
|
||||||
|
|
||||||
{features.groups && <WrappedRoute path='/groups' exact page={GroupsPage} component={Groups} content={children} />}
|
{features.groups && <WrappedRoute path='/groups' exact page={GroupsPage} component={Groups} content={children} />}
|
||||||
{features.groupsDiscovery && <WrappedRoute path='/groups/discover' exact page={GroupsPage} component={GroupsDiscover} content={children} />}
|
{features.groupsDiscovery && <WrappedRoute path='/groups/discover' exact page={GroupsPage} component={GroupsDiscover} content={children} />}
|
||||||
|
@ -361,6 +363,8 @@ const SwitchingColumnsArea: React.FC<ISwitchingColumnsArea> = ({ children }) =>
|
||||||
<Redirect from='/auth/password/new' to='/reset-password' />
|
<Redirect from='/auth/password/new' to='/reset-password' />
|
||||||
<Redirect from='/auth/password/edit' to={`/edit-password${search}`} />
|
<Redirect from='/auth/password/edit' to={`/edit-password${search}`} />
|
||||||
|
|
||||||
|
<WrappedRoute path='/:bech32([\x21-\x7E]{1,83}1[023456789acdefghjklmnpqrstuvwxyz]{6,})' publicRoute page={EmptyPage} component={Bech32Redirect} content={children} />
|
||||||
|
|
||||||
<WrappedRoute page={EmptyPage} component={GenericNotFound} content={children} />
|
<WrappedRoute page={EmptyPage} component={GenericNotFound} content={children} />
|
||||||
</Switch>
|
</Switch>
|
||||||
);
|
);
|
||||||
|
|
|
@ -171,3 +171,4 @@ export const EditIdentity = lazy(() => import('soapbox/features/edit-identity'))
|
||||||
export const Domains = lazy(() => import('soapbox/features/admin/domains'));
|
export const Domains = lazy(() => import('soapbox/features/admin/domains'));
|
||||||
export const EditDomainModal = lazy(() => import('soapbox/features/ui/components/modals/edit-domain-modal'));
|
export const EditDomainModal = lazy(() => import('soapbox/features/ui/components/modals/edit-domain-modal'));
|
||||||
export const NostrRelays = lazy(() => import('soapbox/features/nostr-relays'));
|
export const NostrRelays = lazy(() => import('soapbox/features/nostr-relays'));
|
||||||
|
export const Bech32Redirect = lazy(() => import('soapbox/features/nostr/Bech32Redirect'));
|
Ładowanie…
Reference in New Issue