Skip to content

Commit c8dfeb7

Browse files
committed
use social SDK for publisher page (#5639)
closes: DASH-547 <!-- start pr-codex --> --- ## PR-Codex overview This PR primarily focuses on removing unused components and optimizing existing code related to publisher profiles and social media integration. It also introduces improvements to error handling and modifies the account components to avoid retrying on failures. ### Detailed summary - Deleted several unused icon and component files. - Set `retry: false` for account components in `thirdweb`. - Added `replaceDeployerAddress` function to `publisher-utils`. - Refactored profile handling to utilize social profiles. - Removed unused profile schema definitions. - Updated `ProfileUI` to use `ProfileHeader` for displaying user info. - Simplified `ContractPublisher` to use `AccountProvider`. - Enhanced error handling in various components. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent 5574c15 commit c8dfeb7

File tree

27 files changed

+186
-717
lines changed

27 files changed

+186
-717
lines changed

.changeset/blue-bees-ring.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
default account components to not retry on failure

apps/dashboard/src/@/components/ui/code/getCodeHtml.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ export async function getCodeHtml(code: string, lang: BundledLanguage) {
2525
}).catch((e) => {
2626
console.error(e);
2727
console.error("Failed to format code");
28-
console.log({
29-
code,
30-
lang,
31-
});
3228
return code;
3329
})
3430
: code;

apps/dashboard/src/app/(dashboard)/profile/[addressOrEns]/ProfileUI.tsx

Lines changed: 3 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,20 @@
11
import { Spinner } from "@/components/ui/Spinner/Spinner";
22
import { fetchPublishedContracts } from "components/contract-components/fetchPublishedContracts";
3-
import { PublisherSocials } from "components/contract-components/publisher/PublisherSocials";
4-
import { EditProfile } from "components/contract-components/publisher/edit-profile";
5-
import { PublisherAvatar } from "components/contract-components/publisher/masked-avatar";
63
import { DeployedContracts } from "components/contract-components/tables/deployed-contracts";
7-
import type { ProfileMetadata } from "constants/schemas";
84
import { Suspense } from "react";
9-
import { shortenIfAddress } from "utils/usedapp-external";
105
import { getSortedDeployedContracts } from "../../../account/contracts/_components/getSortedDeployedContracts";
6+
import { ProfileHeader } from "./components/profile-header";
117
import { PublishedContracts } from "./components/published-contracts";
128

