You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-31 09:24:31 +03:00
WIP my account page
This commit is contained in:
@ -2,7 +2,7 @@ import { CodegenConfig } from "@graphql-codegen/cli";
|
||||
|
||||
const config: CodegenConfig = {
|
||||
schema: "./schema.graphql",
|
||||
documents: ["src/**/*.tsx", "!src/gql/**/*"],
|
||||
documents: ["src/**/*.{tsx,ts}", "!src/gql/**/*"],
|
||||
ignoreNoDocuments: true, // for better experience with the watcher
|
||||
generates: {
|
||||
"./src/gql/": {
|
||||
|
13
frontend/package-lock.json
generated
13
frontend/package-lock.json
generated
@ -10,6 +10,7 @@
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.10.6",
|
||||
"@urql/core": "^4.0.7",
|
||||
"@urql/devtools": "^2.0.3",
|
||||
"@urql/exchange-graphcache": "^6.0.3",
|
||||
"date-fns": "^2.29.3",
|
||||
"graphql": "^16.6.0",
|
||||
@ -6440,6 +6441,18 @@
|
||||
"wonka": "^6.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@urql/devtools": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@urql/devtools/-/devtools-2.0.3.tgz",
|
||||
"integrity": "sha512-TktPLiBS9LcBPHD6qcnb8wqOVcg3Bx0iCtvQ80uPpfofwwBGJmqnQTjUdEFU6kwaLOFZULQ9+Uo4831G823mQw==",
|
||||
"dependencies": {
|
||||
"wonka": ">= 4.0.9"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@urql/core": ">= 1.14.0",
|
||||
"graphql": ">= 0.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@urql/exchange-graphcache": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@urql/exchange-graphcache/-/exchange-graphcache-6.0.3.tgz",
|
||||
|
@ -18,6 +18,7 @@
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.10.6",
|
||||
"@urql/core": "^4.0.7",
|
||||
"@urql/devtools": "^2.0.3",
|
||||
"@urql/exchange-graphcache": "^6.0.3",
|
||||
"date-fns": "^2.29.3",
|
||||
"graphql": "^16.6.0",
|
||||
|
@ -13,12 +13,66 @@
|
||||
// limitations under the License.
|
||||
|
||||
import type { ReactElement } from "react";
|
||||
import { atom } from "jotai";
|
||||
import { useHydrateAtoms } from "jotai/utils";
|
||||
import { clientAtom } from "jotai-urql";
|
||||
import { atomWithQuery, clientAtom } from "jotai-urql";
|
||||
|
||||
import { client } from "./graphql";
|
||||
import { graphql } from "./gql";
|
||||
|
||||
export const HydrateAtoms = ({ children }: { children: ReactElement }) => {
|
||||
useHydrateAtoms([[clientAtom, client]]);
|
||||
return children;
|
||||
};
|
||||
|
||||
const CURRENT_VIEWER_QUERY = graphql(/* GraphQL */ `
|
||||
query CurrentViewerQuery {
|
||||
viewer {
|
||||
... on User {
|
||||
id
|
||||
}
|
||||
|
||||
... on Anonymous {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
const currentViewerAtom = atomWithQuery({ query: CURRENT_VIEWER_QUERY });
|
||||
|
||||
export const currentUserIdAtom = atom(async (get) => {
|
||||
const result = await get(currentViewerAtom);
|
||||
if (result.data?.viewer.__typename === "User") {
|
||||
return result.data.viewer.id;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
const CURRENT_VIEWER_SESSION_QUERY = graphql(/* GraphQL */ `
|
||||
query CurrentViewerSessionQuery {
|
||||
viewerSession {
|
||||
... on BrowserSession {
|
||||
id
|
||||
}
|
||||
|
||||
... on Anonymous {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
const currentViewerSessionAtom = atomWithQuery({
|
||||
query: CURRENT_VIEWER_SESSION_QUERY,
|
||||
});
|
||||
|
||||
export const currentBrowserSessionIdAtom = atom(
|
||||
async (get): Promise<string | null> => {
|
||||
const result = await get(currentViewerSessionAtom);
|
||||
if (result.data?.viewerSession.__typename === "BrowserSession") {
|
||||
return result.data.viewerSession.id;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
@ -19,7 +19,7 @@ import { FragmentType, graphql, useFragment } from "../gql";
|
||||
|
||||
const FRAGMENT = graphql(/* GraphQL */ `
|
||||
fragment BrowserSessionList_user on User {
|
||||
browserSessions(first: $count, after: $cursor) {
|
||||
browserSessions(first: 10) {
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
|
@ -19,7 +19,7 @@ import { FragmentType, graphql, useFragment } from "../gql";
|
||||
|
||||
const FRAGMENT = graphql(/* GraphQL */ `
|
||||
fragment CompatSsoLoginList_user on User {
|
||||
compatSsoLogins(first: $count, after: $cursor) {
|
||||
compatSsoLogins(first: 10) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
|
@ -20,7 +20,7 @@ import { FragmentType, graphql, useFragment } from "../gql";
|
||||
|
||||
const FRAGMENT = graphql(/* GraphQL */ `
|
||||
fragment OAuth2SessionList_user on User {
|
||||
oauth2Sessions(first: $count, after: $cursor) {
|
||||
oauth2Sessions(first: 10) {
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
|
@ -31,7 +31,6 @@ const QUERY = graphql(/* GraphQL */ `
|
||||
$before: String
|
||||
) {
|
||||
user(id: $userId) {
|
||||
__typename
|
||||
id
|
||||
emails(first: $first, after: $after, last: $last, before: $before) {
|
||||
edges {
|
||||
@ -54,12 +53,12 @@ const QUERY = graphql(/* GraphQL */ `
|
||||
`);
|
||||
|
||||
type ForwardPagination = {
|
||||
first: int;
|
||||
first: number;
|
||||
after: string | null;
|
||||
};
|
||||
|
||||
type BackwardPagination = {
|
||||
last: int;
|
||||
last: number;
|
||||
before: string | null;
|
||||
};
|
||||
|
||||
|
@ -13,31 +13,33 @@ import { TypedDocumentNode as DocumentNode } from "@graphql-typed-document-node/
|
||||
* Therefore it is highly recommended to use the babel or swc plugin for production.
|
||||
*/
|
||||
const documents = {
|
||||
"\n query CurrentViewerQuery {\n viewer {\n ... on User {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n":
|
||||
types.CurrentViewerQueryDocument,
|
||||
"\n query CurrentViewerSessionQuery {\n viewerSession {\n ... on BrowserSession {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n":
|
||||
types.CurrentViewerSessionQueryDocument,
|
||||
"\n mutation AddEmail($userId: ID!, $email: String!) {\n addEmail(input: { userId: $userId, email: $email }) {\n status\n user {\n id\n }\n email {\n id\n ...UserEmail_email\n }\n }\n }\n":
|
||||
types.AddEmailDocument,
|
||||
"\n fragment BrowserSession_session on BrowserSession {\n id\n createdAt\n lastAuthentication {\n id\n createdAt\n }\n }\n":
|
||||
types.BrowserSession_SessionFragmentDoc,
|
||||
"\n fragment BrowserSessionList_user on User {\n browserSessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n }\n }\n }\n }\n":
|
||||
"\n fragment BrowserSessionList_user on User {\n browserSessions(first: 10) {\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n }\n }\n }\n }\n":
|
||||
types.BrowserSessionList_UserFragmentDoc,
|
||||
"\n fragment CompatSsoLogin_login on CompatSsoLogin {\n id\n redirectUri\n createdAt\n session {\n id\n createdAt\n deviceId\n finishedAt\n }\n }\n":
|
||||
types.CompatSsoLogin_LoginFragmentDoc,
|
||||
"\n fragment CompatSsoLoginList_user on User {\n compatSsoLogins(first: $count, after: $cursor) {\n edges {\n node {\n id\n ...CompatSsoLogin_login\n }\n }\n }\n }\n":
|
||||
"\n fragment CompatSsoLoginList_user on User {\n compatSsoLogins(first: 10) {\n edges {\n node {\n id\n ...CompatSsoLogin_login\n }\n }\n }\n }\n":
|
||||
types.CompatSsoLoginList_UserFragmentDoc,
|
||||
"\n fragment OAuth2Session_session on Oauth2Session {\n id\n scope\n client {\n id\n clientId\n clientName\n clientUri\n }\n }\n":
|
||||
types.OAuth2Session_SessionFragmentDoc,
|
||||
"\n fragment OAuth2SessionList_user on User {\n oauth2Sessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n }\n }\n }\n }\n":
|
||||
"\n fragment OAuth2SessionList_user on User {\n oauth2Sessions(first: 10) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n }\n }\n }\n }\n":
|
||||
types.OAuth2SessionList_UserFragmentDoc,
|
||||
"\n fragment UserEmail_email on UserEmail {\n id\n email\n createdAt\n confirmedAt\n }\n":
|
||||
types.UserEmail_EmailFragmentDoc,
|
||||
"\n query UserEmailListQuery(\n $userId: ID!\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n __typename\n id\n emails(first: $first, after: $after, last: $last, before: $before) {\n edges {\n cursor\n node {\n id\n ...UserEmail_email\n }\n }\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n":
|
||||
"\n query UserEmailListQuery(\n $userId: ID!\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n emails(first: $first, after: $after, last: $last, before: $before) {\n edges {\n cursor\n node {\n id\n ...UserEmail_email\n }\n }\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n":
|
||||
types.UserEmailListQueryDocument,
|
||||
"\n query CurrentUserQuery {\n viewer {\n ... on User {\n __typename\n id\n }\n }\n }\n":
|
||||
types.CurrentUserQueryDocument,
|
||||
"\n query AccountQuery($id: ID!) {\n user(id: $id) {\n id\n username\n }\n }\n":
|
||||
types.AccountQueryDocument,
|
||||
"\n query BrowserSessionQuery($id: ID!) {\n browserSession(id: $id) {\n id\n createdAt\n lastAuthentication {\n id\n createdAt\n }\n user {\n id\n username\n }\n }\n }\n":
|
||||
types.BrowserSessionQueryDocument,
|
||||
"\n query HomeQuery($count: Int!, $cursor: String) {\n # eslint-disable-next-line @graphql-eslint/no-deprecated\n currentBrowserSession {\n id\n user {\n id\n username\n\n ...CompatSsoLoginList_user\n ...BrowserSessionList_user\n ...OAuth2SessionList_user\n }\n }\n }\n":
|
||||
"\n query HomeQuery {\n # eslint-disable-next-line @graphql-eslint/no-deprecated\n currentBrowserSession {\n id\n user {\n id\n username\n\n ...CompatSsoLoginList_user\n ...BrowserSessionList_user\n ...OAuth2SessionList_user\n }\n }\n }\n":
|
||||
types.HomeQueryDocument,
|
||||
"\n query OAuth2ClientQuery($id: ID!) {\n oauth2Client(id: $id) {\n id\n clientId\n clientName\n clientUri\n tosUri\n policyUri\n redirectUris\n }\n }\n":
|
||||
types.OAuth2ClientQueryDocument,
|
||||
@ -57,6 +59,18 @@ const documents = {
|
||||
*/
|
||||
export function graphql(source: string): unknown;
|
||||
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(
|
||||
source: "\n query CurrentViewerQuery {\n viewer {\n ... on User {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n"
|
||||
): (typeof documents)["\n query CurrentViewerQuery {\n viewer {\n ... on User {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(
|
||||
source: "\n query CurrentViewerSessionQuery {\n viewerSession {\n ... on BrowserSession {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n"
|
||||
): (typeof documents)["\n query CurrentViewerSessionQuery {\n viewerSession {\n ... on BrowserSession {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@ -73,8 +87,8 @@ export function graphql(
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(
|
||||
source: "\n fragment BrowserSessionList_user on User {\n browserSessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n }\n }\n }\n }\n"
|
||||
): (typeof documents)["\n fragment BrowserSessionList_user on User {\n browserSessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n }\n }\n }\n }\n"];
|
||||
source: "\n fragment BrowserSessionList_user on User {\n browserSessions(first: 10) {\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n }\n }\n }\n }\n"
|
||||
): (typeof documents)["\n fragment BrowserSessionList_user on User {\n browserSessions(first: 10) {\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n }\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@ -85,8 +99,8 @@ export function graphql(
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(
|
||||
source: "\n fragment CompatSsoLoginList_user on User {\n compatSsoLogins(first: $count, after: $cursor) {\n edges {\n node {\n id\n ...CompatSsoLogin_login\n }\n }\n }\n }\n"
|
||||
): (typeof documents)["\n fragment CompatSsoLoginList_user on User {\n compatSsoLogins(first: $count, after: $cursor) {\n edges {\n node {\n id\n ...CompatSsoLogin_login\n }\n }\n }\n }\n"];
|
||||
source: "\n fragment CompatSsoLoginList_user on User {\n compatSsoLogins(first: 10) {\n edges {\n node {\n id\n ...CompatSsoLogin_login\n }\n }\n }\n }\n"
|
||||
): (typeof documents)["\n fragment CompatSsoLoginList_user on User {\n compatSsoLogins(first: 10) {\n edges {\n node {\n id\n ...CompatSsoLogin_login\n }\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@ -97,8 +111,8 @@ export function graphql(
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(
|
||||
source: "\n fragment OAuth2SessionList_user on User {\n oauth2Sessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n }\n }\n }\n }\n"
|
||||
): (typeof documents)["\n fragment OAuth2SessionList_user on User {\n oauth2Sessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n }\n }\n }\n }\n"];
|
||||
source: "\n fragment OAuth2SessionList_user on User {\n oauth2Sessions(first: 10) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n }\n }\n }\n }\n"
|
||||
): (typeof documents)["\n fragment OAuth2SessionList_user on User {\n oauth2Sessions(first: 10) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n }\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@ -109,14 +123,8 @@ export function graphql(
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(
|
||||
source: "\n query UserEmailListQuery(\n $userId: ID!\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n __typename\n id\n emails(first: $first, after: $after, last: $last, before: $before) {\n edges {\n cursor\n node {\n id\n ...UserEmail_email\n }\n }\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"
|
||||
): (typeof documents)["\n query UserEmailListQuery(\n $userId: ID!\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n __typename\n id\n emails(first: $first, after: $after, last: $last, before: $before) {\n edges {\n cursor\n node {\n id\n ...UserEmail_email\n }\n }\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(
|
||||
source: "\n query CurrentUserQuery {\n viewer {\n ... on User {\n __typename\n id\n }\n }\n }\n"
|
||||
): (typeof documents)["\n query CurrentUserQuery {\n viewer {\n ... on User {\n __typename\n id\n }\n }\n }\n"];
|
||||
source: "\n query UserEmailListQuery(\n $userId: ID!\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n emails(first: $first, after: $after, last: $last, before: $before) {\n edges {\n cursor\n node {\n id\n ...UserEmail_email\n }\n }\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"
|
||||
): (typeof documents)["\n query UserEmailListQuery(\n $userId: ID!\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n emails(first: $first, after: $after, last: $last, before: $before) {\n edges {\n cursor\n node {\n id\n ...UserEmail_email\n }\n }\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@ -133,8 +141,8 @@ export function graphql(
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(
|
||||
source: "\n query HomeQuery($count: Int!, $cursor: String) {\n # eslint-disable-next-line @graphql-eslint/no-deprecated\n currentBrowserSession {\n id\n user {\n id\n username\n\n ...CompatSsoLoginList_user\n ...BrowserSessionList_user\n ...OAuth2SessionList_user\n }\n }\n }\n"
|
||||
): (typeof documents)["\n query HomeQuery($count: Int!, $cursor: String) {\n # eslint-disable-next-line @graphql-eslint/no-deprecated\n currentBrowserSession {\n id\n user {\n id\n username\n\n ...CompatSsoLoginList_user\n ...BrowserSessionList_user\n ...OAuth2SessionList_user\n }\n }\n }\n"];
|
||||
source: "\n query HomeQuery {\n # eslint-disable-next-line @graphql-eslint/no-deprecated\n currentBrowserSession {\n id\n user {\n id\n username\n\n ...CompatSsoLoginList_user\n ...BrowserSessionList_user\n ...OAuth2SessionList_user\n }\n }\n }\n"
|
||||
): (typeof documents)["\n query HomeQuery {\n # eslint-disable-next-line @graphql-eslint/no-deprecated\n currentBrowserSession {\n id\n user {\n id\n username\n\n ...CompatSsoLoginList_user\n ...BrowserSessionList_user\n ...OAuth2SessionList_user\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
|
@ -577,6 +577,26 @@ export type Viewer = Anonymous | User;
|
||||
/** Represents the current viewer's session */
|
||||
export type ViewerSession = Anonymous | BrowserSession;
|
||||
|
||||
export type CurrentViewerQueryQueryVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
export type CurrentViewerQueryQuery = {
|
||||
__typename?: "Query";
|
||||
viewer:
|
||||
| { __typename?: "Anonymous"; id: string }
|
||||
| { __typename?: "User"; id: string };
|
||||
};
|
||||
|
||||
export type CurrentViewerSessionQueryQueryVariables = Exact<{
|
||||
[key: string]: never;
|
||||
}>;
|
||||
|
||||
export type CurrentViewerSessionQueryQuery = {
|
||||
__typename?: "Query";
|
||||
viewerSession:
|
||||
| { __typename?: "Anonymous"; id: string }
|
||||
| { __typename?: "BrowserSession"; id: string };
|
||||
};
|
||||
|
||||
export type AddEmailMutationVariables = Exact<{
|
||||
userId: Scalars["ID"];
|
||||
email: Scalars["String"];
|
||||
@ -698,7 +718,7 @@ export type UserEmailListQueryQueryVariables = Exact<{
|
||||
export type UserEmailListQueryQuery = {
|
||||
__typename?: "Query";
|
||||
user?: {
|
||||
__typename: "User";
|
||||
__typename?: "User";
|
||||
id: string;
|
||||
emails: {
|
||||
__typename?: "UserEmailConnection";
|
||||
@ -723,13 +743,6 @@ export type UserEmailListQueryQuery = {
|
||||
} | null;
|
||||
};
|
||||
|
||||
export type CurrentUserQueryQueryVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
export type CurrentUserQueryQuery = {
|
||||
__typename?: "Query";
|
||||
viewer: { __typename?: "Anonymous" } | { __typename: "User"; id: string };
|
||||
};
|
||||
|
||||
export type AccountQueryQueryVariables = Exact<{
|
||||
id: Scalars["ID"];
|
||||
}>;
|
||||
@ -758,10 +771,7 @@ export type BrowserSessionQueryQuery = {
|
||||
} | null;
|
||||
};
|
||||
|
||||
export type HomeQueryQueryVariables = Exact<{
|
||||
count: Scalars["Int"];
|
||||
cursor?: InputMaybe<Scalars["String"]>;
|
||||
}>;
|
||||
export type HomeQueryQueryVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
export type HomeQueryQuery = {
|
||||
__typename?: "Query";
|
||||
@ -847,18 +857,7 @@ export const BrowserSessionList_UserFragmentDoc = {
|
||||
{
|
||||
kind: "Argument",
|
||||
name: { kind: "Name", value: "first" },
|
||||
value: {
|
||||
kind: "Variable",
|
||||
name: { kind: "Name", value: "count" },
|
||||
},
|
||||
},
|
||||
{
|
||||
kind: "Argument",
|
||||
name: { kind: "Name", value: "after" },
|
||||
value: {
|
||||
kind: "Variable",
|
||||
name: { kind: "Name", value: "cursor" },
|
||||
},
|
||||
value: { kind: "IntValue", value: "10" },
|
||||
},
|
||||
],
|
||||
selectionSet: {
|
||||
@ -985,18 +984,7 @@ export const CompatSsoLoginList_UserFragmentDoc = {
|
||||
{
|
||||
kind: "Argument",
|
||||
name: { kind: "Name", value: "first" },
|
||||
value: {
|
||||
kind: "Variable",
|
||||
name: { kind: "Name", value: "count" },
|
||||
},
|
||||
},
|
||||
{
|
||||
kind: "Argument",
|
||||
name: { kind: "Name", value: "after" },
|
||||
value: {
|
||||
kind: "Variable",
|
||||
name: { kind: "Name", value: "cursor" },
|
||||
},
|
||||
value: { kind: "IntValue", value: "10" },
|
||||
},
|
||||
],
|
||||
selectionSet: {
|
||||
@ -1121,18 +1109,7 @@ export const OAuth2SessionList_UserFragmentDoc = {
|
||||
{
|
||||
kind: "Argument",
|
||||
name: { kind: "Name", value: "first" },
|
||||
value: {
|
||||
kind: "Variable",
|
||||
name: { kind: "Name", value: "count" },
|
||||
},
|
||||
},
|
||||
{
|
||||
kind: "Argument",
|
||||
name: { kind: "Name", value: "after" },
|
||||
value: {
|
||||
kind: "Variable",
|
||||
name: { kind: "Name", value: "cursor" },
|
||||
},
|
||||
value: { kind: "IntValue", value: "10" },
|
||||
},
|
||||
],
|
||||
selectionSet: {
|
||||
@ -1229,6 +1206,112 @@ export const UserEmail_EmailFragmentDoc = {
|
||||
},
|
||||
],
|
||||
} as unknown as DocumentNode<UserEmail_EmailFragment, unknown>;
|
||||
export const CurrentViewerQueryDocument = {
|
||||
kind: "Document",
|
||||
definitions: [
|
||||
{
|
||||
kind: "OperationDefinition",
|
||||
operation: "query",
|
||||
name: { kind: "Name", value: "CurrentViewerQuery" },
|
||||
selectionSet: {
|
||||
kind: "SelectionSet",
|
||||
selections: [
|
||||
{
|
||||
kind: "Field",
|
||||
name: { kind: "Name", value: "viewer" },
|
||||
selectionSet: {
|
||||
kind: "SelectionSet",
|
||||
selections: [
|
||||
{
|
||||
kind: "InlineFragment",
|
||||
typeCondition: {
|
||||
kind: "NamedType",
|
||||
name: { kind: "Name", value: "User" },
|
||||
},
|
||||
selectionSet: {
|
||||
kind: "SelectionSet",
|
||||
selections: [
|
||||
{ kind: "Field", name: { kind: "Name", value: "id" } },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
kind: "InlineFragment",
|
||||
typeCondition: {
|
||||
kind: "NamedType",
|
||||
name: { kind: "Name", value: "Anonymous" },
|
||||
},
|
||||
selectionSet: {
|
||||
kind: "SelectionSet",
|
||||
selections: [
|
||||
{ kind: "Field", name: { kind: "Name", value: "id" } },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
} as unknown as DocumentNode<
|
||||
CurrentViewerQueryQuery,
|
||||
CurrentViewerQueryQueryVariables
|
||||
>;
|
||||
export const CurrentViewerSessionQueryDocument = {
|
||||
kind: "Document",
|
||||
definitions: [
|
||||
{
|
||||
kind: "OperationDefinition",
|
||||
operation: "query",
|
||||
name: { kind: "Name", value: "CurrentViewerSessionQuery" },
|
||||
selectionSet: {
|
||||
kind: "SelectionSet",
|
||||
selections: [
|
||||
{
|
||||
kind: "Field",
|
||||
name: { kind: "Name", value: "viewerSession" },
|
||||
selectionSet: {
|
||||
kind: "SelectionSet",
|
||||
selections: [
|
||||
{
|
||||
kind: "InlineFragment",
|
||||
typeCondition: {
|
||||
kind: "NamedType",
|
||||
name: { kind: "Name", value: "BrowserSession" },
|
||||
},
|
||||
selectionSet: {
|
||||
kind: "SelectionSet",
|
||||
selections: [
|
||||
{ kind: "Field", name: { kind: "Name", value: "id" } },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
kind: "InlineFragment",
|
||||
typeCondition: {
|
||||
kind: "NamedType",
|
||||
name: { kind: "Name", value: "Anonymous" },
|
||||
},
|
||||
selectionSet: {
|
||||
kind: "SelectionSet",
|
||||
selections: [
|
||||
{ kind: "Field", name: { kind: "Name", value: "id" } },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
} as unknown as DocumentNode<
|
||||
CurrentViewerSessionQueryQuery,
|
||||
CurrentViewerSessionQueryQueryVariables
|
||||
>;
|
||||
export const AddEmailDocument = {
|
||||
kind: "Document",
|
||||
definitions: [
|
||||
@ -1417,7 +1500,6 @@ export const UserEmailListQueryDocument = {
|
||||
selectionSet: {
|
||||
kind: "SelectionSet",
|
||||
selections: [
|
||||
{ kind: "Field", name: { kind: "Name", value: "__typename" } },
|
||||
{ kind: "Field", name: { kind: "Name", value: "id" } },
|
||||
{
|
||||
kind: "Field",
|
||||
@ -1552,50 +1634,6 @@ export const UserEmailListQueryDocument = {
|
||||
UserEmailListQueryQuery,
|
||||
UserEmailListQueryQueryVariables
|
||||
>;
|
||||
export const CurrentUserQueryDocument = {
|
||||
kind: "Document",
|
||||
definitions: [
|
||||
{
|
||||
kind: "OperationDefinition",
|
||||
operation: "query",
|
||||
name: { kind: "Name", value: "CurrentUserQuery" },
|
||||
selectionSet: {
|
||||
kind: "SelectionSet",
|
||||
selections: [
|
||||
{
|
||||
kind: "Field",
|
||||
name: { kind: "Name", value: "viewer" },
|
||||
selectionSet: {
|
||||
kind: "SelectionSet",
|
||||
selections: [
|
||||
{
|
||||
kind: "InlineFragment",
|
||||
typeCondition: {
|
||||
kind: "NamedType",
|
||||
name: { kind: "Name", value: "User" },
|
||||
},
|
||||
selectionSet: {
|
||||
kind: "SelectionSet",
|
||||
selections: [
|
||||
{
|
||||
kind: "Field",
|
||||
name: { kind: "Name", value: "__typename" },
|
||||
},
|
||||
{ kind: "Field", name: { kind: "Name", value: "id" } },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
} as unknown as DocumentNode<
|
||||
CurrentUserQueryQuery,
|
||||
CurrentUserQueryQueryVariables
|
||||
>;
|
||||
export const AccountQueryDocument = {
|
||||
kind: "Document",
|
||||
definitions: [
|
||||
@ -1726,27 +1764,6 @@ export const HomeQueryDocument = {
|
||||
kind: "OperationDefinition",
|
||||
operation: "query",
|
||||
name: { kind: "Name", value: "HomeQuery" },
|
||||
variableDefinitions: [
|
||||
{
|
||||
kind: "VariableDefinition",
|
||||
variable: {
|
||||
kind: "Variable",
|
||||
name: { kind: "Name", value: "count" },
|
||||
},
|
||||
type: {
|
||||
kind: "NonNullType",
|
||||
type: { kind: "NamedType", name: { kind: "Name", value: "Int" } },
|
||||
},
|
||||
},
|
||||
{
|
||||
kind: "VariableDefinition",
|
||||
variable: {
|
||||
kind: "Variable",
|
||||
name: { kind: "Name", value: "cursor" },
|
||||
},
|
||||
type: { kind: "NamedType", name: { kind: "Name", value: "String" } },
|
||||
},
|
||||
],
|
||||
selectionSet: {
|
||||
kind: "SelectionSet",
|
||||
selections: [
|
||||
@ -1895,18 +1912,7 @@ export const HomeQueryDocument = {
|
||||
{
|
||||
kind: "Argument",
|
||||
name: { kind: "Name", value: "first" },
|
||||
value: {
|
||||
kind: "Variable",
|
||||
name: { kind: "Name", value: "count" },
|
||||
},
|
||||
},
|
||||
{
|
||||
kind: "Argument",
|
||||
name: { kind: "Name", value: "after" },
|
||||
value: {
|
||||
kind: "Variable",
|
||||
name: { kind: "Name", value: "cursor" },
|
||||
},
|
||||
value: { kind: "IntValue", value: "10" },
|
||||
},
|
||||
],
|
||||
selectionSet: {
|
||||
@ -1964,18 +1970,7 @@ export const HomeQueryDocument = {
|
||||
{
|
||||
kind: "Argument",
|
||||
name: { kind: "Name", value: "first" },
|
||||
value: {
|
||||
kind: "Variable",
|
||||
name: { kind: "Name", value: "count" },
|
||||
},
|
||||
},
|
||||
{
|
||||
kind: "Argument",
|
||||
name: { kind: "Name", value: "after" },
|
||||
value: {
|
||||
kind: "Variable",
|
||||
name: { kind: "Name", value: "cursor" },
|
||||
},
|
||||
value: { kind: "IntValue", value: "10" },
|
||||
},
|
||||
],
|
||||
selectionSet: {
|
||||
@ -2037,18 +2032,7 @@ export const HomeQueryDocument = {
|
||||
{
|
||||
kind: "Argument",
|
||||
name: { kind: "Name", value: "first" },
|
||||
value: {
|
||||
kind: "Variable",
|
||||
name: { kind: "Name", value: "count" },
|
||||
},
|
||||
},
|
||||
{
|
||||
kind: "Argument",
|
||||
name: { kind: "Name", value: "after" },
|
||||
value: {
|
||||
kind: "Variable",
|
||||
name: { kind: "Name", value: "cursor" },
|
||||
},
|
||||
value: { kind: "IntValue", value: "10" },
|
||||
},
|
||||
],
|
||||
selectionSet: {
|
||||
|
@ -17,33 +17,35 @@ import { cacheExchange } from "@urql/exchange-graphcache";
|
||||
|
||||
import schema from "./gql/schema";
|
||||
import type { MutationAddEmailArgs } from "./gql/graphql";
|
||||
import { devtoolsExchange } from "@urql/devtools";
|
||||
|
||||
const cache = cacheExchange({
|
||||
schema,
|
||||
updates: {
|
||||
Mutation: {
|
||||
addEmail: (result, args: MutationAddEmailArgs, cache, _info) => {
|
||||
const key = cache.keyOfEntity({
|
||||
__typename: "User",
|
||||
id: args.input.userId,
|
||||
});
|
||||
|
||||
// Invalidate the emails field on the User object so that it gets refetched
|
||||
cache
|
||||
.inspectFields(key)
|
||||
.filter((field) => field.fieldName === "emails")
|
||||
.forEach((field) => {
|
||||
cache.invalidate(key, field.fieldName, field.arguments);
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const client = createClient({
|
||||
url: "/graphql",
|
||||
// XXX: else queries don't refetch on cache invalidation for some reason
|
||||
requestPolicy: "cache-and-network",
|
||||
exchanges: [
|
||||
cacheExchange({
|
||||
schema,
|
||||
updates: {
|
||||
Mutation: {
|
||||
addEmail: (result, args: MutationAddEmailArgs, cache, _info) => {
|
||||
const key = cache.keyOfEntity({
|
||||
__typename: "User",
|
||||
id: args.input.userId,
|
||||
});
|
||||
|
||||
// Invalidate the emails field on the User object so that it gets refetched
|
||||
cache
|
||||
.inspectFields(key)
|
||||
.filter((field) => field.fieldName === "emails")
|
||||
.forEach((field) => {
|
||||
cache.invalidate(key, field.fieldName, field.arguments);
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
fetchExchange,
|
||||
],
|
||||
exchanges: import.meta.env.DEV
|
||||
? [devtoolsExchange, cache, fetchExchange]
|
||||
: [cache, fetchExchange],
|
||||
});
|
||||
|
@ -24,7 +24,7 @@ import { HydrateAtoms } from "./atoms";
|
||||
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
|
||||
<React.StrictMode>
|
||||
<Provider>
|
||||
<DevTools />
|
||||
{import.meta.env.DEV && <DevTools />}
|
||||
<HydrateAtoms>
|
||||
<React.Suspense fallback={<LoadingScreen />}>
|
||||
<Router />
|
||||
|
@ -21,19 +21,7 @@ import { graphql } from "../gql";
|
||||
import UserEmailList from "../components/UserEmailList";
|
||||
import { Title } from "../components/Typography";
|
||||
import AddEmailForm from "../components/AddEmailForm";
|
||||
|
||||
const CURRENT_USER_QUERY = graphql(/* GraphQL */ `
|
||||
query CurrentUserQuery {
|
||||
viewer {
|
||||
... on User {
|
||||
__typename
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
const currentUserAtom = atomWithQuery({ query: CURRENT_USER_QUERY });
|
||||
import { currentUserIdAtom } from "../atoms";
|
||||
|
||||
const QUERY = graphql(/* GraphQL */ `
|
||||
query AccountQuery($id: ID!) {
|
||||
@ -61,11 +49,11 @@ const UserAccount: React.FC<{ id: string }> = ({ id }) => {
|
||||
};
|
||||
|
||||
const CurrentUserAccount: React.FC = () => {
|
||||
const result = useAtomValue(currentUserAtom);
|
||||
if (result.data?.viewer?.__typename === "User") {
|
||||
const userId = useAtomValue(currentUserIdAtom);
|
||||
if (userId !== null) {
|
||||
return (
|
||||
<div className="w-96 mx-auto">
|
||||
<UserAccount id={result.data.viewer.id} />
|
||||
<UserAccount id={userId} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import Typography from "../components/Typography";
|
||||
import { graphql } from "../gql";
|
||||
|
||||
const QUERY = graphql(/* GraphQL */ `
|
||||
query HomeQuery($count: Int!, $cursor: String) {
|
||||
query HomeQuery {
|
||||
# eslint-disable-next-line @graphql-eslint/no-deprecated
|
||||
currentBrowserSession {
|
||||
id
|
||||
@ -40,7 +40,6 @@ const QUERY = graphql(/* GraphQL */ `
|
||||
|
||||
const homeDataAtom = atomWithQuery({
|
||||
query: QUERY,
|
||||
getVariables: () => ({ count: 10 }),
|
||||
});
|
||||
|
||||
const Home: React.FC = () => {
|
||||
|
Reference in New Issue
Block a user