Skip to content

Commit

Permalink
react: enable useLinkHandle and useUnlinkHandle hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
krzysu committed Oct 26, 2023
1 parent b9facc3 commit 19c3f94
Show file tree
Hide file tree
Showing 15 changed files with 170 additions and 54 deletions.
8 changes: 8 additions & 0 deletions .changeset/smooth-ties-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@lens-protocol/api-bindings": minor
"@lens-protocol/domain": minor
"@lens-protocol/react": minor
"@lens-protocol/react-web": minor
---

Added useLinkHandle and useUnlinkHandle hooks
6 changes: 2 additions & 4 deletions examples/web/src/profiles/ProfilesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,8 @@ const profileHooks = [
path: '/profiles/useUpdateFollowPolicy',
},
{
label: 'useOwnedHandles',
// label: 'useOwnedHandles & useLinkHandle & useUnlinkHandle',
// description: `Link and unlink handle from a profile.`,
description: `Fetch all handles owned by a wallet.`,
label: 'useOwnedHandles & useLinkHandle & useUnlinkHandle',
description: `Link and unlink handle from a profile.`,
path: '/profiles/useOwnedHandles',
},
];
Expand Down
74 changes: 49 additions & 25 deletions examples/web/src/profiles/UseOwnedHandles.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,65 @@
import {
EvmAddress,
HandleInfo,
Profile,
ProfileId,
useLinkHandle,
useOwnedHandles,
useProfiles,
useUnlinkHandle,
} from '@lens-protocol/react-web';
import toast from 'react-hot-toast';

import { UnauthenticatedFallback, WhenLoggedIn, WhenLoggedOut } from '../components/auth';
import { ErrorMessage } from '../components/error/ErrorMessage';
import { Loading } from '../components/loading/Loading';

type LinkHandleButtonProps = {
handle: string;
handle: HandleInfo;
};

function LinkHandleButton({ handle }: LinkHandleButtonProps) {
const { execute, error, loading } = useLinkHandle();

if (error) {
toast.error(error.message);
}

return (
<>
<button onClick={() => execute({ handle })} disabled={loading} style={{ padding: '1px 6px' }}>
Link
</button>
{error && <p>{error.message}</p>}
</>
<button
onClick={() => execute({ fullHandle: handle.fullHandle })}
disabled={loading}
style={{ padding: '1px 6px', margin: 0 }}
>
Link
</button>
);
}

type UnlinkHandleButtonProps = {
handle: string;
handle: HandleInfo;
profileId: ProfileId;
};

function UnlinkHandleButton({ handle }: UnlinkHandleButtonProps) {
function UnlinkHandleButton({ handle, profileId }: UnlinkHandleButtonProps) {
const { execute, error, loading } = useUnlinkHandle();

if (error) {
toast.error(error.message);
}

const isUnlinkable = handle.linkedTo?.nftTokenId === profileId;

if (!isUnlinkable) return null;

return (
<>
<button onClick={() => execute({ handle })} disabled={loading} style={{ padding: '1px 6px' }}>
Unlink
</button>
{error && <p>{error.message}</p>}
</>
<button
onClick={() => execute({ fullHandle: handle.fullHandle })}
disabled={loading}
style={{ padding: '1px 6px', margin: 0 }}
>
Unlink
</button>
);
}

Expand Down Expand Up @@ -74,8 +92,13 @@ function UseOwnedProfiles({ address }: { address: EvmAddress }) {
);
}

