diff --git a/src/components/search/Spark/Meta/Meta.module.scss b/src/components/search/Spark/Meta/Meta.module.scss
index e5d423fce..18bbfb7f3 100644
--- a/src/components/search/Spark/Meta/Meta.module.scss
+++ b/src/components/search/Spark/Meta/Meta.module.scss
@@ -5,7 +5,6 @@
// temp
z-index: 1;
-
font-size: 14px;
& > :first-child {
@@ -13,7 +12,3 @@
top: 4px;
}
}
-
-.size {
- white-space: nowrap;
-}
diff --git a/src/components/search/Spark/Meta/Meta.tsx b/src/components/search/Spark/Meta/Meta.tsx
index e7802d1e7..5f3221305 100644
--- a/src/components/search/Spark/Meta/Meta.tsx
+++ b/src/components/search/Spark/Meta/Meta.tsx
@@ -1,10 +1,7 @@
-import useQueueIpfsContent from 'src/hooks/useQueueIpfsContent';
-import { formatCurrency } from 'src/utils/utils';
-import { PREFIXES } from 'src/containers/ipfs/components/metaInfo';
import { useNavigate } from 'react-router-dom';
import { routes } from 'src/routes';
-import { useEffect } from 'react';
import useCyberlinksCount from 'src/features/cyberlinks/hooks/useCyberlinksCount';
+import ParticleSize from 'src/features/particle/ParticleSize/ParticleSize';
import Links from './Links/Links';
import styles from './Meta.module.scss';
@@ -13,18 +10,10 @@ type Props = {
};
function Meta({ cid }: Props) {
- const { content, fetchParticle } = useQueueIpfsContent(cid);
-
const { data: count } = useCyberlinksCount(cid);
- useEffect(() => {
- fetchParticle && (async () => fetchParticle(cid))();
- }, [cid, fetchParticle]);
-
const navigate = useNavigate();
- const size = content?.meta?.size;
-
return (
- {size && (
-
- 🟥 {formatCurrency(size, 'B', 0, PREFIXES)}
-
- )}
+
);
}
diff --git a/src/containers/ipfs/components/AdviserMeta/AdviserMeta.tsx b/src/containers/ipfs/components/AdviserMeta/AdviserMeta.tsx
index 2e20793d0..a70878bb9 100644
--- a/src/containers/ipfs/components/AdviserMeta/AdviserMeta.tsx
+++ b/src/containers/ipfs/components/AdviserMeta/AdviserMeta.tsx
@@ -1,23 +1,22 @@
import { Account } from 'src/components';
-import { timeSince, formatCurrency } from 'src/utils/utils';
+import { timeSince } from 'src/utils/utils';
import useRank from 'src/features/cyberlinks/rank/useRank';
import { Link } from 'react-router-dom';
import { routes } from 'src/routes';
+import ParticleSize from 'src/features/particle/ParticleSize/ParticleSize';
import {
LLMAvatar,
useIsLLMPageParam,
} from 'src/containers/Search/LLMSpark/LLMSpark';
import useGetCreator from '../../hooks/useGetCreator';
-import { PREFIXES } from '../metaInfo';
import styles from './AdviserMeta.module.scss';
type Props = {
cid: string;
type: string | undefined;
- size: number | bigint | undefined;
};
-function AdviserMeta({ cid, type, size }: Props) {
+function AdviserMeta({ cid, type }: Props) {
const { creator } = useGetCreator(cid);
const rank = useRank(cid);
@@ -62,9 +61,7 @@ function AdviserMeta({ cid, type, size }: Props) {
)}
-
- 🟥 {size ? formatCurrency(size, 'B', 0, PREFIXES) : 'unknown'}
-
+
🌓
diff --git a/src/containers/ipfs/ipfs.tsx b/src/containers/ipfs/ipfs.tsx
index bbc8c914e..d6ce459ff 100644
--- a/src/containers/ipfs/ipfs.tsx
+++ b/src/containers/ipfs/ipfs.tsx
@@ -26,6 +26,7 @@ function Ipfs() {
const { setAdviser } = useAdviser();
const isText = useMemo(() => !query.match(PATTERN_IPFS_HASH), [query]);
+
useEffect(() => {
if (!isReady) {
return;
@@ -41,7 +42,7 @@ function Ipfs() {
})();
}
}, [isText, isReady, query, ipfsApi, isIpfsInitialized]);
- useEffect(() => {}, [details]);
+
useEffect(() => {
if (!status) {
return;
@@ -61,14 +62,7 @@ function Ipfs() {
'yellow'
);
} else if (status === 'completed') {
- setAdviser(
- ,
- 'purple'
- );
+ setAdviser(, 'purple');
}
}, [details, setAdviser, cid, content, status]);
diff --git a/src/features/cyberlinks/hooks/useCyberlinksCount.ts b/src/features/cyberlinks/hooks/useCyberlinksCount.ts
index 7c668f115..26a5e7011 100644
--- a/src/features/cyberlinks/hooks/useCyberlinksCount.ts
+++ b/src/features/cyberlinks/hooks/useCyberlinksCount.ts
@@ -4,7 +4,7 @@ const getVar = (type: 'from' | 'to', cid: string, neuron) => {
return { [`particle_${type}`]: { _eq: cid }, neuron: { _eq: neuron } };
};
-function useCyberlinksCount(cid: string, neuron) {
+function useCyberlinksCount(cid: string, neuron?: string) {
const toCountQuery = useCyberlinksCountByParticleQuery({
variables: { where: getVar('to', cid, neuron) },
});
diff --git a/src/features/particle/ParticleSize/ParticleSize.module.scss b/src/features/particle/ParticleSize/ParticleSize.module.scss
new file mode 100644
index 000000000..4e0cd13f0
--- /dev/null
+++ b/src/features/particle/ParticleSize/ParticleSize.module.scss
@@ -0,0 +1,3 @@
+.size {
+ white-space: nowrap;
+}
diff --git a/src/features/particle/ParticleSize/ParticleSize.tsx b/src/features/particle/ParticleSize/ParticleSize.tsx
new file mode 100644
index 000000000..96d5104f2
--- /dev/null
+++ b/src/features/particle/ParticleSize/ParticleSize.tsx
@@ -0,0 +1,36 @@
+import { formatCurrency } from 'src/utils/utils';
+import { PREFIXES } from 'src/containers/ipfs/components/metaInfo';
+import useParticle from '../../../hooks/useParticle';
+import styles from './ParticleSize.module.scss';
+
+// for future use if no UI needed
+// eslint-disable-next-line import/no-unused-modules
+export function useParticleSize(cid: string) {
+ const { content, details, status } = useParticle(cid);
+
+ const size = content?.meta?.size || details?.content?.length;
+
+ return {
+ size,
+ isLoading: status === 'pending' || status === 'executing',
+ };
+}
+
+function ParticleSize({ cid }: { cid: string }) {
+ const { isLoading, size } = useParticleSize(cid);
+
+ let content;
+
+ if (isLoading) {
+ // use Loading component
+ content = 'loading...';
+ } else if (size) {
+ content = formatCurrency(size, 'B', 0, PREFIXES);
+ } else {
+ content = 'unknown';
+ }
+
+ return 🟥 {content};
+}
+
+export default ParticleSize;
diff --git a/src/generated/graphql.ts b/src/generated/graphql.ts
index 4ab8dcdd9..ed4916e7c 100644
--- a/src/generated/graphql.ts
+++ b/src/generated/graphql.ts
@@ -8843,6 +8843,13 @@ export type CyberlinksCountByNeuronQueryVariables = Exact<{
export type CyberlinksCountByNeuronQuery = { cyberlinks_aggregate: { aggregate?: { count: number } | null } };
+export type CyberlinksCountByNeuron2QueryVariables = Exact<{
+ address?: InputMaybe;
+}>;
+
+
+export type CyberlinksCountByNeuron2Query = { cyberlinks_aggregate: { aggregate?: { count: number } | null } };
+
export type CyberlinksCountByParticleQueryVariables = Exact<{
cid?: InputMaybe;
where?: InputMaybe;
@@ -8883,6 +8890,22 @@ export type MessagesByAddressSenseWsSubscriptionVariables = Exact<{
export type MessagesByAddressSenseWsSubscription = { messages_by_address: Array<{ transaction_hash: string, index: any, value: any, type: string, transaction?: { success: boolean, memo?: string | null, block: { timestamp: any, height: any } } | null }> };
+export type ParticlesQueryVariables = Exact<{
+ neuron?: InputMaybe;
+ limit?: InputMaybe;
+ offset?: InputMaybe;
+}>;
+
+
+export type ParticlesQuery = { particles: Array<{ id: number, particle: string, timestamp: any, transaction_hash: string }> };
+
+export type ParticlesAggregateQueryVariables = Exact<{
+ neuron?: InputMaybe;
+}>;
+
+
+export type ParticlesAggregateQuery = { particles_aggregate: { aggregate?: { count: number } | null } };
+
export type TransactionCountQueryVariables = Exact<{ [key: string]: never; }>;
@@ -9213,6 +9236,48 @@ export type CyberlinksCountByNeuronQueryHookResult = ReturnType;
export type CyberlinksCountByNeuronSuspenseQueryHookResult = ReturnType;
export type CyberlinksCountByNeuronQueryResult = Apollo.QueryResult;
+export const CyberlinksCountByNeuron2Document = gql`
+ query CyberlinksCountByNeuron2($address: String) {
+ cyberlinks_aggregate(where: {neuron: {_eq: $address}}) {
+ aggregate {
+ count
+ }
+ }
+}
+ `;
+
+/**
+ * __useCyberlinksCountByNeuron2Query__
+ *
+ * To run a query within a React component, call `useCyberlinksCountByNeuron2Query` and pass it any options that fit your needs.
+ * When your component renders, `useCyberlinksCountByNeuron2Query` 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 } = useCyberlinksCountByNeuron2Query({
+ * variables: {
+ * address: // value for 'address'
+ * },
+ * });
+ */
+export function useCyberlinksCountByNeuron2Query(baseOptions?: Apollo.QueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useQuery(CyberlinksCountByNeuron2Document, options);
+ }
+export function useCyberlinksCountByNeuron2LazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useLazyQuery(CyberlinksCountByNeuron2Document, options);
+ }
+export function useCyberlinksCountByNeuron2SuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useSuspenseQuery(CyberlinksCountByNeuron2Document, options);
+ }
+export type CyberlinksCountByNeuron2QueryHookResult = ReturnType;
+export type CyberlinksCountByNeuron2LazyQueryHookResult = ReturnType;
+export type CyberlinksCountByNeuron2SuspenseQueryHookResult = ReturnType;
+export type CyberlinksCountByNeuron2QueryResult = Apollo.QueryResult;
export const CyberlinksCountByParticleDocument = gql`
query cyberlinksCountByParticle($cid: String, $where: cyberlinks_bool_exp) {
cyberlinks_aggregate(where: $where) {
@@ -9412,6 +9477,93 @@ export function useMessagesByAddressSenseWsSubscription(baseOptions?: Apollo.Sub
}
export type MessagesByAddressSenseWsSubscriptionHookResult = ReturnType;
export type MessagesByAddressSenseWsSubscriptionResult = Apollo.SubscriptionResult;
+export const ParticlesDocument = gql`
+ query particles($neuron: String, $limit: Int = 10, $offset: Int = 0) {
+ particles(where: {neuron: {_eq: $neuron}}, limit: $limit, offset: $offset) {
+ id
+ particle
+ timestamp
+ transaction_hash
+ }
+}
+ `;
+
+/**
+ * __useParticlesQuery__
+ *
+ * To run a query within a React component, call `useParticlesQuery` and pass it any options that fit your needs.
+ * When your component renders, `useParticlesQuery` 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 } = useParticlesQuery({
+ * variables: {
+ * neuron: // value for 'neuron'
+ * limit: // value for 'limit'
+ * offset: // value for 'offset'
+ * },
+ * });
+ */
+export function useParticlesQuery(baseOptions?: Apollo.QueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useQuery(ParticlesDocument, options);
+ }
+export function useParticlesLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useLazyQuery(ParticlesDocument, options);
+ }
+export function useParticlesSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useSuspenseQuery(ParticlesDocument, options);
+ }
+export type ParticlesQueryHookResult = ReturnType;
+export type ParticlesLazyQueryHookResult = ReturnType;
+export type ParticlesSuspenseQueryHookResult = ReturnType;
+export type ParticlesQueryResult = Apollo.QueryResult;
+export const ParticlesAggregateDocument = gql`
+ query particlesAggregate($neuron: String) {
+ particles_aggregate(where: {neuron: {_eq: $neuron}}) {
+ aggregate {
+ count
+ }
+ }
+}
+ `;
+
+/**
+ * __useParticlesAggregateQuery__
+ *
+ * To run a query within a React component, call `useParticlesAggregateQuery` and pass it any options that fit your needs.
+ * When your component renders, `useParticlesAggregateQuery` 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 } = useParticlesAggregateQuery({
+ * variables: {
+ * neuron: // value for 'neuron'
+ * },
+ * });
+ */
+export function useParticlesAggregateQuery(baseOptions?: Apollo.QueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useQuery(ParticlesAggregateDocument, options);
+ }
+export function useParticlesAggregateLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useLazyQuery(ParticlesAggregateDocument, options);
+ }
+export function useParticlesAggregateSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useSuspenseQuery(ParticlesAggregateDocument, options);
+ }
+export type ParticlesAggregateQueryHookResult = ReturnType;
+export type ParticlesAggregateLazyQueryHookResult = ReturnType;
+export type ParticlesAggregateSuspenseQueryHookResult = ReturnType;
+export type ParticlesAggregateQueryResult = Apollo.QueryResult;
export const TransactionCountDocument = gql`
query transactionCount {
transaction_aggregate {
diff --git a/src/pages/robot/Brain/Brain.tsx b/src/pages/robot/Brain/Brain.tsx
index 8d8df016c..d96286390 100644
--- a/src/pages/robot/Brain/Brain.tsx
+++ b/src/pages/robot/Brain/Brain.tsx
@@ -8,6 +8,7 @@ import TreedView from './ui/TreedView';
import styles from './Brain.module.scss';
import GraphView from './ui/GraphView';
import useGraphLimit from './useGraphLimit';
+import Particles from './ui/Particles/Particles';
enum TabsKey {
graph3d = 'graph3d',
@@ -56,6 +57,11 @@ function Brain() {
to: './list',
text: 'last cyberlinks',
},
+ {
+ key: TabsKey.list,
+ to: './particles',
+ text: 'particles',
+ },
]}
selected={selected}
/>
@@ -71,6 +77,7 @@ function Brain() {
))}
} />
+ } />
} />
diff --git a/src/pages/robot/Brain/ui/Particles/Particles.module.scss b/src/pages/robot/Brain/ui/Particles/Particles.module.scss
new file mode 100644
index 000000000..275cba72a
--- /dev/null
+++ b/src/pages/robot/Brain/ui/Particles/Particles.module.scss
@@ -0,0 +1,5 @@
+.particleContent {
+ max-height: 60px;
+ display: block;
+ overflow: auto;
+}
diff --git a/src/pages/robot/Brain/ui/Particles/Particles.tsx b/src/pages/robot/Brain/ui/Particles/Particles.tsx
new file mode 100644
index 000000000..a6aa106bb
--- /dev/null
+++ b/src/pages/robot/Brain/ui/Particles/Particles.tsx
@@ -0,0 +1,197 @@
+import useAdviserTexts from 'src/features/adviser/useAdviserTexts';
+import {
+ ParticlesQuery,
+ useCyberlinksCountByNeuron2Query,
+ useParticlesAggregateQuery,
+ useParticlesQuery,
+} from 'src/generated/graphql';
+import { useRobotContext } from 'src/pages/robot/robot.context';
+
+import { createColumnHelper } from '@tanstack/react-table';
+import Table from 'src/components/Table/Table';
+import ContentItem from 'src/components/ContentItem/contentItem';
+import { Display } from 'src/components';
+import { useState } from 'react';
+import InfiniteScroll from 'react-infinite-scroll-component';
+import Loader2 from 'src/components/ui/Loader2';
+import ParticleSize from 'src/features/particle/ParticleSize/ParticleSize';
+import { Link, useNavigate } from 'react-router-dom';
+import { routes } from 'src/routes';
+import useRank from 'src/features/cyberlinks/rank/useRank';
+import styles from './Particles.module.scss';
+
+const columnHelper = createColumnHelper();
+
+const LIMIT = 20;
+
+function Rank2({ cid }) {
+ const rank = useRank(cid);
+
+ if (!rank) {
+ return null;
+ }
+
+ return (
+
+ {rank / 10 ** 15}
+ {/* {rank.toLocaleString().replaceAll(',', ' ')} */}
+
+ );
+}
+
+function Particles() {
+ const { address } = useRobotContext();
+ const [hasMore, setHasMore] = useState(true);
+ // const [offset, setOffset] = useState(0);
+
+ const navigate = useNavigate();
+
+ const { data, loading, error, fetchMore } = useParticlesQuery({
+ variables: {
+ neuron: address,
+ limit: LIMIT,
+ },
+ });
+
+ console.log(data);
+
+ const particleAggregateQuery = useParticlesAggregateQuery({
+ variables: {
+ neuron: address,
+ },
+ });
+
+ const cyberlinksCountQuery = useCyberlinksCountByNeuron2Query({
+ variables: {
+ address,
+ },
+ });
+
+ function fetch() {
+ fetchMore({
+ variables: {
+ offset: data?.particles.length,
+ },
+ updateQuery: (prev, { fetchMoreResult }) => {
+ if (!fetchMoreResult) {
+ return prev;
+ }
+
+ setHasMore(fetchMoreResult.particles.length > 0);
+
+ return {
+ ...prev,
+ particles: [...prev.particles, ...fetchMoreResult.particles],
+ };
+ },
+ });
+ }
+
+ useAdviserTexts({
+ defaultText: 'Particles',
+ isLoading: loading,
+ error,
+ });
+
+ console.log(data, cyberlinksCountQuery);
+
+ const total =
+ particleAggregateQuery.data?.particles_aggregate.aggregate?.count;
+
+ return (
+
+
+ {total} particles
+
+
+ {cyberlinksCountQuery.data?.cyberlinks_aggregate.aggregate?.count}{' '}
+ cyberlinks
+
+
+
+
+ }
+ >
+ {
+ const cid = data!.particles[row].particle;
+
+ navigate(routes.oracle.ask.getLink(cid));
+ }}
+ columns={[
+ columnHelper.accessor('particle', {
+ header: 'CID',
+ id: 'cid',
+ cell: (info) => {
+ return (
+
+ );
+ },
+ }),
+ columnHelper.accessor('timestamp', {
+ header: 'timestamp',
+ cell: (info) => {
+ const hash = info.row.original.transaction_hash;
+ // return new Date(info.getValue()).toLocaleString();
+ return (
+
+ {new Intl.DateTimeFormat(navigator.language, {
+ dateStyle: 'medium',
+ timeStyle: 'short',
+ }).format(new Date(info.getValue()))}
+
+ );
+ },
+ }),
+ columnHelper.accessor('particle', {
+ header: 'size',
+ id: 'size',
+ cell: (info) => {
+ return ;
+ },
+ }),
+ columnHelper.accessor('particle', {
+ header: (
+ <>
+ {/* rank{' '} */}
+ {/*
+ ðŸ¦
+ */}
+ probability of observation
+ >
+ ),
+ id: 'rank',
+ cell: (info) => {
+ return ;
+ },
+ }),
+ ]}
+ data={data?.particles || []}
+ />
+
+
+
+ );
+}
+
+export default Particles;
diff --git a/src/services/backend/services/indexer/graphql/cyberlinksCountByNeuron.graphql b/src/services/backend/services/indexer/graphql/cyberlinksCountByNeuron.graphql
index 880c18a98..abaa4986b 100644
--- a/src/services/backend/services/indexer/graphql/cyberlinksCountByNeuron.graphql
+++ b/src/services/backend/services/indexer/graphql/cyberlinksCountByNeuron.graphql
@@ -17,3 +17,12 @@ query CyberlinksCountByNeuron(
}
}
}
+
+# refactor
+query CyberlinksCountByNeuron2($address: String) {
+ cyberlinks_aggregate(where: { neuron: { _eq: $address } }) {
+ aggregate {
+ count
+ }
+ }
+}
diff --git a/src/services/backend/services/indexer/graphql/particles/particles.graphql b/src/services/backend/services/indexer/graphql/particles/particles.graphql
new file mode 100644
index 000000000..9b30bb771
--- /dev/null
+++ b/src/services/backend/services/indexer/graphql/particles/particles.graphql
@@ -0,0 +1,23 @@
+# input OrderByInput {
+# timestamp: order_by
+# id: order_by
+# }
+
+query particles(
+ $neuron: String
+ $limit: Int = 10
+ $offset: Int = 0
+) # $orderBy: OrderByInput
+{
+ particles(
+ where: { neuron: { _eq: $neuron } }
+ # order_by: $orderBy
+ limit: $limit
+ offset: $offset
+ ) {
+ id
+ particle
+ timestamp
+ transaction_hash
+ }
+}
diff --git a/src/services/backend/services/indexer/graphql/particles/particlesAggregate.graphql b/src/services/backend/services/indexer/graphql/particles/particlesAggregate.graphql
new file mode 100644
index 000000000..ad735485d
--- /dev/null
+++ b/src/services/backend/services/indexer/graphql/particles/particlesAggregate.graphql
@@ -0,0 +1,7 @@
+query particlesAggregate($neuron: String) {
+ particles_aggregate(where: { neuron: { _eq: $neuron } }) {
+ aggregate {
+ count
+ }
+ }
+}
diff --git a/src/utils/date.ts b/src/utils/date.ts
index 8cab5cdb3..9e4f8da02 100644
--- a/src/utils/date.ts
+++ b/src/utils/date.ts
@@ -14,10 +14,6 @@ function roundMilliseconds(dateTimeString: string) {
date.setMilliseconds(roundedMilliseconds);
return dateFormat(date, 'yyyy-mm-dd"T"HH:MM:ss.l');
}
-function getCurrentTimezoneOffset() {
- const now = new Date();
- return -now.getTimezoneOffset() / 60;
-}
function pluralizeUnit(quantity: number, unit: string): string {
return quantity === 1 ? unit : `${unit}s`;