mirror of
https://github.com/urbit/shrub.git
synced 2024-12-24 03:14:30 +03:00
permalinks: restructure paths
This commit is contained in:
parent
bc82f02091
commit
c7015e2080
21
pkg/interface/src/logic/lib/permalinks.ts
Normal file
21
pkg/interface/src/logic/lib/permalinks.ts
Normal 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`;
|
||||
}
|
@ -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;
|
||||
|
@ -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 =
|
||||
|
150
pkg/interface/src/views/apps/permalinks/app.tsx
Normal file
150
pkg/interface/src/views/apps/permalinks/app.tsx
Normal 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>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user