permalinks: restructure paths

This commit is contained in:
Liam Fitzgerald 2021-03-17 14:06:45 +10:00
parent bc82f02091
commit c7015e2080
No known key found for this signature in database
GPG Key ID: D390E12C61D1CFFB
5 changed files with 184 additions and 24 deletions

View File

@ -0,0 +1,21 @@
import { Association, resourceFromPath } from "@urbit/api";
import { useGroupForAssoc } from "../state/group";
export function usePermalinkForGraph(assoc: Association, index = "") {
const group = usePermalinkForAssociatedGroup(assoc);
const { ship, name } = resourceFromPath(assoc.resource);
return `${group}/graph/${ship}/${name}${index}`;
}
function usePermalinkForAssociatedGroup(assoc: Association) {
const group = useGroupForAssoc(assoc);
const mod = assoc.metadata.module;
const { ship, name } = resourceFromPath(assoc.group);
if (!group?.hidden) {
return `web+urbit://group/${ship}/${name}`;
}
if (mod === "chat") {
return `web+urbit://messages`;
}
return `web+urbit://mychannel`;
}

View File

@ -1,15 +1,24 @@
import { Path, JoinRequests } from "@urbit/api";
import { Path, JoinRequests, Association, Group } from "@urbit/api";
import { BaseState, createState } from "./base";
import {useCallback} from "react";
export interface GroupState extends BaseState<GroupState> {
groups: Set<Path>;
groups: {
[group: string]: Group;
}
pendingJoin: JoinRequests;
};
const useGroupState = createState<GroupState>('Group', {
groups: new Set(),
groups: {},
pendingJoin: {},
}, ['groups']);
export default useGroupState;
export function useGroupForAssoc(association: Association) {
return useGroupState(
useCallback(s => s.groups[association.group] as Group | undefined, [association])
);
}
export default useGroupState;

View File

@ -5,7 +5,6 @@ import { deSig } from '~/logic/lib/util';
import useGraphState from '~/logic/state/graph';
import useMetadataState from '~/logic/state/metadata';
import useGroupState from '~/logic/state/group';
import { GraphIndexRoute } from './graphIndex';
const GraphApp = (props) => {
const associations= useMetadataState(state => state.associations);
@ -17,25 +16,6 @@ const GraphApp = (props) => {
return (
<Switch>
<Route path="/~graph/graph/ship/:ship/:name"
render={(props) => {
const resource =
`${deSig(props.match.params.ship)}/${props.match.params.name}`;
const { ship, name } = props.match.params;
const path = `/ship/~${deSig(ship)}/${name}`;
const association = associations.graph[path];
const url = `/~graph/graph/ship/${ship}/${name}`;
const group = groups[association.group];
if(!(group && association)) {
return null;
}
return (
<GraphIndexRoute url={url} association={association} index="" group={group} />
);
}}
/>
<Route exact path="/~graph/join/ship/:ship/:name/:module?"
render={(props) => {
const resource =

View File

@ -0,0 +1,150 @@
import React, { useCallback } from "react";
import useMetadataState from "~/logic/state/metadata";
import useGroupState from "~/logic/state/group";
import {
Switch,
Route,
Redirect,
useLocation,
useParams,
} from "react-router-dom";
import { makeResource, Association } from "@urbit/api";
import { getGraphPermalink } from "./graphIndex";
import { useQuery } from "~/logic/lib/useQuery";
import useGraphState from "~/logic/state/graph";
interface ResourceRouteProps {
ship: string;
name: string;
}
export function PermalinkRoutes(props: {}) {
const groups = useGroupState((s) => s.groups);
const { query, toQuery } = useQuery();
return (
<Switch>
<Route
path="/perma/group/:ship/:name"
render={({ match, history, location }) => {
const { ship, name } = match.params as ResourceRouteProps;
console.log(ship);
const { url } = match;
const path = `/ship/${ship}/${name}`;
const group = groups[path];
if(!group) {
if (Object.keys(groups).length > 0) {
console.log(groups);
const redir = location.pathname;
const to = toQuery({ redir }, `/~landscape/join/${ship}/${name}`);
return <Redirect to={to} />;
}
return null;
}
return <GroupRoutes url={url} group={path} />;
}}
/>
<Route path="/perma" render={() => <FallbackRoutes query={query} />} />
</Switch>
);
}
function FallbackRoutes(props: { query: URLSearchParams }) {
const { query } = props;
if (query.has("ext")) {
const ext = query.get("ext")!;
console.log(ext);
const url = `/perma${ext.slice(11)}`;
console.log(url);
return <Redirect to={{ pathname: url }} />;
}
return <Redirect to="/~404" />;
}
function GroupRoutes(props: { group: string; url: string }) {
const { group, url } = props;
const makePath = (s: string) => url + s;
const associations = useMetadataState((s) => s.associations);
const graphKeys = useGraphState(s => s.graphKeys);
const { toQuery } = useQuery();
const groupUrl = `/~landscape${group}`;
console.log(group);
return (
<Switch>
<Route
path={makePath("/graph/:ship/:name")}
render={({ match, location }) => {
const { ship, name } = match.params as ResourceRouteProps;
const path = `/ship/${ship}/${name}`;
const association = associations.graph[path];
const { url: routeUrl } = match;
if(!association) {
return null;
}
if(!graphKeys.has(`${ship}/${name}`)) {
if(graphKeys.size > 0) {
return <Redirect
to={toQuery(
{ auto: 'y', redir: location.pathname },
`${groupUrl}/join/${association.metadata.module}${path}`
)}
/>;
}
return null;
}
return <GraphIndexRoutes url={routeUrl} association={association} />;
}}
/>
<Route
exact
path={makePath("")}
render={() => {
return <Redirect to={groupUrl} />;
}}
/>
</Switch>
);
}
export function GraphIndexRoutes(props: {
association: Association;
url: string;
index?: string;
}) {
const { index = "", association, url } = props;
const makePath = (s: string) => url + s;
const group = useGroupState(
useCallback((s) => s.groups[association.group], [association])
);
if(!group) {
return null;
}
return (
<Switch>
<Route
path={makePath("/:id")}
render={({ match }) => {
const newIndex = `${index}/${match.params.id}`;
const { url: newUrl } = match;
return (
<GraphIndexRoutes
association={association}
url={newUrl}
index={newIndex}
/>
);
}}
/>
<Route path={makePath("")}>
<Redirect to={getGraphPermalink(association, group, index)} />
</Route>
</Switch>
);
}