{
- e.currentTarget.style.opacity = "1"
- }}
- onMouseLeave={(e) => {
- e.currentTarget.style.opacity = "0.2"
- }}
- >
+
(e.currentTarget.style.opacity = "1")}
+ onMouseLeave={(e) => (e.currentTarget.style.opacity = "0.4")}
+ >
+
{}}
size={35}
position={{ x: 0, y: 0 }}
className="hover:opacity-80 transition-opacity"
/>
+
+ {hasNotification && (
+
+
+
+
+ )}
)
}
-export default PlasmoInline
+const queryClient = new QueryClient()
+
+const Wrapper = () => {
+ const [address, setAddress] = useState("")
+
+ useEffect(() => {
+ chrome.storage.local.get("metamask-account", (res) => {
+ const addr = res["metamask-account"]
+ if (addr) {
+ console.log("✅ Metamask account loaded:", addr)
+ setAddress(addr)
+ }
+ })
+ }, [])
+
+ console.log("🧪 Rendering Wrapper with address:", address)
+
+ return (
+
+
+
+
+
+ )
+}
+
+export default Wrapper
diff --git a/src/graphql/src/apollo-subscription-client.ts b/src/graphql/src/apollo-subscription-client.ts
new file mode 100644
index 00000000..4e30d9e5
--- /dev/null
+++ b/src/graphql/src/apollo-subscription-client.ts
@@ -0,0 +1,62 @@
+import { ApolloClient, InMemoryCache, split } from "@apollo/client"
+import { GraphQLWsLink } from "@apollo/client/link/subscriptions"
+import { createClient } from "graphql-ws"
+import { getMainDefinition } from "@apollo/client/utilities"
+import { HttpLink } from "@apollo/client"
+
+
+const ENV = "dev" // "local" | "dev" | "prod"
+
+const ENDPOINTS = {
+ local: {
+ http: "http://localhost:8080/v1/graphql",
+ ws: "ws://localhost:8080/v1/graphql"
+ },
+ dev: {
+ http: "https://prod.base-sepolia.intuition-api.com/v1/graphql",
+ ws: "wss://prod.base-sepolia.intuition-api.com/v1/graphql"
+ },
+ prod: {
+ http: "https://prod.base.intuition-api.com/v1/graphql",
+ ws: "wss://prod.base.intuition-api.com/v1/graphql"
+ }
+}
+
+const { http, ws } = ENDPOINTS[ENV]
+
+const httpLink = new HttpLink({
+ uri: http,
+ headers: {
+ "Content-Type": "application/json"
+
+ }
+})
+
+const wsLink = new GraphQLWsLink(
+ createClient({
+ url: ws,
+ connectionParams: {
+ headers: {
+
+ }
+ }
+ })
+)
+
+
+const splitLink = split(
+ ({ query }) => {
+ const definition = getMainDefinition(query)
+ return (
+ definition.kind === "OperationDefinition" &&
+ definition.operation === "subscription"
+ )
+ },
+ wsLink,
+ httpLink
+)
+
+export const apolloSubscriptionClient = new ApolloClient({
+ link: splitLink,
+ cache: new InMemoryCache()
+})
diff --git a/src/graphql/src/generated/index.ts b/src/graphql/src/generated/index.ts
index 75357c18..18cde6c7 100644
--- a/src/graphql/src/generated/index.ts
+++ b/src/graphql/src/generated/index.ts
@@ -11480,6 +11480,18 @@ export type GetFollowersFromAddressQuery = {
}>
}
+export type GetFollowingIdsQueryVariables = Exact<{
+ address: Scalars["String"]["input"]
+}>
+
+export type GetFollowingIdsQuery = {
+ __typename?: "query_root"
+ triples: Array<{
+ __typename?: "triples"
+ object: { __typename?: "atoms"; id: any }
+ }>
+}
+
export type GetFollowingsFromAddressQueryVariables = Exact<{
address: Scalars["String"]["input"]
}>
@@ -13925,6 +13937,15 @@ export type EventsSubscription = {
}>
}
+export type FollowerActivitySubscriptionVariables = Exact<{
+ limit: Scalars["Int"]["input"]
+}>
+
+export type FollowerActivitySubscription = {
+ __typename?: "subscription_root"
+ events: Array<{ __typename?: "events"; type: any; block_timestamp: any }>
+}
+
export const AccountClaimsAggregateFragmentDoc = `
fragment AccountClaimsAggregate on accounts {
claims_aggregate(order_by: {shares: desc}) {
@@ -15823,6 +15844,93 @@ useGetFollowersFromAddressQuery.fetcher = (
options
)
+export const GetFollowingIdsDocument = `
+ query getFollowingIds($address: String!) {
+ triples(
+ where: {predicate: {label: {_eq: "follow"}}, subject: {accounts: {id: {_eq: $address}}}}
+ ) {
+ object {
+ id
+ }
+ }
+}
+ `
+
+export const useGetFollowingIdsQuery = <
+ TData = GetFollowingIdsQuery,
+ TError = unknown
+>(
+ variables: GetFollowingIdsQueryVariables,
+ options?: Omit<
+ UseQueryOptions
,
+ "queryKey"
+ > & {
+ queryKey?: UseQueryOptions["queryKey"]
+ }
+) => {
+ return useQuery({
+ queryKey: ["getFollowingIds", variables],
+ queryFn: fetcher(
+ GetFollowingIdsDocument,
+ variables
+ ),
+ ...options
+ })
+}
+
+useGetFollowingIdsQuery.document = GetFollowingIdsDocument
+
+useGetFollowingIdsQuery.getKey = (variables: GetFollowingIdsQueryVariables) => [
+ "getFollowingIds",
+ variables
+]
+
+export const useInfiniteGetFollowingIdsQuery = <
+ TData = InfiniteData,
+ TError = unknown
+>(
+ variables: GetFollowingIdsQueryVariables,
+ options: Omit<
+ UseInfiniteQueryOptions,
+ "queryKey"
+ > & {
+ queryKey?: UseInfiniteQueryOptions<
+ GetFollowingIdsQuery,
+ TError,
+ TData
+ >["queryKey"]
+ }
+) => {
+ return useInfiniteQuery(
+ (() => {
+ const { queryKey: optionsQueryKey, ...restOptions } = options
+ return {
+ queryKey: optionsQueryKey ?? ["getFollowingIds.infinite", variables],
+ queryFn: (metaData) =>
+ fetcher(
+ GetFollowingIdsDocument,
+ { ...variables, ...(metaData.pageParam ?? {}) }
+ )(),
+ ...restOptions
+ }
+ })()
+ )
+}
+
+useInfiniteGetFollowingIdsQuery.getKey = (
+ variables: GetFollowingIdsQueryVariables
+) => ["getFollowingIds.infinite", variables]
+
+useGetFollowingIdsQuery.fetcher = (
+ variables: GetFollowingIdsQueryVariables,
+ options?: RequestInit["headers"]
+) =>
+ fetcher(
+ GetFollowingIdsDocument,
+ variables,
+ options
+ )
+
export const GetFollowingsFromAddressDocument = `
query getFollowingsFromAddress($address: String!) {
following(args: {address: $address}) {
@@ -18627,6 +18735,18 @@ ${VaultDetailsWithFilteredPositionsFragmentDoc}
${VaultBasicDetailsFragmentDoc}
${VaultFilteredPositionsFragmentDoc}
${PositionFieldsFragmentDoc}`
+export const FollowerActivityDocument = `
+ subscription FollowerActivity($limit: Int!) {
+ events(
+ where: {type: {_in: ["ClaimCreated", "AtomCreated"]}}
+ order_by: [{block_number: desc}]
+ limit: $limit
+ ) {
+ type
+ block_timestamp
+ }
+}
+ `
export const AccountClaimsAggregate = {
kind: "Document",
definitions: [
@@ -27609,6 +27729,129 @@ export const GetFollowersFromAddress = {
}
]
} as unknown as DocumentNode
+export const GetFollowingIds = {
+ kind: "Document",
+ definitions: [
+ {
+ kind: "OperationDefinition",
+ operation: "query",
+ name: { kind: "Name", value: "getFollowingIds" },
+ variableDefinitions: [
+ {
+ kind: "VariableDefinition",
+ variable: {
+ kind: "Variable",
+ name: { kind: "Name", value: "address" }
+ },
+ type: {
+ kind: "NonNullType",
+ type: { kind: "NamedType", name: { kind: "Name", value: "String" } }
+ }
+ }
+ ],
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "triples" },
+ arguments: [
+ {
+ kind: "Argument",
+ name: { kind: "Name", value: "where" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "predicate" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "label" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "_eq" },
+ value: {
+ kind: "StringValue",
+ value: "follow",
+ block: false
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "subject" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "accounts" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "id" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "_eq" },
+ value: {
+ kind: "Variable",
+ name: {
+ kind: "Name",
+ value: "address"
+ }
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ],
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "object" },
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ { kind: "Field", name: { kind: "Name", value: "id" } }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+} as unknown as DocumentNode
export const GetFollowingsFromAddress = {
kind: "Document",
definitions: [
@@ -36603,3 +36846,111 @@ export const Events = {
}
]
} as unknown as DocumentNode
+export const FollowerActivity = {
+ kind: "Document",
+ definitions: [
+ {
+ kind: "OperationDefinition",
+ operation: "subscription",
+ name: { kind: "Name", value: "FollowerActivity" },
+ variableDefinitions: [
+ {
+ kind: "VariableDefinition",
+ variable: {
+ kind: "Variable",
+ name: { kind: "Name", value: "limit" }
+ },
+ type: {
+ kind: "NonNullType",
+ type: { kind: "NamedType", name: { kind: "Name", value: "Int" } }
+ }
+ }
+ ],
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "events" },
+ arguments: [
+ {
+ kind: "Argument",
+ name: { kind: "Name", value: "where" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "type" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "_in" },
+ value: {
+ kind: "ListValue",
+ values: [
+ {
+ kind: "StringValue",
+ value: "ClaimCreated",
+ block: false
+ },
+ {
+ kind: "StringValue",
+ value: "AtomCreated",
+ block: false
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ kind: "Argument",
+ name: { kind: "Name", value: "order_by" },
+ value: {
+ kind: "ListValue",
+ values: [
+ {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "block_number" },
+ value: { kind: "EnumValue", value: "desc" }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ kind: "Argument",
+ name: { kind: "Name", value: "limit" },
+ value: {
+ kind: "Variable",
+ name: { kind: "Name", value: "limit" }
+ }
+ }
+ ],
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ { kind: "Field", name: { kind: "Name", value: "type" } },
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "block_timestamp" }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+} as unknown as DocumentNode
diff --git a/src/graphql/src/generated/subscriptions.ts b/src/graphql/src/generated/subscriptions.ts
index 7893be46..0a42a069 100644
--- a/src/graphql/src/generated/subscriptions.ts
+++ b/src/graphql/src/generated/subscriptions.ts
@@ -11500,6 +11500,18 @@ export type GetFollowersFromAddressQuery = {
}>
}
+export type GetFollowingIdsQueryVariables = Exact<{
+ address: Scalars["String"]["input"]
+}>
+
+export type GetFollowingIdsQuery = {
+ __typename?: "query_root"
+ triples: Array<{
+ __typename?: "triples"
+ object: { __typename?: "atoms"; id: any }
+ }>
+}
+
export type GetFollowingsFromAddressQueryVariables = Exact<{
address: Scalars["String"]["input"]
}>
@@ -13945,6 +13957,15 @@ export type EventsSubscription = {
}>
}
+export type FollowerActivitySubscriptionVariables = Exact<{
+ limit: Scalars["Int"]["input"]
+}>
+
+export type FollowerActivitySubscription = {
+ __typename?: "subscription_root"
+ events: Array<{ __typename?: "events"; type: any; block_timestamp: any }>
+}
+
export const AccountClaimsAggregateFragmentDoc = {
kind: "Document",
definitions: [
@@ -23457,6 +23478,204 @@ export type GetFollowersFromAddressQueryResult = Apollo.QueryResult<
GetFollowersFromAddressQuery,
GetFollowersFromAddressQueryVariables
>
+export const GetFollowingIdsDocument = {
+ kind: "Document",
+ definitions: [
+ {
+ kind: "OperationDefinition",
+ operation: "query",
+ name: { kind: "Name", value: "getFollowingIds" },
+ variableDefinitions: [
+ {
+ kind: "VariableDefinition",
+ variable: {
+ kind: "Variable",
+ name: { kind: "Name", value: "address" }
+ },
+ type: {
+ kind: "NonNullType",
+ type: { kind: "NamedType", name: { kind: "Name", value: "String" } }
+ }
+ }
+ ],
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "triples" },
+ arguments: [
+ {
+ kind: "Argument",
+ name: { kind: "Name", value: "where" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "predicate" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "label" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "_eq" },
+ value: {
+ kind: "StringValue",
+ value: "follow",
+ block: false
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "subject" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "accounts" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "id" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "_eq" },
+ value: {
+ kind: "Variable",
+ name: {
+ kind: "Name",
+ value: "address"
+ }
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ],
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "object" },
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ { kind: "Field", name: { kind: "Name", value: "id" } }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+} as unknown as DocumentNode
+
+/**
+ * __useGetFollowingIdsQuery__
+ *
+ * To run a query within a React component, call `useGetFollowingIdsQuery` and pass it any options that fit your needs.
+ * When your component renders, `useGetFollowingIdsQuery` returns an object from Apollo Client that contains loading, error, and data properties
+ * you can use to render your UI.
+ *
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
+ *
+ * @example
+ * const { data, loading, error } = useGetFollowingIdsQuery({
+ * variables: {
+ * address: // value for 'address'
+ * },
+ * });
+ */
+export function useGetFollowingIdsQuery(
+ baseOptions: Apollo.QueryHookOptions<
+ GetFollowingIdsQuery,
+ GetFollowingIdsQueryVariables
+ > &
+ (
+ | { variables: GetFollowingIdsQueryVariables; skip?: boolean }
+ | { skip: boolean }
+ )
+) {
+ const options = { ...defaultOptions, ...baseOptions }
+ return Apollo.useQuery(
+ GetFollowingIdsDocument,
+ options
+ )
+}
+export function useGetFollowingIdsLazyQuery(
+ baseOptions?: Apollo.LazyQueryHookOptions<
+ GetFollowingIdsQuery,
+ GetFollowingIdsQueryVariables
+ >
+) {
+ const options = { ...defaultOptions, ...baseOptions }
+ return Apollo.useLazyQuery<
+ GetFollowingIdsQuery,
+ GetFollowingIdsQueryVariables
+ >(GetFollowingIdsDocument, options)
+}
+export function useGetFollowingIdsSuspenseQuery(
+ baseOptions?:
+ | Apollo.SkipToken
+ | Apollo.SuspenseQueryHookOptions<
+ GetFollowingIdsQuery,
+ GetFollowingIdsQueryVariables
+ >
+) {
+ const options =
+ baseOptions === Apollo.skipToken
+ ? baseOptions
+ : { ...defaultOptions, ...baseOptions }
+ return Apollo.useSuspenseQuery<
+ GetFollowingIdsQuery,
+ GetFollowingIdsQueryVariables
+ >(GetFollowingIdsDocument, options)
+}
+export type GetFollowingIdsQueryHookResult = ReturnType<
+ typeof useGetFollowingIdsQuery
+>
+export type GetFollowingIdsLazyQueryHookResult = ReturnType<
+ typeof useGetFollowingIdsLazyQuery
+>
+export type GetFollowingIdsSuspenseQueryHookResult = ReturnType<
+ typeof useGetFollowingIdsSuspenseQuery
+>
+export type GetFollowingIdsQueryResult = Apollo.QueryResult<
+ GetFollowingIdsQuery,
+ GetFollowingIdsQueryVariables
+>
export const GetFollowingsFromAddressDocument = {
kind: "Document",
definitions: [
@@ -33994,3 +34213,149 @@ export type EventsSubscriptionHookResult = ReturnType<
>
export type EventsSubscriptionResult =
Apollo.SubscriptionResult
+export const FollowerActivityDocument = {
+ kind: "Document",
+ definitions: [
+ {
+ kind: "OperationDefinition",
+ operation: "subscription",
+ name: { kind: "Name", value: "FollowerActivity" },
+ variableDefinitions: [
+ {
+ kind: "VariableDefinition",
+ variable: {
+ kind: "Variable",
+ name: { kind: "Name", value: "limit" }
+ },
+ type: {
+ kind: "NonNullType",
+ type: { kind: "NamedType", name: { kind: "Name", value: "Int" } }
+ }
+ }
+ ],
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "events" },
+ arguments: [
+ {
+ kind: "Argument",
+ name: { kind: "Name", value: "where" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "type" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "_in" },
+ value: {
+ kind: "ListValue",
+ values: [
+ {
+ kind: "StringValue",
+ value: "ClaimCreated",
+ block: false
+ },
+ {
+ kind: "StringValue",
+ value: "AtomCreated",
+ block: false
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ kind: "Argument",
+ name: { kind: "Name", value: "order_by" },
+ value: {
+ kind: "ListValue",
+ values: [
+ {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "block_number" },
+ value: { kind: "EnumValue", value: "desc" }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ kind: "Argument",
+ name: { kind: "Name", value: "limit" },
+ value: {
+ kind: "Variable",
+ name: { kind: "Name", value: "limit" }
+ }
+ }
+ ],
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ { kind: "Field", name: { kind: "Name", value: "type" } },
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "block_timestamp" }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+} as unknown as DocumentNode
+
+/**
+ * __useFollowerActivitySubscription__
+ *
+ * To run a query within a React component, call `useFollowerActivitySubscription` and pass it any options that fit your needs.
+ * When your component renders, `useFollowerActivitySubscription` returns an object from Apollo Client that contains loading, error, and data properties
+ * you can use to render your UI.
+ *
+ * @param baseOptions options that will be passed into the subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
+ *
+ * @example
+ * const { data, loading, error } = useFollowerActivitySubscription({
+ * variables: {
+ * limit: // value for 'limit'
+ * },
+ * });
+ */
+export function useFollowerActivitySubscription(
+ baseOptions: Apollo.SubscriptionHookOptions<
+ FollowerActivitySubscription,
+ FollowerActivitySubscriptionVariables
+ > &
+ (
+ | { variables: FollowerActivitySubscriptionVariables; skip?: boolean }
+ | { skip: boolean }
+ )
+) {
+ const options = { ...defaultOptions, ...baseOptions }
+ return Apollo.useSubscription<
+ FollowerActivitySubscription,
+ FollowerActivitySubscriptionVariables
+ >(FollowerActivityDocument, options)
+}
+export type FollowerActivitySubscriptionHookResult = ReturnType<
+ typeof useFollowerActivitySubscription
+>
+export type FollowerActivitySubscriptionResult =
+ Apollo.SubscriptionResult
diff --git a/src/graphql/src/queries/following-ids.graphql b/src/graphql/src/queries/following-ids.graphql
new file mode 100644
index 00000000..c81a585f
--- /dev/null
+++ b/src/graphql/src/queries/following-ids.graphql
@@ -0,0 +1,12 @@
+query getFollowingIds($address: String!) {
+ triples(
+ where: {
+ predicate: { label: { _eq: "follow" } }
+ subject: { accounts: { id: { _eq: $address } } }
+ }
+ ) {
+ object {
+ id
+ }
+ }
+}
diff --git a/src/graphql/src/subscriptions/follower-activity.graphql b/src/graphql/src/subscriptions/follower-activity.graphql
new file mode 100644
index 00000000..6318e607
--- /dev/null
+++ b/src/graphql/src/subscriptions/follower-activity.graphql
@@ -0,0 +1,11 @@
+subscription FollowerActivity($limit: Int!) {
+ events(
+ where: { type: { _in: ["ClaimCreated", "AtomCreated"] } }
+ order_by: [{ block_number: desc }]
+ limit: $limit
+ ) {
+ type
+
+ block_timestamp
+ }
+}
diff --git a/src/hooks/useClaimDetection.ts b/src/hooks/useClaimDetection.ts
new file mode 100644
index 00000000..f81e3079
--- /dev/null
+++ b/src/hooks/useClaimDetection.ts
@@ -0,0 +1,39 @@
+import { useEffect, useState } from "react"
+import { useGetClaimsByUriQuery } from "~src/graphql/src"
+
+export type Status = "loading" | "found" | "not_found"
+
+export const useClaimDetection = (
+ uri: string,
+ address?: string
+): { status: Status } => {
+ const [status, setStatus] = useState("loading")
+
+ const { data, isLoading } = useGetClaimsByUriQuery(
+ { uri, address },
+ { enabled: Boolean(uri) && Boolean(address) }
+ )
+
+ useEffect(() => {
+
+
+ if (isLoading) {
+ setStatus("loading")
+ } else {
+ const atoms = data?.atoms ?? []
+
+ const foundClaim = atoms.some((atom) => {
+ const subjectCount =
+ atom?.as_subject_claims_aggregate?.aggregate?.count ?? 0
+ const objectCount =
+ atom?.as_object_claims_aggregate?.aggregate?.count ?? 0
+ return subjectCount > 0 || objectCount > 0
+ })
+
+
+ setStatus(foundClaim ? "found" : "not_found")
+ }
+ }, [isLoading, data, uri, address])
+
+ return { status }
+}
diff --git a/src/hooks/useEventNotification.ts b/src/hooks/useEventNotification.ts
new file mode 100644
index 00000000..c7652ee3
--- /dev/null
+++ b/src/hooks/useEventNotification.ts
@@ -0,0 +1,25 @@
+import { useEffect, useState } from "react"
+import { useSubscription } from "@apollo/client"
+import { EventsDocument } from "~src/graphql/src/generated/subscriptions"
+
+export const useEventNotification = () => {
+ const [hasNotification, setHasNotification] = useState(false)
+
+ const { data } = useSubscription(EventsDocument, {
+ variables: {
+ addresses: [],
+ limit: 1
+ }
+ })
+
+ useEffect(() => {
+ const event = data?.events?.[0]
+ const type = event?.type?.toLowerCase?.()
+ if (type?.includes("claim") || type?.includes("atom")) {
+
+ setHasNotification(true)
+ }
+ }, [data])
+
+ return { hasNotification, reset: () => setHasNotification(false) }
+}
diff --git a/src/pages/RecentActivity.tsx b/src/pages/RecentActivity.tsx
index a402f51d..4657600b 100644
--- a/src/pages/RecentActivity.tsx
+++ b/src/pages/RecentActivity.tsx
@@ -38,7 +38,7 @@ const RecentActivity: React.FC = () => {
}
- if (error) return Erreur : {error.message}
+ if (error) return Error : {error.message}
if (loading || !data) {
return (