From 13155a37d3db4869a5c4d8c44f144a82efcd8e9f Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Wed, 9 Aug 2023 15:19:41 +0800 Subject: [PATCH 1/3] add contenthash to profile tab --- e2e/specs/stateless/profileEditor.spec.ts | 2 ++ playwright/pageObjects/profilePage.ts | 4 ++++ src/components/pages/profile/ProfileButton.tsx | 17 ++++++++++++++--- src/components/pages/profile/ProfileDetails.tsx | 7 +++++++ .../pages/profile/[name]/tabs/ProfileTab.tsx | 1 + 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/e2e/specs/stateless/profileEditor.spec.ts b/e2e/specs/stateless/profileEditor.spec.ts index 71d2af633..d5ae1d87c 100644 --- a/e2e/specs/stateless/profileEditor.spec.ts +++ b/e2e/specs/stateless/profileEditor.spec.ts @@ -35,6 +35,7 @@ const DEFAULT_RECORDS = { value: '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC', }, ], + contentHash: 'ipfs://bafybeico3uuyj3vphxpvbowchdwjlrlrh62awxscrnii7w7flu5z6fk77y', } test.describe('unwrapped', () => { @@ -172,6 +173,7 @@ test.describe('unwrapped', () => { 'ETC_LEGACY0x3C4...293BC', ) await expect(profilePage.record('text', 'email')).toHaveText('fakeemail@fake.com') + await expect(profilePage.contentHash()).toContainText('ipfs://bafybeic...') await profilePage.editProfileButton.click() await profilePage.profileEditor.getByTestId('warning-overlay-next-button').click() diff --git a/playwright/pageObjects/profilePage.ts b/playwright/pageObjects/profilePage.ts index 7cb240fc5..5dccd6d2e 100644 --- a/playwright/pageObjects/profilePage.ts +++ b/playwright/pageObjects/profilePage.ts @@ -63,6 +63,10 @@ export class ProfilePage { return this.page.getByTestId(`other-profile-button-${key}`) } + contentHash(): Locator { + return this.page.getByTestId('other-profile-button-contenthash') + } + async profileEditorAddInputs(keys: string[]) { await this.page.getByTestId('show-add-profile-records-modal-button').click() for (const key of keys) { diff --git a/src/components/pages/profile/ProfileButton.tsx b/src/components/pages/profile/ProfileButton.tsx index 2f19817fd..1232833bd 100644 --- a/src/components/pages/profile/ProfileButton.tsx +++ b/src/components/pages/profile/ProfileButton.tsx @@ -11,6 +11,7 @@ import { DynamicSocialIcon, socialIconTypes } from '@app/assets/social/DynamicSo import { usePrimary } from '@app/hooks/usePrimary' import { getDestination } from '@app/routes' import { useBreakpoint } from '@app/utils/BreakpointProvider' +import { getContentHashLink, getProtocolTypeAndContentId } from '@app/utils/contenthash' import { getSocialData } from '@app/utils/getSocialData' import { shortenAddress } from '@app/utils/utils' @@ -105,10 +106,11 @@ export const OtherProfileButton = ({ }: { iconKey: string value: string - type?: 'text' | 'address' + type?: 'text' | 'address' | 'contenthash' }) => { const breakpoints = useBreakpoint() - const isLink = value?.startsWith('http://') || value?.startsWith('https://') + const isLink = + value?.startsWith('http://') || value?.startsWith('https://') || type === 'contenthash' const formattedValue = useMemo(() => { if (breakpoints.sm) { @@ -122,11 +124,20 @@ export const OtherProfileButton = ({ const linkProps = useMemo(() => { if (!isLink) return {} + if (type === 'contenthash') { + const { protocolType, contentId } = getProtocolTypeAndContentId(value) + const _link = getContentHashLink('', 0, { protocolType, decoded: contentId }) + if (!_link) return {} + return { + as: 'a', + link: _link, + } as const + } return { as: 'a', link: value, } as const - }, [value, isLink]) + }, [value, type, isLink]) return ( > addresses: Array> + contentHash?: ContentHash expiryDate: Date | undefined pccExpired: boolean owners: ReturnType @@ -310,6 +314,9 @@ export const ProfileDetails = ({ !supportedProfileItems.includes(x.key.toLowerCase()), ) .map((x) => ({ ...x, type: 'text' })), + ...(contentHash + ? [{ key: 'contenthash', type: 'contenthash', value: contentHashToString(contentHash) }] + : []), ] const mappedOwners = ownershipInfoCalc(name, pccExpired, owners, gracePeriodEndDate, expiryDate) diff --git a/src/components/pages/profile/[name]/tabs/ProfileTab.tsx b/src/components/pages/profile/[name]/tabs/ProfileTab.tsx index 5701e9b3c..e998fc107 100644 --- a/src/components/pages/profile/[name]/tabs/ProfileTab.tsx +++ b/src/components/pages/profile/[name]/tabs/ProfileTab.tsx @@ -128,6 +128,7 @@ const ProfileTab = ({ nameDetails, name }: Props) => { textRecords={(profile?.records?.texts || []) .map((item: any) => ({ key: item.key, value: item.value })) .filter((item: any) => item.value !== null)} + contentHash={profile?.records?.contentHash} owners={owners} name={normalisedName} actions={profileActions.profileActions} From bacb891ef27b0ac4bf41963aa6f7247421b23e22 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Mon, 28 Aug 2023 19:09:01 +0800 Subject: [PATCH 2/3] convert contenthash to string before adding to other records --- src/components/pages/profile/ProfileDetails.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/pages/profile/ProfileDetails.tsx b/src/components/pages/profile/ProfileDetails.tsx index 421e1999d..a248f7d7d 100644 --- a/src/components/pages/profile/ProfileDetails.tsx +++ b/src/components/pages/profile/ProfileDetails.tsx @@ -306,6 +306,7 @@ export const ProfileDetails = ({ }) => { const breakpoint = useBreakpoint() + const _contentHash = contentHashToString(contentHash) const otherRecords = [ ...textRecords .filter( @@ -314,9 +315,7 @@ export const ProfileDetails = ({ !supportedProfileItems.includes(x.key.toLowerCase()), ) .map((x) => ({ ...x, type: 'text' })), - ...(contentHash - ? [{ key: 'contenthash', type: 'contenthash', value: contentHashToString(contentHash) }] - : []), + ...(_contentHash ? [{ key: 'contenthash', type: 'contenthash', value: _contentHash }] : []), ] const mappedOwners = ownershipInfoCalc(name, pccExpired, owners, gracePeriodEndDate, expiryDate) From a709d3e9c94e88ac084a85832c9e2ffc91932899 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Mon, 28 Aug 2023 19:33:33 +0800 Subject: [PATCH 3/3] added tests for content hash display on ProfileDetails --- .../pages/profile/ProfileDetails.test.tsx | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/components/pages/profile/ProfileDetails.test.tsx b/src/components/pages/profile/ProfileDetails.test.tsx index 8b4602ac5..12ccb0a28 100644 --- a/src/components/pages/profile/ProfileDetails.test.tsx +++ b/src/components/pages/profile/ProfileDetails.test.tsx @@ -4,6 +4,19 @@ import { OwnerArray } from '@app/types' import { ownershipInfoCalc } from './ProfileDetails' +import { ProfileDetails } from './ProfileDetails' +import { render, screen } from '@app/test-utils' + +jest.mock('@app/utils/BreakpointProvider', () => ({ + useBreakpoint: () => ({ + xs: true, + sm: true, + md: true, + lg: true, + xl: false, + }) +})) + describe('onwershipInfoCalc', () => { it('should return no owner if PCC is expired', () => { const result = ownershipInfoCalc('', true, [], new Date(), new Date()) @@ -95,3 +108,16 @@ describe('onwershipInfoCalc', () => { ]) }) }) + +describe('ProfileDetails', () => { + it('should show content hash if there is valid contenthash', () => { + render() + expect(screen.getByTestId('other-profile-button-contenthash')).toBeVisible() + expect(screen.getByText('ipfs://QmXoypiz...')).toBeVisible() + }) + + it('should not show content hash if contenthash is empty', () => { + render() + expect(screen.queryByTestId('other-profile-button-contenthash')).toBeNull() + }) +}) \ No newline at end of file