diff --git a/packages/web/src/components/ActorDetail.tsx b/packages/web/src/components/ActorDetail.tsx new file mode 100644 index 0000000..af8be37 --- /dev/null +++ b/packages/web/src/components/ActorDetail.tsx @@ -0,0 +1,45 @@ +// DrFed: A web-based platform for developing and debugging ActivityPub apps +// Copyright (C) 2026 DrFed team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +import { graphql } from "relay-runtime"; +import { Show } from "solid-js"; +import { createFragment } from "solid-relay"; + +import type { ActorDetail_actor$key } from "./__generated__/ActorDetail_actor.graphql.ts"; + +import styles from "~/styles/instance.module.css"; + +export const ActorDetail = (props: { $actor: ActorDetail_actor$key }) => { + const actorData = createFragment( + graphql` + fragment ActorDetail_actor on Actor { + handle + } + `, + () => props.$actor, + ); + + return ( + + {(actor) => ( +
+
+ )} +
+ ); +}; diff --git a/packages/web/src/components/InstanceSummary.tsx b/packages/web/src/components/InstanceSummary.tsx index 8314684..b0b222d 100644 --- a/packages/web/src/components/InstanceSummary.tsx +++ b/packages/web/src/components/InstanceSummary.tsx @@ -31,6 +31,9 @@ export default function InstanceSummary(props: { fragment InstanceSummary_instance on Instance { id host + localInstance { + slug + } } `, () => props.$instance, @@ -45,13 +48,17 @@ export default function InstanceSummary(props: {

Instance host

{instance().host}

- - Create actors - - + + {(localInstance) => ( + + View Detail + + + )} + )} diff --git a/packages/web/src/routes/instance/[slug].tsx b/packages/web/src/routes/instance/[slug].tsx index 49e2691..2b80abe 100644 --- a/packages/web/src/routes/instance/[slug].tsx +++ b/packages/web/src/routes/instance/[slug].tsx @@ -15,87 +15,158 @@ // along with this program. If not, see . import { Title } from "@solidjs/meta"; -import { A, useParams } from "@solidjs/router"; -import { For } from "solid-js"; +import { + A, + type RouteDefinition, + type RouteSectionProps, + query, +} from "@solidjs/router"; +import { graphql } from "relay-runtime"; +import { For, Show } from "solid-js"; +import { + createPreloadedQuery, + loadQuery, + useRelayEnvironment, +} from "solid-relay"; + +import { ActorDetail } from "~/components/ActorDetail.tsx"; + +import type { InstanceDetailQuery } from "./__generated__/InstanceDetailQuery.graphql.ts"; import styles from "~/styles/instance.module.css"; -const actors = ["@sherry", "@newsroom", "@garden"] as const; +// Temp Query to show first 100. +const instanceDetailQuery = graphql` + query InstanceDetailQuery($slug: String!) { + localInstanceBySlug(slug: $slug) { + instance { + id + host + actors(first: 100) { + totalCount + edges { + node { + ...ActorDetail_actor + } + } + } + } + } + } +`; + +const loadInstanceDetailQuery = query( + (slug: string) => + loadQuery( + useRelayEnvironment()(), + instanceDetailQuery, + { slug }, + ), + "InstanceDetailQuery", +); + +export const route = { + preload({ params }) { + if (params.slug === undefined) { + throw new Error("Missing slug route parameter."); + } + + return loadInstanceDetailQuery(params.slug); + }, +} satisfies RouteDefinition; + +type RouteData = ReturnType; -export default function InstanceDetailPage() { - const params = useParams(); - const host = () => params.slug ?? "social.example"; +export default function InstanceDetailPage( + props: RouteSectionProps, +) { + const data = createPreloadedQuery( + instanceDetailQuery, + () => props.data, + ); + + const instanceData = () => data()?.localInstanceBySlug?.instance; return ( -
- {host()} — DrFed - - - All instances - - -
-

{host()}

- - - Create actor - -
- -
-
-

Connection record

-

Federation endpoints

-
-
-
-
NodeInfo
-
- /nodeinfo/2.1 -
-
-
-
WebFinger
-
- - /.well-known/webfinger - -
-
-
-
Shared inbox
-
- /inbox -
-
-
-
- -
-
-
-

Local identities

-

Actors

-
-

{actors.length} registered

-
- -
- - {(handle) => ( -
-
- )} -
-
-
-
+ + + All instances + +

Instance not found.

+ + } + > + {(instance) => ( +
+ {instance().host} — DrFed + + + All instances + + +
+

{instance().host}

+ + + Create actor + +
+ +
+
+

Connection record

+

Federation endpoints

+
+
+ + +
+
Shared inbox
+
+ {`https://${instance().host}/inbox`} +
+
+
+
+ +
+
+
+

Local identities

+

Actors

+
+

{instance().actors.totalCount} registered

+
+
+ + {(edge) => } + +
+
+
+ )} +
); }