// eslint-disable-next-line
function UseOwnedHandlesInner({ address }: { address: EvmAddress }) {
function UseOwnedHandlesInner({
address,
profileId,
}: {
address: EvmAddress;
profileId: ProfileId;
}) {
const {
data: handleResult,
loading,
Expand All @@ -94,9 +117,8 @@ function UseOwnedHandlesInner({ address }: { address: EvmAddress }) {
<ul>
{handleResult.map((handle, index) => (
<li key={index}>
<div>{handle.fullHandle}</div>
<LinkHandleButton handle={handle.fullHandle} />{' '}
<UnlinkHandleButton handle={handle.fullHandle} />
<span>{handle.fullHandle}</span> <LinkHandleButton handle={handle} />{' '}
<UnlinkHandleButton handle={handle} profileId={profileId} />
</li>
))}
</ul>
Expand All @@ -112,13 +134,16 @@ type ContentProps = {
function Content({ address, profile }: ContentProps) {
return (
<div>
<p>Wallet address: {address}.</p>
<p>
Active profile: {profile.id}. Current handle {profile.handle?.fullHandle || 'NOT LINKED'}
Wallet address: <strong>{address}</strong>.
</p>
<p>
Active profile: <strong>{profile.id}</strong>. Current handle{' '}
<strong>{profile.handle?.fullHandle || 'NOT LINKED'}</strong>.
</p>
<div style={{ display: 'flex' }}>
<UseOwnedProfiles address={address} />
{/* <UseOwnedHandlesInner address={address} /> */}
<UseOwnedHandlesInner address={address} profileId={profile.id} />
</div>
</div>
);
Expand All @@ -128,8 +153,7 @@ export function UseOwnedHandles() {
return (
<div>
<h1>
{/* <code>useOwnedHandles & useLinkHandle & useUnlinkHandle</code> */}
<code>useOwnedHandles</code>
<code>useOwnedHandles & useLinkHandle & useUnlinkHandle</code>
</h1>

<WhenLoggedIn>
Expand Down
37 changes: 36 additions & 1 deletion packages/api-bindings/src/apollo/cache/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import {
TransactionErrorReason,
TransactionKind,
} from '@lens-protocol/domain/entities';
import { FollowRequest, UnfollowRequest } from '@lens-protocol/domain/use-cases/profile';
import {
FollowRequest,
LinkHandleRequest,
UnfollowRequest,
UnlinkHandleRequest,
} from '@lens-protocol/domain/use-cases/profile';
import { OpenActionRequest, AllOpenActionType } from '@lens-protocol/domain/use-cases/publications';
import { AnyTransactionRequest } from '@lens-protocol/domain/use-cases/transactions';
import { DateUtils } from '@lens-protocol/shared-kernel';
Expand Down Expand Up @@ -174,3 +179,33 @@ export function countPendingUnfollowFor(profileId: ProfileId) {
0,
);
}

function isPendingLinkHandleTransaction(
transaction: TransactionState<AnyTransactionRequest>,
): transaction is TransactionState<LinkHandleRequest> {
return (
transaction.request.kind === TransactionKind.LINK_HANDLE &&
transaction.status === TxStatus.PENDING
);
}

export function getPendingLinkHandleTx() {
return recentTransactionsVar().find((transaction) => {
return isPendingLinkHandleTransaction(transaction);
}) as TransactionState<LinkHandleRequest> | undefined;
}

function isPendingUnlinkHandleTransaction(
transaction: TransactionState<AnyTransactionRequest>,
): transaction is TransactionState<UnlinkHandleRequest> {
return (
transaction.request.kind === TransactionKind.UNLINK_HANDLE &&
transaction.status === TxStatus.PENDING
);
}

export function getPendingUnlinkHandleTx() {
return recentTransactionsVar().find((transaction) => {
return isPendingUnlinkHandleTransaction(transaction);
}) as TransactionState<UnlinkHandleRequest> | undefined;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,60 @@
import { StrictTypedTypePolicies } from '../../../lens';
import { FieldFunctionOptions } from '@apollo/client';
import { ProfileId } from '@lens-protocol/domain/entities';

import { HandleInfo, StrictTypedTypePolicies } from '../../../lens';
import { getPendingLinkHandleTx, getPendingUnlinkHandleTx } from '../transactions';

function buildHandleInfo({
fullHandle,
profileId,
}: {
fullHandle: string;
profileId: ProfileId;
}): HandleInfo {
return {
__typename: 'HandleInfo',
id: '',
fullHandle: fullHandle,
namespace: '',
localName: '',
ownedBy: '',
suggestedFormatted: { full: '', localName: '' },
linkedTo: {
nftTokenId: profileId,
contract: {
__typename: 'NetworkAddress',
address: '',
chainId: 1,
},
},
};
}

export function createProfileTypePolicy(): StrictTypedTypePolicies['Profile'] {
return {
fields: {},
fields: {
handle: {
read(
existing: HandleInfo | undefined,
{ readField }: FieldFunctionOptions,
): HandleInfo | undefined {
const profileId = readField('id') as ProfileId;
const pendingLinkHandleTx = getPendingLinkHandleTx();
const pendingUnLinkHandleTx = getPendingUnlinkHandleTx();

if (pendingLinkHandleTx) {
return buildHandleInfo({
profileId,
fullHandle: pendingLinkHandleTx.request.fullHandle,
});
}
if (pendingUnLinkHandleTx) {
return undefined;
}

return existing;
},
},
},
};
}
2 changes: 1 addition & 1 deletion packages/domain/src/use-cases/profile/LinkHandle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { TransactionKind } from '../../entities';
import { DelegableSigning } from '../transactions/DelegableSigning';

export type LinkHandleRequest = {
handle: string;
fullHandle: string;
kind: TransactionKind.LINK_HANDLE;
delegate: boolean;
};
Expand Down
2 changes: 1 addition & 1 deletion packages/domain/src/use-cases/profile/UnlinkHandle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { TransactionKind } from '../../entities';
import { DelegableSigning } from '../transactions/DelegableSigning';

export type UnlinkHandleRequest = {
handle: string;
fullHandle: string;
kind: TransactionKind.UNLINK_HANDLE;
delegate: boolean;
};
Expand Down
4 changes: 2 additions & 2 deletions packages/domain/src/use-cases/profile/__helpers__/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export function mockINftOwnershipChallengeGateway({

export function mockLinkHandleRequest(overrides?: Partial<LinkHandleRequest>): LinkHandleRequest {
return {
handle: faker.internet.userName(),
fullHandle: faker.internet.userName(),
delegate: true,
...overrides,
kind: TransactionKind.LINK_HANDLE,
Expand All @@ -181,7 +181,7 @@ export function mockUnlinkHandleRequest(
overrides?: Partial<UnlinkHandleRequest>,
): UnlinkHandleRequest {
return {
handle: faker.internet.userName(),
fullHandle: faker.internet.userName(),
delegate: true,
...overrides,
kind: TransactionKind.UNLINK_HANDLE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class LinkHandleGateway
mutation: LinkHandleToProfileDocument,
variables: {
request: {
handle: request.handle,
handle: request.fullHandle,
},
},
});
Expand All @@ -101,7 +101,7 @@ export class LinkHandleGateway
mutation: CreateLinkHandleToProfileTypedDataDocument,
variables: {
request: {
handle: request.handle,
handle: request.fullHandle,
},
options: nonce ? { overrideSigNonce: nonce } : undefined,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class UnlinkHandleGateway
mutation: UnlinkHandleFromProfileDocument,
variables: {
request: {
handle: request.handle,
handle: request.fullHandle,
},
},
});
Expand All @@ -101,7 +101,7 @@ export class UnlinkHandleGateway
mutation: CreateUnlinkHandleFromProfileTypedDataDocument,
variables: {
request: {
handle: request.handle,
handle: request.fullHandle,
},
options: nonce ? { overrideSigNonce: nonce } : undefined,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe(`Given an instance of ${LinkHandleGateway.name}`, () => {
mockCreateLinkHandleToProfileTypedDataResponse({
variables: {
request: {
handle: request.handle,
handle: request.fullHandle,
},
},
data,
Expand All @@ -54,7 +54,7 @@ describe(`Given an instance of ${LinkHandleGateway.name}`, () => {
mockLinkHandleToProfileResponse({
variables: {
request: {
handle: request.handle,
handle: request.fullHandle,
},
},
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe(`Given an instance of ${UnlinkHandleGateway.name}`, () => {
mockCreateUnlinkHandleFromProfileTypedDataResponse({
variables: {
request: {
handle: request.handle,
handle: request.fullHandle,
},
},
data,
Expand All @@ -54,7 +54,7 @@ describe(`Given an instance of ${UnlinkHandleGateway.name}`, () => {
mockUnlinkHandleFromProfileResponse({
variables: {
request: {
handle: request.handle,
handle: request.fullHandle,
},
},
data: {
Expand Down
4 changes: 2 additions & 2 deletions packages/react/src/transactions/adapters/schemas/profiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,13 @@ export const SetProfileMetadataRequestSchema = z.object({
});

export const LinkHandleRequestSchema = z.object({
handle: z.string(),
fullHandle: z.string(),
kind: z.literal(TransactionKind.LINK_HANDLE),
delegate: z.boolean(),
});

export const UnlinkHandleRequestSchema = z.object({
handle: z.string(),
fullHandle: z.string(),
kind: z.literal(TransactionKind.UNLINK_HANDLE),
delegate: z.boolean(),
});
Expand Down
Loading

0 comments on commit 19c3f94

Please sign in to comment.