139
export function ProfileUI(props: {
1410
profileAddress: string;
1511
ensName: string | undefined;
16-
publisherProfile: ProfileMetadata | null;
17-
showEditProfile: boolean;
1812
}) {
19-
const { profileAddress, ensName, publisherProfile, showEditProfile } = props;
20-
21-
const displayName = shortenIfAddress(ensName || profileAddress).replace(
22-
"deployer.thirdweb.eth",
23-
"thirdweb.eth",
24-
);
13+
const { profileAddress, ensName } = props;
2514

2615
return (
2716
<div className="container pt-8 pb-20">
28-
{/* Header */}
29-
<div className="flex w-full flex-col items-center justify-between gap-4 border-border border-b pb-6 md:flex-row">
30-
<div className="flex w-full items-center gap-4">
31-
<PublisherAvatar address={profileAddress} className="size-20" />
32-
<div>
33-
<h1 className="font-semibold text-4xl tracking-tight">
34-
{displayName}
35-
</h1>
36-
37-
{publisherProfile?.bio && (
38-
<p className="line-clamp-2 text-muted-foreground">
39-
{publisherProfile.bio}
40-
</p>
41-
)}
42-
43-
<div className="-translate-x-2 mt-1">
44-
{publisherProfile && (
45-
<PublisherSocials publisherProfile={publisherProfile} />
46-
)}
47-
</div>
48-
</div>
49-
</div>
50-
51-
{showEditProfile && (
52-
<div className="shrink-0">
53-
{publisherProfile && (
54-
<EditProfile publisherProfile={publisherProfile} />
55-
)}
56-
</div>
57-
)}
58-
</div>
59-
17+
<ProfileHeader profileAddress={profileAddress} />
6018
<div className="h-8" />
6119

6220
<div>

apps/dashboard/src/app/(dashboard)/profile/[addressOrEns]/components/PublishedContractTable.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import {
1111
} from "@/components/ui/table";
1212
import { ToolTipLabel } from "@/components/ui/tooltip";
1313
import { TrackedLinkTW } from "@/components/ui/tracked-link";
14-
import { replaceDeployerAddress } from "components/explore/publisher";
1514
import { useTrack } from "hooks/analytics/useTrack";
15+
import { replaceDeployerAddress } from "lib/publisher-utils";
1616
import { replaceIpfsUrl } from "lib/sdk";
1717
import { ShieldCheckIcon } from "lucide-react";
1818
import Link from "next/link";
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
"use client";
2+
3+
import { Skeleton } from "@/components/ui/skeleton";
4+
import { useThirdwebClient } from "@/constants/thirdweb.client";
5+
import { replaceDeployerAddress } from "lib/publisher-utils";
6+
import {
7+
AccountAddress,
8+
AccountAvatar,
9+
AccountBlobbie,
10+
AccountName,
11+
AccountProvider,
12+
} from "thirdweb/react";
13+
import { shortenIfAddress } from "utils/usedapp-external";
14+
15+
export function ProfileHeader(props: { profileAddress: string }) {
16+
const client = useThirdwebClient();
17+
return (
18+
<AccountProvider address={props.profileAddress} client={client}>
19+
<div className="flex w-full flex-col items-center justify-between gap-4 border-border border-b pb-6 md:flex-row">
20+
<div className="flex w-full items-center gap-4">
21+
<AccountAvatar
22+
className="size-20 rounded-full"
23+
loadingComponent={<Skeleton className="size-20 rounded-full" />}
24+
fallbackComponent={
25+
<AccountBlobbie className="size-20 rounded-full" />
26+
}
27+
/>
28+
<div>
29+
<h1 className="font-semibold text-4xl tracking-tight">
30+
<AccountName
31+
fallbackComponent={
32+
<AccountAddress
33+
formatFn={(addr) =>
34+
shortenIfAddress(replaceDeployerAddress(addr))
35+
}
36+
/>
37+
}
38+
loadingComponent={<Skeleton className="h-8 w-40" />}
39+
formatFn={(name) => replaceDeployerAddress(name)}
40+
/>
41+
</h1>
42+
</div>
43+
</div>
44+
</div>
45+
</AccountProvider>
46+
);
47+
}
Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
import { getActiveAccountCookie } from "@/constants/cookie";
2-
import { fetchPublisherProfile } from "components/contract-components/fetch-contracts-with-versions";
1+
import { replaceDeployerAddress } from "lib/publisher-utils";
32
import type { Metadata } from "next";
43
import { notFound } from "next/navigation";
5-
import { getAddress } from "thirdweb/utils";
64
import { shortenIfAddress } from "utils/usedapp-external";
75
import { ProfileUI } from "./ProfileUI";
86
import { resolveAddressAndEns } from "./resolveAddressAndEns";
@@ -16,22 +14,15 @@ type PageProps = {
1614
export default async function Page(props: PageProps) {
1715
const params = await props.params;
1816
const resolvedInfo = await resolveAddressAndEns(params.addressOrEns);
19-
const currentUserAddress = await getCurrentUserAddress();
2017

2118
if (!resolvedInfo) {
2219
return notFound();
2320
}
2421

25-
const publisherProfile = await fetchPublisherProfile(
26-
resolvedInfo.address,
27-
).catch(() => null);
28-
2922
return (
3023
<ProfileUI
3124
ensName={resolvedInfo.ensName}
3225
profileAddress={resolvedInfo.address}
33-
publisherProfile={publisherProfile}
34-
showEditProfile={currentUserAddress === resolvedInfo.address}
3526
/>
3627
);
3728
}
@@ -45,23 +36,11 @@ export async function generateMetadata(props: PageProps): Promise<Metadata> {
4536
}
4637

4738
const displayName = shortenIfAddress(
48-
resolvedInfo.ensName || resolvedInfo.address,
49-
).replace("deployer.thirdweb.eth", "thirdweb.eth");
39+
replaceDeployerAddress(resolvedInfo.ensName || resolvedInfo.address),
40+
);
5041

5142
return {
5243
title: displayName,
5344
description: `Visit ${displayName}'s profile. See their published contracts and deploy them in one click.`,
5445
};
5546
}
56-
57-
async function getCurrentUserAddress() {
58-
try {
59-
const currentUserAddress = await getActiveAccountCookie();
60-
if (!currentUserAddress) {
61-
return null;
62-
}
63-
return getAddress(currentUserAddress);
64-
} catch {
65-
return null;
66-
}
67-
}

apps/dashboard/src/app/(dashboard)/published-contract/[publisher]/[contract_id]/[version]/opengraph-image.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
import { fetchPublisherProfile } from "components/contract-components/fetch-contracts-with-versions";
1+
import { getThirdwebClient } from "@/constants/thirdweb.server";
22
import { format } from "date-fns/format";
3+
import { resolveEns } from "lib/ens";
34
import { correctAndUniqueLicenses } from "lib/licenses";
5+
import { getSocialProfiles } from "thirdweb/social";
46
import { getPublishedContractsWithPublisherMapping } from "../utils/getPublishedContractsWithPublisherMapping";
57
import { publishedContractOGImageTemplate } from "../utils/publishedContractOGImageTemplate";
68

@@ -18,20 +20,33 @@ export default async function Image(props: {
1820
version: string;
1921
};
2022
}) {
23+
const client = getThirdwebClient();
2124
const { publisher, contract_id } = props.params;
2225

23-
const [publishedContracts, publisherProfile] = await Promise.all([
26+
const [publishedContracts, socialProfiles] = await Promise.all([
2427
getPublishedContractsWithPublisherMapping({
2528
publisher: publisher,
2629
contract_id: contract_id,
2730
}),
28-
fetchPublisherProfile(publisher),
31+
getSocialProfiles({
32+
address: (await resolveEns(publisher)).address || publisher,
33+
client,
34+
}),
2935
]);
3036

3137
if (!publishedContracts) {
3238
return null;
3339
}
3440

41+
const publisherProfile = (() => {
42+
const name = socialProfiles.find((p) => p.name)?.name || publisher;
43+
const avatar = socialProfiles.find((p) => p.avatar)?.avatar;
44+
return {
45+
name,
46+
avatar,
47+
};
48+
})();
49+
3550
const publishedContract =
3651
publishedContracts.find((p) => p.version === props.params.version) ||
3752
publishedContracts[0];

apps/dashboard/src/app/(dashboard)/published-contract/[publisher]/[contract_id]/opengraph-image.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
import { fetchPublisherProfile } from "components/contract-components/fetch-contracts-with-versions";
1+
import { getThirdwebClient } from "@/constants/thirdweb.server";
22
import { format } from "date-fns/format";
3+
import { resolveEns } from "lib/ens";
34
import { correctAndUniqueLicenses } from "lib/licenses";
5+
import { getSocialProfiles } from "thirdweb/social";
46
import { getPublishedContractsWithPublisherMapping } from "./utils/getPublishedContractsWithPublisherMapping";
57
import { publishedContractOGImageTemplate } from "./utils/publishedContractOGImageTemplate";
68

@@ -17,16 +19,29 @@ export default async function Image(props: {
1719
contract_id: string;
1820
};
1921
}) {
22+
const client = getThirdwebClient();
2023
const { publisher, contract_id } = props.params;
2124

22-
const [publishedContracts, publisherProfile] = await Promise.all([
25+
const [publishedContracts, socialProfiles] = await Promise.all([
2326
getPublishedContractsWithPublisherMapping({
2427
publisher: publisher,
2528
contract_id: contract_id,
2629
}),
27-
fetchPublisherProfile(publisher),
30+
getSocialProfiles({
31+
address: (await resolveEns(publisher)).address || publisher,
32+
client,
33+
}),
2834
]);
2935

36+
const publisherProfile = (() => {
37+
const name = socialProfiles.find((p) => p.name)?.name || publisher;
38+
const avatar = socialProfiles.find((p) => p.avatar)?.avatar;
39+
return {
40+
name,
41+
avatar,
42+
};
43+
})();
44+
3045
if (!publishedContracts) {
3146
return null;
3247
}

apps/dashboard/src/components/contract-components/fetch-contracts-with-versions.ts

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
import { getThirdwebClient } from "@/constants/thirdweb.server";
2-
import type { ProfileMetadata } from "constants/schemas";
32
import { isAddress } from "thirdweb";
43
import { fetchDeployMetadata } from "thirdweb/contract";
54
import { resolveAddress } from "thirdweb/extensions/ens";
65
import {
76
getContractPublisher,
87
getPublishedContractVersions,
9-
getPublisherProfileUri,
108
} from "thirdweb/extensions/thirdweb";
11-
import { download } from "thirdweb/storage";
129

1310
export function mapThirdwebPublisher(publisher: string) {
1411
if (publisher === "thirdweb.eth") {
@@ -18,34 +15,6 @@ export function mapThirdwebPublisher(publisher: string) {
1815
return publisher;
1916
}
2017

21-
export async function fetchPublisherProfile(publisherAddress: string) {
22-
const client = getThirdwebClient();
23-
24-
const profileUri = await getPublisherProfileUri({
25-
contract: getContractPublisher(client),
26-
publisher: isAddress(publisherAddress)
27-
? publisherAddress
28-
: await resolveAddress({
29-
client,
30-
name: mapThirdwebPublisher(publisherAddress),
31-
}),
32-
});
33-
34-
if (!profileUri) {
35-
return null;
36-
}
37-
38-
try {
39-
const res = await download({
40-
client,
41-
uri: profileUri,
42-
});
43-
return res.json() as Promise<ProfileMetadata>;
44-
} catch {
45-
return null;
46-
}
47-
}
48-
4918
export async function fetchPublishedContractVersions(
5019
publisherAddress: string,
5120
contractId: string,

apps/dashboard/src/components/contract-components/hooks.ts

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,10 @@ import { isAddress } from "thirdweb/utils";
1212
import {
1313
type PublishedContractWithVersion,
1414
fetchPublishedContractVersions,
15-
fetchPublisherProfile,
1615
} from "./fetch-contracts-with-versions";
1716
import { fetchPublishedContracts } from "./fetchPublishedContracts";
1817
import { fetchPublishedContractsFromDeploy } from "./fetchPublishedContractsFromDeploy";
1918

20-
function publisherProfileQuery(publisherAddress?: string) {
21-
return queryOptions({
22-
queryKey: ["releaser-profile", publisherAddress],
23-
queryFn: () => {
24-
if (!publisherAddress) {
25-
throw new Error("publisherAddress is not defined");
26-
}
27-
return fetchPublisherProfile(publisherAddress);
28-
},
29-
enabled: !!publisherAddress,
30-
// 24h
31-
gcTime: 60 * 60 * 24 * 1000,
32-
// 1h
33-
staleTime: 60 * 60 * 1000,
34-
});
35-
}
36-
37-
export function usePublisherProfile(publisherAddress?: string) {
38-
return useQuery(publisherProfileQuery(publisherAddress));
39-
}
40-
4119
export function useAllVersions(
4220
publisherAddress: string | undefined,
4321
contractId: string | undefined,

0 commit comments

Comments
 (0)