mirror of
https://github.com/urbit/shrub.git
synced 2024-12-24 20:47:27 +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 { BaseState, createState } from "./base";
|
||||||
|
import {useCallback} from "react";
|
||||||
|
|
||||||
export interface GroupState extends BaseState<GroupState> {
|
export interface GroupState extends BaseState<GroupState> {
|
||||||
groups: Set<Path>;
|
groups: {
|
||||||
|
[group: string]: Group;
|
||||||
|
}
|
||||||
pendingJoin: JoinRequests;
|
pendingJoin: JoinRequests;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useGroupState = createState<GroupState>('Group', {
|
const useGroupState = createState<GroupState>('Group', {
|
||||||
groups: new Set(),
|
groups: {},
|
||||||
pendingJoin: {},
|
pendingJoin: {},
|
||||||
}, ['groups']);
|
}, ['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 useGraphState from '~/logic/state/graph';
|
||||||
import useMetadataState from '~/logic/state/metadata';
|
import useMetadataState from '~/logic/state/metadata';
|
||||||
import useGroupState from '~/logic/state/group';
|
import useGroupState from '~/logic/state/group';
|
||||||
import { GraphIndexRoute } from './graphIndex';
|
|
||||||
|
|
||||||
const GraphApp = (props) => {
|
const GraphApp = (props) => {
|
||||||
const associations= useMetadataState(state => state.associations);
|
const associations= useMetadataState(state => state.associations);
|
||||||
@ -17,25 +16,6 @@ const GraphApp = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Switch>
|
<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?"
|
<Route exact path="/~graph/join/ship/:ship/:name/:module?"
|
||||||
render={(props) => {
|
render={(props) => {
|
||||||
const resource =
|
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