diff --git a/.graphclientrc.yml b/.graphclientrc.yml index af6a5232..a505b50d 100644 --- a/.graphclientrc.yml +++ b/.graphclientrc.yml @@ -2,9 +2,8 @@ sources: - name: grant-ships handler: graphql: - endpoint: https://indexer.bigdevenergy.link/3a96753/v1/graphql + endpoint: https://indexer.bigdevenergy.link/e09c75f/v1/graphql # endpoint: http://localhost:8080/v1/graphql - # endpoint: https://{context.apiEndpoint:api.studio.thegraph.com/query/41101/grant-ships-arb/version/latest} # - name: gs-voting # handler: # graphql: diff --git a/src/.graphclient/index.ts b/src/.graphclient/index.ts index 06ed4c53..53b5cebb 100644 --- a/src/.graphclient/index.ts +++ b/src/.graphclient/index.ts @@ -9762,7 +9762,7 @@ const grantShipsTransforms = []; const additionalTypeDefs = [] as any[]; const grantShipsHandler = new GraphqlHandler({ name: "grant-ships", - config: {"endpoint":"https://indexer.bigdevenergy.link/3a96753/v1/graphql"}, + config: {"endpoint":"https://indexer.bigdevenergy.link/e09c75f/v1/graphql"}, baseDir, cache, pubsub, @@ -9916,11 +9916,11 @@ const merger = new(BareMerger as any)({ }, location: 'GetShipPoolIdDocument.graphql' },{ - document: GetUpdatesDocument, + document: GetUpdatesQueryDocument, get rawSDL() { - return printWithCache(GetUpdatesDocument); + return printWithCache(GetUpdatesQueryDocument); }, - location: 'GetUpdatesDocument.graphql' + location: 'GetUpdatesQueryDocument.graphql' },{ document: GetUserDataDocument, get rawSDL() { @@ -10359,13 +10359,13 @@ export type getShipPoolIdQueryVariables = Exact<{ export type getShipPoolIdQuery = { GrantShip: Array> }; -export type getUpdatesQueryVariables = Exact<{ +export type getUpdatesQueryQueryVariables = Exact<{ entityAddress: Scalars['String']; scope?: InputMaybe; }>; -export type getUpdatesQuery = { Update: Array<( +export type getUpdatesQueryQuery = { Update: Array<( Pick & { content?: Maybe> } )> }; @@ -10421,7 +10421,7 @@ export type shipPageQueryQueryVariables = Exact<{ export type shipPageQueryQuery = { GrantShip: Array<( - Pick + Pick & { profileMetadata?: Maybe>, alloProfileMembers?: Maybe> } )> }; @@ -10987,8 +10987,8 @@ export const getShipPoolIdDocument = gql` } } ` as unknown as DocumentNode; -export const getUpdatesDocument = gql` - query getUpdates($entityAddress: String!, $scope: Int) { +export const getUpdatesQueryDocument = gql` + query getUpdatesQuery($entityAddress: String!, $scope: Int) { Update( where: {entityAddress: {_eq: $entityAddress}, scope: {_eq: $scope}} order_by: {timestamp: desc} @@ -10996,7 +10996,7 @@ export const getUpdatesDocument = gql` ...UpdateBody } } - ${UpdateBodyFragmentDoc}` as unknown as DocumentNode; + ${UpdateBodyFragmentDoc}` as unknown as DocumentNode; export const getUserDataDocument = gql` query getUserData($id: String!, $chainId: Int!) { projects: Project(where: {owner: {_eq: $id}, chainId: {_eq: $chainId}}) { @@ -11063,6 +11063,7 @@ export const shipPageQueryDocument = gql` query shipPageQuery($id: String!) { GrantShip(where: {id: {_eq: $id}}) { ...BaseShipData + hatId } } ${BaseShipDataFragmentDoc}` as unknown as DocumentNode; @@ -11165,8 +11166,8 @@ export function getSdk(requester: Requester) { getShipPoolId(variables: getShipPoolIdQueryVariables, options?: C): Promise { return requester(getShipPoolIdDocument, variables, options) as Promise; }, - getUpdates(variables: getUpdatesQueryVariables, options?: C): Promise { - return requester(getUpdatesDocument, variables, options) as Promise; + getUpdatesQuery(variables: getUpdatesQueryQueryVariables, options?: C): Promise { + return requester(getUpdatesQueryDocument, variables, options) as Promise; }, getUserData(variables: getUserDataQueryVariables, options?: C): Promise { return requester(getUserDataDocument, variables, options) as Promise; diff --git a/src/components/PostDrawer.tsx b/src/components/PostDrawer.tsx index b01051d3..b7dd5df8 100644 --- a/src/components/PostDrawer.tsx +++ b/src/components/PostDrawer.tsx @@ -15,16 +15,17 @@ import { pinJSONToIPFS } from '../utils/ipfs/pin'; import { notifications } from '@mantine/notifications'; import { TxButton } from './TxButton'; import { PlayerAvatar } from './PlayerAvatar'; -import { GAME_MANAGER } from '../constants/gameSetup'; +import { GAME_MANAGER, ZER0_ADDRESS } from '../constants/gameSetup'; import { RTEditor } from './RTEditor'; import { PageDrawer } from './PageDrawer'; +import GrantShipAbi from '../abi/GrantShip.json'; +import { Address } from 'viem'; type PostDrawerProps = { avatarImg?: string; name?: string; posterType: Player; posterId: string; - postType: string; refetch: () => void; content?: Content; }; @@ -32,9 +33,8 @@ type PostDrawerProps = { export const PostDrawer = ({ avatarImg, name, - postType, + posterType, posterId, - refetch, content = { type: 'doc', content: [] }, }: PostDrawerProps) => { @@ -48,20 +48,18 @@ export const PostDrawer = ({ ], onUpdate({ editor }) { const newContent = editor.getJSON(); - localStorage.setItem(postId, JSON.stringify(newContent)); + localStorage.setItem(posterId, JSON.stringify(newContent)); }, content, }); const { tx } = useTx(); - const postId = `${postType}-${posterId}`; - useEffect(() => { - const draft = localStorage.getItem(postId); + const draft = localStorage.getItem(posterId); if (editor && draft) { editor.commands.setContent(JSON.parse(draft)); } - }, [postId, editor]); + }, [posterId, editor]); const isOpen = location.pathname.includes('post'); @@ -93,38 +91,47 @@ export const PostDrawer = ({ onClose(); - // tag: TAG tells the indexer to await for instructions - // action: PROJECT_POST action code to be executed index side - // postId: - // - posterId: the id of the poster, in this case it's the profileID - /// - GAME_MANAGER.ADDRESS ensures that this post is only available within this game scope - - const tag = `TAG:PROJECT_POST:${postId}:${GAME_MANAGER.ADDRESS}`; + if (posterType === Player.Project) { + const tag = `TAG:PROJECT_POST:${GAME_MANAGER.ADDRESS}`; - tx({ - writeContractParams: { - abi: AlloPoster, - address: ADDR.ALLO_POSTER, - functionName: 'postUpdate', - args: [tag, posterId, [1n, pinRes.IpfsHash]], - }, - writeContractOptions: { - onPollSuccess() { - refetch(); - localStorage.removeItem(postId); + tx({ + writeContractParams: { + abi: AlloPoster, + address: ADDR.ALLO_POSTER, + functionName: 'postUpdate', + args: [tag, posterId, [1n, pinRes.IpfsHash]], }, - }, - }); + writeContractOptions: { + onPollSuccess() { + refetch(); + localStorage.removeItem(posterId); + }, + }, + }); + } else if (Player.Ship === posterType) { + const tag = `TAG:SHIP_POST:${GAME_MANAGER.ADDRESS}`; + + tx({ + writeContractParams: { + abi: GrantShipAbi, + address: posterId as Address, + functionName: 'postUpdate', + args: [tag, [1n, pinRes.IpfsHash], ZER0_ADDRESS], + }, + writeContractOptions: { + onPollSuccess() { + refetch?.(); + localStorage.removeItem(posterId); + }, + }, + }); + } }; return ( - + } onClick={postContent}> Post diff --git a/src/components/UpdatesPanel.tsx b/src/components/UpdatesPanel.tsx new file mode 100644 index 00000000..7e7ffa1c --- /dev/null +++ b/src/components/UpdatesPanel.tsx @@ -0,0 +1,72 @@ +import { Box, Divider, Group, Skeleton, Text } from '@mantine/core'; +import { ResolvedUpdate } from '../resolvers/updates'; +import { Display } from './Display'; +import { PlayerAvatar } from './PlayerAvatar'; +import { secondsToShortRelativeTime } from '../utils/time'; +import { Player } from '../types/ui'; +import { RTDisplay } from './RTDisplay'; + +export const UpdatesPanel = ({ + updates, + name, + isLoading, + error, + imgUrl, + playerType, +}: { + playerType: Player; + updates?: ResolvedUpdate[]; + imgUrl?: string; + name: string; + isLoading: boolean; + error: Error | null; +}) => { + if (isLoading) { + return ( + + + + + + ); + } + + if (error) { + return ; + } + + if (!updates || updates?.length === 0) { + return ( + + ); + } + + return ( + + {updates.map((update) => ( + + + + + · + + + {secondsToShortRelativeTime(update.timestamp)} + + + + + + + + ))} + + ); +}; diff --git a/src/components/projectItems/ProjectUpdatesPanel.tsx b/src/components/projectItems/ProjectUpdatesPanel.tsx index 11e04eb1..4a304c74 100644 --- a/src/components/projectItems/ProjectUpdatesPanel.tsx +++ b/src/components/projectItems/ProjectUpdatesPanel.tsx @@ -15,7 +15,6 @@ // import { FeedSkeletonCard } from '../skeletons'; // import { AppAlert } from '../UnderContruction'; // import { IconX } from '@tabler/icons-react'; -// import { getUpdates } from '../../queries/getUpdates'; // import { FeedCard } from '../feed/FeedCard'; // import { DashGrant } from '../../resolvers/grantResolvers'; // import { useState } from 'react'; diff --git a/src/graphql/newQueries/getUpdates.graphql b/src/graphql/newQueries/getUpdates.graphql index f68dc37c..3f6b7cab 100644 --- a/src/graphql/newQueries/getUpdates.graphql +++ b/src/graphql/newQueries/getUpdates.graphql @@ -1,4 +1,4 @@ -query getUpdates($entityAddress: String!, $scope: Int) { +query getUpdatesQuery($entityAddress: String!, $scope: Int) { Update( where: { entityAddress: { _eq: $entityAddress }, scope: { _eq: $scope } } order_by: { timestamp: desc } diff --git a/src/graphql/newQueries/shipPage.graphql b/src/graphql/newQueries/shipPage.graphql index f164912b..8fc40414 100644 --- a/src/graphql/newQueries/shipPage.graphql +++ b/src/graphql/newQueries/shipPage.graphql @@ -1,5 +1,6 @@ query shipPageQuery($id: String!) { GrantShip(where: { id: { _eq: $id } }) { ...BaseShipData + hatId } } diff --git a/src/pages/Project.tsx b/src/pages/Project.tsx index 9d73fd27..e72fca19 100644 --- a/src/pages/Project.tsx +++ b/src/pages/Project.tsx @@ -3,12 +3,10 @@ import { Avatar, Box, Collapse, - Divider, Flex, Group, Loader, Paper, - Skeleton, Stack, Tabs, Text, @@ -55,11 +53,7 @@ import { MilestoneProgress } from '../components/projectItems/MilestoneProgress' import { GrantCard } from '../components/grant/GrantCard'; import { GrantInvite } from '../components/projectItems/GrantInvite'; import { getUpdates } from '../queries/getUpdates'; -import { Display } from '../components/Display'; -import { PlayerAvatar } from '../components/PlayerAvatar'; -import { RTDisplay } from '../components/RTDisplay'; -import { secondsToShortRelativeTime } from '../utils/time'; -import { ResolvedUpdate } from '../resolvers/updates'; +import { UpdatesPanel } from '../components/UpdatesPanel'; const infiniteWrapper = async ({ pageParam }: any) => { const result = await getEntityFeed(pageParam); @@ -368,12 +362,13 @@ export const Project = () => { )} - @@ -458,7 +453,6 @@ export const Project = () => { name={project.name} posterType={Player.Project} posterId={project.profileId} - postType="richtext/post" refetch={() => { refetchUpdates(); }} @@ -475,67 +469,3 @@ export const Project = () => { ); }; - -const ProjectUpdatesPanel = ({ - updates, - projectName, - isLoading, - error, - imgUrl, -}: { - updates?: ResolvedUpdate[]; - imgUrl?: string; - - projectName: string; - isLoading: boolean; - error: Error | null; -}) => { - if (isLoading) { - return ( - - - - - - ); - } - - if (error) { - return ; - } - - if (!updates || updates?.length === 0) { - return ( - - ); - } - - return ( - - {updates.map((update) => ( - - - - - · - - - {secondsToShortRelativeTime(update.timestamp)} - - - - - - - - ))} - - ); -}; diff --git a/src/pages/Ship.tsx b/src/pages/Ship.tsx index d4349c9a..8c0f9e97 100644 --- a/src/pages/Ship.tsx +++ b/src/pages/Ship.tsx @@ -23,7 +23,7 @@ import { DetailsPanel } from '../components/shipItems/DetailsPanel'; import { useParams } from 'react-router-dom'; import { GAME_MANAGER, GAME_TOKEN } from '../constants/gameSetup'; import { AddressAvatarGroup } from '../components/AddressAvatar'; -import { GameStatus, GrantStatus } from '../types/common'; +import { GameStatus, GrantStatus, UpdateScope } from '../types/common'; import { getShipPageData } from '../queries/getShipPage'; import { useQuery, useInfiniteQuery } from '@tanstack/react-query'; @@ -33,7 +33,6 @@ import { SingleItemPageSkeleton } from '../components/skeletons'; import { getEntityFeed } from '../queries/getFeed'; import { formatEther } from 'viem'; import { useUserData } from '../hooks/useUserState'; -// import { UpdatesPanel } from '../components/shipItems/UpdatesPanel'; import { SHIP_STATUS_INFO } from '../constants/copy'; import { useLaptop, useTablet } from '../hooks/useBreakpoint'; import { useMemo } from 'react'; @@ -41,6 +40,11 @@ import { ShipBadge } from '../components/RoleBadges'; import { ApplyButton } from '../components/shipItems/ApplyButton'; import { getShipGrants } from '../queries/getShipGrants'; import { GrantCard } from '../components/grant/GrantCard'; +import { PostDrawer } from '../components/PostDrawer'; +import { Player } from '../types/ui'; +import { PostAffix } from '../components/PostAffix'; +import { getUpdates } from '../queries/getUpdates'; +import { UpdatesPanel } from '../components/UpdatesPanel'; const infiniteWrapper = async ({ pageParam }: any) => { const result = await getEntityFeed(pageParam); @@ -91,6 +95,17 @@ export const Ship = () => { enabled: !!id, }); + const { + data: updates, + error: updatesError, + isLoading: updatesLoading, + refetch: refetchUpdates, + } = useQuery({ + queryKey: [`project-updates-${id}`], + queryFn: () => getUpdates(id as string, UpdateScope.Ship), + enabled: !!id, + }); + const { userData } = useUserData(); const { @@ -264,13 +279,16 @@ export const Ship = () => { - {/* + - */} + {grants?.map((grant) => ( @@ -337,6 +355,18 @@ export const Ship = () => { )} + {isShipOperator && } + {isShipOperator && ship.shipContractAddress && ( + { + refetchUpdates(); + }} + /> + )} ); }; diff --git a/src/queries/getShipPage.ts b/src/queries/getShipPage.ts index d2657b56..69b4d065 100644 --- a/src/queries/getShipPage.ts +++ b/src/queries/getShipPage.ts @@ -19,7 +19,7 @@ export const getShipPageData = async (id: string): Promise => { if (!GrantShip?.[0]) { throw new Error('No ship found'); } - + console.log('GrantShip', GrantShip); const grantShip = GrantShip[0]; const pointer = grantShip?.profileMetadata?.pointer; @@ -78,6 +78,7 @@ export const getShipPageData = async (id: string): Promise => { totalRoundAmount: grantShip.totalRoundAmount || '0', shipContractAddress: grantShip.shipContractAddress, members, + hatId: grantShip.hatId || undefined, details: { thesis: applyData?.thesis, apply: applyData?.guidelines, diff --git a/src/queries/getUpdates.ts b/src/queries/getUpdates.ts index 7ce55ca7..476a28e6 100644 --- a/src/queries/getUpdates.ts +++ b/src/queries/getUpdates.ts @@ -4,9 +4,9 @@ import { UpdateScope } from '../types/common'; export const getUpdates = async (entityAddress: string, scope: UpdateScope) => { try { - const { getUpdates } = getBuiltGraphSDK(); + const { getUpdatesQuery } = getBuiltGraphSDK(); - const result = await getUpdates({ + const result = await getUpdatesQuery({ entityAddress: entityAddress, scope: scope, }); diff --git a/src/routes.tsx b/src/routes.tsx index 54db5f7f..7e5909a5 100644 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -30,7 +30,7 @@ export const ClientRoutes = () => { } /> } /> } /> - } /> + } /> } /> } />