Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/events/src/components/auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { useEffect, useState } from 'react';

function DoGraphLogin() {
const { login } = Identity.useGraphLogin();
// biome-ignore lint/correctness/useExhaustiveDependencies: this is an issue and will make sure login is not run in a useEffect
useEffect(() => {
console.log('Logging in to The Graph');
login();
}, [login]);
}, []);
return <div />;
}

Expand Down
16 changes: 15 additions & 1 deletion apps/events/src/routes/__root.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Logout } from '@/components/logout';
import { GraphFramework, Identity } from '@graphprotocol/hypergraph';
import { Link, Outlet, createRootRoute } from '@tanstack/react-router';
import { Link, Outlet, createRootRoute, useLayoutEffect, useRouter } from '@tanstack/react-router';
import { TanStackRouterDevtools } from '@tanstack/router-devtools';

export const Route = createRootRoute({
Expand All @@ -10,6 +10,20 @@ export const Route = createRootRoute({
const graphIdentity = getIdentity();
const loggedInSessionToken = getSessionToken();

const router = useRouter();

useLayoutEffect(() => {
if (router.state.location.href.startsWith('/login')) {
return;
}

if (!authenticated) {
router.navigate({
to: '/login',
});
}
}, [authenticated]);

return (
<>
<div className="flex flex-col min-h-screen">
Expand Down
18 changes: 3 additions & 15 deletions apps/events/src/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Identity, store, useGraphFramework, useSelector } from '@graphprotocol/hypergraph';
import { store, useGraphFramework, useSelector } from '@graphprotocol/hypergraph';
import { Link, createFileRoute } from '@tanstack/react-router';

import { Button } from '@/components/ui/button';
Expand All @@ -12,30 +12,18 @@ export const Route = createFileRoute('/')({
function Index() {
const spaces = useSelector(store, (state) => state.context.spaces);
const { createSpace, listSpaces, listInvitations, invitations, acceptInvitation, isLoading } = useGraphFramework();
const { authenticated } = Identity.useGraphLogin();

useEffect(() => {
if (authenticated && !isLoading) {
if (!isLoading) {
listSpaces();
listInvitations();
}
}, [authenticated, listSpaces, listInvitations, isLoading]);
}, [listSpaces, listInvitations, isLoading]);

if (isLoading) {
return <div className="flex justify-center items-center h-screen">Loading …</div>;
}

if (!authenticated) {
return (
<div className="flex flex-col gap-4 justify-center items-center h-screen">
<h1 className="text-2xl font-bold">Not authenticated</h1>
<Link to="/login" className="text-blue-500 hover:text-blue-600 underline">
Go to Login
</Link>
</div>
);
}

return (
<div className="flex flex-col gap-4 max-w-screen-sm mx-auto py-8">
<h2 className="text-lg font-bold">Invitations</h2>
Expand Down
20 changes: 4 additions & 16 deletions apps/events/src/routes/space/$spaceId.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Identity, Schema, store, useGraphFramework, useSelector } from '@graphprotocol/hypergraph';
import { Link, createFileRoute } from '@tanstack/react-router';
import { Schema, store, useGraphFramework, useSelector } from '@graphprotocol/hypergraph';
import { createFileRoute } from '@tanstack/react-router';

import { DevTool } from '@/components/dev-tool';
import { Todos } from '@/components/todos';
Expand All @@ -15,12 +15,11 @@ function Space() {
const { spaceId } = Route.useParams();
const spaces = useSelector(store, (state) => state.context.spaces);
const { subscribeToSpace, inviteToSpace, isLoading } = useGraphFramework();
const { authenticated } = Identity.useGraphLogin();
useEffect(() => {
if (!isLoading && authenticated) {
if (!isLoading) {
subscribeToSpace({ spaceId });
}
}, [isLoading, subscribeToSpace, spaceId, authenticated]);
}, [isLoading, subscribeToSpace, spaceId]);

const space = spaces.find((space) => space.id === spaceId);

Expand All @@ -32,17 +31,6 @@ function Space() {
return <div className="flex justify-center items-center h-screen">Space not found</div>;
}

if (!authenticated) {
return (
<div className="flex flex-col gap-4 justify-center items-center h-screen">
<h1 className="text-2xl font-bold">Not authenticated</h1>
<Link to="/login" className="text-blue-500 hover:text-blue-600 underline">
Go to Login
</Link>
</div>
);
}

return (
<div className="flex flex-col gap-4 max-w-screen-sm mx-auto py-8">
<Schema.SpacesProvider defaultSpace={space.id}>
Expand Down
1 change: 1 addition & 0 deletions packages/hypergraph/src/core.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export function GraphFramework({
const syncServerWsUrl = new URL(`/?token=${sessionToken}`, syncServerUrl.toString());
syncServerWsUrl.protocol = 'ws:';
const syncServerWsUrlString = syncServerWsUrl.toString();

// Create a stable WebSocket connection that only depends on accountId
useEffect(() => {
if (!sessionToken) {
Expand Down
6 changes: 4 additions & 2 deletions packages/hypergraph/src/identity/graph-login.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Schema } from 'effect';
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
import { createContext, useCallback, useContext, useLayoutEffect, useState } from 'react';
import { SiweMessage } from 'siwe';
import type { Hex } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
Expand Down Expand Up @@ -317,7 +317,9 @@ export function GraphLogin({
store.send({ type: 'reset' });
};

useEffect(() => {
// using a layout effect to set the state before the component is mounted and
// avoid a flash of unauthenticated content
useLayoutEffect(() => {
const accountId = loadAccountId(storage);
if (accountId) {
const sessionToken = loadSyncServerSessionToken(storage, accountId);
Expand Down
Loading