Skip to content

Commit d819b52

Browse files
committed
fix: Add gno-zenao-staging network, Fix pagination for gno-zenao feed
1 parent ef5b716 commit d819b52

File tree

10 files changed

+183
-33
lines changed

10 files changed

+183
-33
lines changed

apps/gnotribe/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import AppRoot from "@/dapp-root/App";
55
const config: AppConfig = {
66
disableBuyTokensButton: true,
77
disableDAppStore: true,
8-
forceNetworkList: ["gno-test5", "gno-zenao"],
8+
forceNetworkList: ["gno-test5", "gno-zenao", "gno-zenao-staging"],
99
forceDAppsList: ["feed", "organizations"],
1010
defaultNetworkId: "gno-test5",
1111
homeScreen: "Feed",

networks.json

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4676,7 +4676,7 @@
46764676
"Organizations",
46774677
"UPP",
46784678
"NameService",
4679-
"SocialFeed"
4679+
"SocialFeedReadonly"
46804680
],
46814681
"currencies": [
46824682
{
@@ -4710,6 +4710,49 @@
47104710
"accountExplorer": "https://gnoscan.io/accounts/$address?type=custom&chainId=zenao-dev&rpcUrl=https://gnorpc.prod.zenao.io/&indexerUrl=https://indexer.zenao.gno.testnet.teritori.com",
47114711
"contractExplorer": "https://gnoscan.io/realms/details?path=$address&type=custom&chainId=zenao-dev&rpcUrl=https://gnorpc.prod.zenao.io/&indexerUrl=https://indexer.zenao.gno.testnet.teritori.com"
47124712
},
4713+
{
4714+
"id": "gno-zenao-staging",
4715+
"kind": "Gno",
4716+
"displayName": "Gno Zenao Staging",
4717+
"icon": "zenao.svg",
4718+
"features": [
4719+
"Organizations",
4720+
"UPP",
4721+
"NameService",
4722+
"SocialFeedReadonly"
4723+
],
4724+
"currencies": [
4725+
{
4726+
"denom": "ugnot",
4727+
"displayName": "GNOT",
4728+
"decimals": 6,
4729+
"coingeckoId": "gno",
4730+
"icon": "gno.svg",
4731+
"kind": "native",
4732+
"color": "#232800",
4733+
"variant": "gno"
4734+
}
4735+
],
4736+
"stakeCurrency": "ugnot",
4737+
"idPrefix": "zenaostaging",
4738+
"chainId": "zenao-dev-staging",
4739+
"endpoint": "https://gnorpc.staging.zenao.io/",
4740+
"testnet": true,
4741+
"backendEndpoint": "https://dapp-backend.testnet.teritori.com",
4742+
"gnowebURL": "https://gnoweb.staging.zenao.io/",
4743+
"vaultContractAddress": "",
4744+
"nameServiceContractAddress": "gno.land/r/demo/users",
4745+
"nameServiceDefaultImage": "ipfs://bafkreigqm3i4urywxohvpkbz5sgxosiogwn433ufmzz7eqldjxoi6xmwma",
4746+
"socialFeedsPkgPath": "gno.land/r/zenao/social_feed",
4747+
"socialFeedsDAOPkgPath": "gno.land/r/teritori/social_feeds_dao",
4748+
"daoInterfacesPkgPath": "gno.land/p/teritori/dao_interfaces",
4749+
"profilePkgPath": "gno.land/r/demo/profile",
4750+
"txIndexerURL": "https://indexer.zenao.gno.testnet.teritori.com",
4751+
"cockpitNamespace": "zenao",
4752+
"txExplorer": "https://gnoscan.io/transactions/details?txhash=$hash&type=custom&chainId=zenao-dev-staging&rpcUrl=https://gnorpc.staging.zenao.io/&indexerUrl=https://indexer.zenao.gno.testnet.teritori.com",
4753+
"accountExplorer": "https://gnoscan.io/accounts/$address?type=custom&chainId=zenao-dev-staging&rpcUrl=https://gnorpc.staging.zenao.io/&indexerUrl=https://indexer.zenao.gno.testnet.teritori.com",
4754+
"contractExplorer": "https://gnoscan.io/realms/details?path=$address&type=custom&chainId=zenao-dev-staging&rpcUrl=https://gnorpc.staging.zenao.io/&indexerUrl=https://indexer.zenao.gno.testnet.teritori.com"
4755+
},
47134756
{
47144757
"id": "cosmos-registry:gravitybridge",
47154758
"displayName": "Gravity Bridge",

packages/components/OptimizedImage.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { neutral33 } from "../utils/style/colors";
66

77
import { useSelectedNetworkId } from "@/hooks/useSelectedNetwork";
88
import { gnoZenaoNetwork } from "@/networks/gno-zenao";
9+
import { gnoZenaoStagingNetwork } from "@/networks/gno-zenao-staging";
910

1011
/**
1112
* This only supports uri images since the proxy is only for external images
@@ -125,7 +126,8 @@ const transformURI = (
125126

126127
if (uri?.startsWith("ipfs://")) {
127128
const ipfsGateway =
128-
networkId === gnoZenaoNetwork.id
129+
networkId === gnoZenaoNetwork.id ||
130+
networkId === gnoZenaoStagingNetwork.id
129131
? "https://pinata.zenao.io"
130132
: "https://teritori.mypinata.cloud";
131133

packages/hooks/feed/useFetchComments.ts

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { nonSigningSocialFeedClient } from "@/client-creators/socialFeedClient";
99
import { PostResult } from "@/contracts-clients/teritori-social-feed/TeritoriSocialFeed.types";
1010
import { GnoNetworkInfo, NetworkKind, parseNetworkObjectId } from "@/networks";
1111
import { gnoZenaoNetwork } from "@/networks/gno-zenao";
12+
import { gnoZenaoStagingNetwork } from "@/networks/gno-zenao-staging";
1213
import { TERITORI_FEED_ID } from "@/utils/feed/constants";
1314
import { decodeGnoPost } from "@/utils/feed/gno";
1415
import { extractGnoJSONResponse, extractGnoJSONString } from "@/utils/gno";
@@ -17,6 +18,7 @@ import { postViewToPost, postViewsFromJson } from "@/utils/zenao";
1718

1819
export type FetchCommentResponse = {
1920
list: Post[];
21+
totalCount: number | undefined;
2022
} | null;
2123

2224
const combineFetchCommentPages = (pages: FetchCommentResponse[]) =>
@@ -37,17 +39,18 @@ const fetchTeritoriComments = async (
3739
networkId,
3840
});
3941

40-
const subComment = await client.querySubPosts({
42+
const comments = await client.querySubPosts({
4143
count: 5,
4244
from: pageParam || 0,
4345
sort: "desc",
4446
identifier: parentId || "",
4547
});
4648

4749
return {
48-
list: subComment.map((subPostRes: PostResult) =>
50+
list: comments.map((subPostRes: PostResult) =>
4951
postResultToPost(networkId, subPostRes),
5052
),
53+
totalCount: comments.length,
5154
};
5255
};
5356

@@ -65,7 +68,7 @@ const fetchGnoComments = async (
6568
`GetComments(${TERITORI_FEED_ID}, ${parentId}, ${offset}, ${limit})`,
6669
);
6770

68-
const posts: Post[] = [];
71+
const comments: Post[] = [];
6972

7073
const gnoPosts = extractGnoJSONString(output);
7174
for (const gnoPost of gnoPosts) {
@@ -77,14 +80,16 @@ const fetchGnoComments = async (
7780
ownState: false, // FIXME: find a way to get the user's reaction state from on-chain post
7881
}));
7982

80-
posts.push({ ...post, reactions: postReactions });
83+
comments.push({ ...post, reactions: postReactions });
8184
}
8285

8386
return {
84-
list: posts.sort((p1, p2) => p2.createdAt - p1.createdAt),
87+
list: comments.sort((p1, p2) => p2.createdAt - p1.createdAt),
88+
totalCount: comments.length,
8589
};
8690
};
8791

92+
const gnoZenaoCommentsLimit = 10;
8893
const fetchGnoZenaoComments = async (
8994
selectedNetwork: GnoNetworkInfo,
9095
parentId: string,
@@ -94,33 +99,38 @@ const fetchGnoZenaoComments = async (
9499
if (!selectedNetwork.socialFeedsPkgPath) return { list: [], totalCount: 0 };
95100
callerAddress = callerAddress || "";
96101

97-
const limit = 100; // For now hardcode to load max 100 comments
102+
const limit = gnoZenaoCommentsLimit;
103+
const offset = pageParam * limit;
98104
const tags = "";
99105
const provider = new GnoJSONRPCProvider(selectedNetwork.endpoint);
100106

101107
const output = await provider.evaluateExpression(
102108
selectedNetwork.socialFeedsPkgPath || "",
103-
`postViewsToJSON(GetChildrenPosts("${parentId}", ${pageParam * limit}, ${limit}, "${tags}", "${callerAddress}"))`,
109+
`postViewsToJSON(GetChildrenPosts("${parentId}", ${offset}, ${limit}, "${tags}", "${callerAddress}"))`,
104110
);
105111
const raw = extractGnoJSONResponse(output);
106112
const postViews = postViewsFromJson(raw);
107113
return {
108-
list: postViews.map((postView) => postViewToPost(postView)),
114+
list: postViews.map((postView) =>
115+
postViewToPost(postView, selectedNetwork.id),
116+
),
117+
totalCount: postViews.length,
109118
};
110119
};
111120

112121
const useFetchCommentsRaw = ({ parentId, totalCount, enabled }: ConfigType) => {
113122
const selectedWallet = useSelectedWallet();
123+
const [parentNetwork, localIdentifier] = parseNetworkObjectId(parentId);
114124

115125
const data = useInfiniteQuery<FetchCommentResponse>(
116126
["FetchComment", parentId],
117127
async ({ pageParam = 0 }) => {
118-
const [parentNetwork, localIdentifier] = parseNetworkObjectId(parentId);
119128
let comments: FetchCommentResponse;
120129
// Gno Zenao network
121130
if (
122131
parentNetwork?.kind === NetworkKind.Gno &&
123-
parentNetwork?.id === gnoZenaoNetwork.id
132+
(parentNetwork?.id === gnoZenaoNetwork.id ||
133+
parentNetwork?.id === gnoZenaoStagingNetwork.id)
124134
) {
125135
return fetchGnoZenaoComments(
126136
parentNetwork,
@@ -144,13 +154,26 @@ const useFetchCommentsRaw = ({ parentId, totalCount, enabled }: ConfigType) => {
144154
return comments;
145155
},
146156
{
147-
getNextPageParam: (_, pages) => {
148-
const postsLength = combineFetchCommentPages(pages).length;
149-
150-
if ((totalCount || 0) > postsLength) {
151-
return postsLength;
157+
getNextPageParam: (lastPage, pages) => {
158+
if (
159+
parentNetwork?.kind === NetworkKind.Gno &&
160+
(parentNetwork?.id === gnoZenaoNetwork.id ||
161+
parentNetwork?.id === gnoZenaoStagingNetwork.id)
162+
) {
163+
if (
164+
lastPage?.totalCount &&
165+
lastPage.totalCount >= gnoZenaoCommentsLimit
166+
) {
167+
return pages.length;
168+
}
169+
} else {
170+
const postsLength = combineFetchCommentPages(pages).length;
171+
172+
if ((totalCount || 0) > postsLength) {
173+
return postsLength;
174+
}
175+
return null;
152176
}
153-
return null;
154177
},
155178
staleTime: Infinity,
156179
refetchOnWindowFocus: false,

packages/hooks/feed/useFetchFeed.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
parseUserId,
1818
} from "@/networks";
1919
import { gnoZenaoNetwork } from "@/networks/gno-zenao";
20+
import { gnoZenaoStagingNetwork } from "@/networks/gno-zenao-staging";
2021
import { mustGetFeedClient } from "@/utils/backend";
2122
import { HYPERAKTIVE_EVENT_ID, TERITORI_FEED_ID } from "@/utils/feed/constants";
2223
import { decodeGnoPost } from "@/utils/feed/gno";
@@ -50,7 +51,7 @@ const fetchTeritoriFeed = async (
5051
const feedClient = mustGetFeedClient(selectedNetwork.id);
5152
const response = await feedClient.Posts(postsRequest);
5253
const list = response.posts.sort((a, b) => b.createdAt - a.createdAt);
53-
return { list, totalCount: undefined };
54+
return { list, totalCount: list.length };
5455
};
5556

5657
const fetchGnoFeed = async (
@@ -105,6 +106,7 @@ const fetchGnoZenaoFeed = async (
105106
callerAddress = callerAddress || "";
106107

107108
const limit = req.limit || 0;
109+
const offset = pageParam * limit;
108110
const tags = "";
109111

110112
const provider = new GnoJSONRPCProvider(selectedNetwork.endpoint);
@@ -113,11 +115,11 @@ const fetchGnoZenaoFeed = async (
113115

114116
const output = await provider.evaluateExpression(
115117
selectedNetwork.socialFeedsPkgPath || "",
116-
`postViewsToJSON(GetFeedPosts("${feedId}", ${pageParam * limit}, ${limit}, "${tags}", "${callerAddress}"))`,
118+
`postViewsToJSON(GetFeedPosts("${feedId}", ${offset}, ${limit}, "${tags}", "${callerAddress}"))`,
117119
);
118120
const raw = extractGnoJSONResponse(output);
119121
const postViews = postViewsFromJson(raw);
120-
return postViewsToPostsList(postViews);
122+
return postViewsToPostsList(postViews, selectedNetwork.id);
121123
};
122124

123125
export const useFetchFeed = (req: DeepPartial<PostsRequest>) => {
@@ -135,7 +137,8 @@ export const useFetchFeed = (req: DeepPartial<PostsRequest>) => {
135137
// Gno Zenao network
136138
else if (
137139
selectedNetwork?.kind === NetworkKind.Gno &&
138-
selectedNetwork?.id === gnoZenaoNetwork.id
140+
(selectedNetwork?.id === gnoZenaoNetwork.id ||
141+
selectedNetwork?.id === gnoZenaoStagingNetwork.id)
139142
) {
140143
return fetchGnoZenaoFeed(
141144
HYPERAKTIVE_EVENT_ID,
@@ -154,9 +157,22 @@ export const useFetchFeed = (req: DeepPartial<PostsRequest>) => {
154157
},
155158
{
156159
getNextPageParam: (lastPage, pages) => {
160+
if (
161+
selectedNetwork?.kind === NetworkKind.Gno &&
162+
(selectedNetwork?.id === gnoZenaoNetwork.id ||
163+
selectedNetwork?.id === gnoZenaoStagingNetwork.id)
164+
) {
165+
if (
166+
lastPage.totalCount &&
167+
req.limit &&
168+
lastPage.totalCount >= req.limit
169+
) {
170+
return pages.length;
171+
}
172+
}
157173
// NOTE: On gno feeds, due to list length depends on each user (due to flag, hide)
158174
// so if last page contains posts = limit => try to load more content
159-
if (selectedNetwork?.kind === NetworkKind.Gno) {
175+
else if (selectedNetwork?.kind === NetworkKind.Gno) {
160176
if (lastPage?.totalCount && lastPage.totalCount === req.limit) {
161177
return pages.length * req.limit;
162178
}

packages/hooks/feed/usePost.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { PostViewJson, PostViewSchema } from "@/api/feeds/v1/feeds_pb";
1010
import { nonSigningSocialFeedClient } from "@/client-creators/socialFeedClient";
1111
import { NetworkKind, getUserId, parseNetworkObjectId } from "@/networks";
1212
import { gnoZenaoNetwork } from "@/networks/gno-zenao";
13+
import { gnoZenaoStagingNetwork } from "@/networks/gno-zenao-staging";
1314
import { decodeGnoPost } from "@/utils/feed/gno";
1415
import { extractGnoJSONResponse, extractGnoJSONString } from "@/utils/gno";
1516
import { safeParseJSON, zodTryParseJSON } from "@/utils/sanitize";
@@ -32,7 +33,8 @@ export const usePost = (id: string | undefined) => {
3233
// Gno Zenao network
3334
else if (
3435
network?.kind === NetworkKind.Gno &&
35-
network?.id === gnoZenaoNetwork.id
36+
(network?.id === gnoZenaoNetwork.id ||
37+
network?.id === gnoZenaoStagingNetwork.id)
3638
) {
3739
const callerAddress = wallet?.address || "";
3840
const provider = new GnoJSONRPCProvider(network.endpoint);
@@ -43,7 +45,7 @@ export const usePost = (id: string | undefined) => {
4345
);
4446
const raw = extractGnoJSONResponse(output);
4547
const postView = fromJson(PostViewSchema, raw as PostViewJson);
46-
return postViewToPost(postView);
48+
return postViewToPost(postView, network.id);
4749
}
4850
// Gno network
4951
else if (network?.kind === NetworkKind.Gno) {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { currencyGNOcolor } from "../../utils/style/colors";
2+
import { CurrencyInfo } from "../types";
3+
4+
export const gnoCurrencies: CurrencyInfo[] = [
5+
{
6+
denom: "ugnot",
7+
displayName: "GNOT",
8+
decimals: 6,
9+
coingeckoId: "gno",
10+
icon: "gno.svg",
11+
kind: "native",
12+
color: currencyGNOcolor,
13+
variant: "gno",
14+
},
15+
];
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { gnoCurrencies } from "./currencies";
2+
import { GnoNetworkInfo, NetworkFeature, NetworkKind } from "../types";
3+
4+
export const gnoZenaoStagingNetwork: GnoNetworkInfo = {
5+
id: "gno-zenao-staging",
6+
kind: NetworkKind.Gno,
7+
displayName: "Gno Zenao Staging",
8+
icon: "zenao.svg",
9+
features: [
10+
NetworkFeature.Organizations,
11+
NetworkFeature.UPP,
12+
NetworkFeature.NameService,
13+
NetworkFeature.SocialFeedReadonly,
14+
],
15+
currencies: gnoCurrencies,
16+
stakeCurrency: "ugnot",
17+
idPrefix: "zenaostaging",
18+
chainId: "zenao-dev-staging",
19+
endpoint: "https://gnorpc.staging.zenao.io/",
20+
testnet: true,
21+
backendEndpoint: "https://dapp-backend.testnet.teritori.com",
22+
gnowebURL: "https://gnoweb.staging.zenao.io/",
23+
vaultContractAddress: "",
24+
nameServiceContractAddress: "gno.land/r/demo/users",
25+
nameServiceDefaultImage:
26+
"ipfs://bafkreigqm3i4urywxohvpkbz5sgxosiogwn433ufmzz7eqldjxoi6xmwma",
27+
socialFeedsPkgPath: "gno.land/r/zenao/social_feed",
28+
socialFeedsDAOPkgPath: "gno.land/r/teritori/social_feeds_dao",
29+
daoInterfacesPkgPath: "gno.land/p/teritori/dao_interfaces",
30+
profilePkgPath: "gno.land/r/demo/profile",
31+
txIndexerURL: "https://indexer.zenao.gno.testnet.teritori.com",
32+
cockpitNamespace: "zenao",
33+
34+
txExplorer: "",
35+
accountExplorer: "",
36+
contractExplorer: "",
37+
};
38+
39+
const customGnoscanParams = (network: GnoNetworkInfo) => {
40+
return `type=custom&chainId=${network.chainId}&rpcUrl=${network.endpoint}&indexerUrl=${network.txIndexerURL}`;
41+
};
42+
43+
gnoZenaoStagingNetwork.txExplorer = `https://gnoscan.io/transactions/details?txhash=$hash&${customGnoscanParams(gnoZenaoStagingNetwork)}`;
44+
gnoZenaoStagingNetwork.accountExplorer = `https://gnoscan.io/accounts/$address?${customGnoscanParams(gnoZenaoStagingNetwork)}`;
45+
gnoZenaoStagingNetwork.contractExplorer = `https://gnoscan.io/realms/details?path=$address&${customGnoscanParams(gnoZenaoStagingNetwork)}`;

0 commit comments

Comments
 (0)