Skip to content

Commit

Permalink
feat: support attributes and image in non-collectable publications (
Browse files Browse the repository at this point in the history
#463)

* Proposal: support attributes and image in non-collectable publications

* Implements proposal

* Adds changeset

* Adds changeset

* Ensures collectable publications can use top level attributes and image without annoying validation errors
  • Loading branch information
cesarenaldi authored Aug 4, 2023
1 parent ea1fcc3 commit 9428efe
Show file tree
Hide file tree
Showing 13 changed files with 493 additions and 148 deletions.
7 changes: 7 additions & 0 deletions .changeset/thirty-carpets-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@lens-protocol/react": minor
"@lens-protocol/react-web": minor
"@lens-protocol/domain": patch
---

**Added** support for `attributes` and `image` for non-collectable publications. Affects `useCreatePost`, `useCreateComment`, `useCreateEncryptedPost`, and `useCreateEncryptedComment`
31 changes: 30 additions & 1 deletion packages/domain/src/use-cases/publications/CreateComment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@ import {
} from '../../entities';
import { DelegableSigning } from '../transactions/DelegableSigning';
import { ReferencePolicyConfig } from './ReferencePolicyConfig';
import { CollectPolicyConfig, ContentFocus, ContentWarning, Locale, MediaObject } from './types';
import {
CollectPolicyConfig,
ContentFocus,
ContentWarning,
Locale,
MediaObject,
MetadataAttribute,
MetadataImage,
} from './types';

/**
* @alpha
Expand Down Expand Up @@ -71,6 +79,27 @@ export type BaseCommentRequest = {
* These are not the same as #hashtag in the publication content. Use these if you don't want to clutter the publication content with tags.
*/
tags?: string[];
/**
* A list of attributes for the collect NFT.
*
* This is the NFT description visible on marketplaces like OpenSea.
*/
attributes?: MetadataAttribute[];
/**
* The collect NFT image.
*
* This is the NFT image visible on marketplaces like OpenSea.
*
* DO NOT use this as primary storage for publication media. Use the `media` property instead.
* In the case your publication has many media consider to use this field as a static representation
* of the collect NFT. For example if the publication is an album of audio files this could be
* used as album cover image. If the publication is a gallery of images, this could be the gallery
* cover image.
*
* DO NOT use this as media cover image.
* For individual media cover image (e.g. the video thumbnail image) use the `media[n].cover` (see {@link MediaObject}).
*/
image?: MetadataImage;
};

export type CreateTextualCommentRequest = BaseCommentRequest & {
Expand Down
31 changes: 30 additions & 1 deletion packages/domain/src/use-cases/publications/CreatePost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@ import { Url, invariant } from '@lens-protocol/shared-kernel';
import { AppId, DecryptionCriteria, ProfileId, TransactionKind } from '../../entities';
import { DelegableSigning } from '../transactions/DelegableSigning';
import { ReferencePolicyConfig } from './ReferencePolicyConfig';
import { CollectPolicyConfig, ContentFocus, ContentWarning, Locale, MediaObject } from './types';
import {
CollectPolicyConfig,
ContentFocus,
ContentWarning,
Locale,
MediaObject,
MetadataAttribute,
MetadataImage,
} from './types';

/**
* @alpha
Expand Down Expand Up @@ -61,6 +69,27 @@ export type BasePostRequest = {
* These are not the same as #hashtag in the publication content. Use these if you don't want to clutter the publication content with tags.
*/
tags?: string[];
/**
* A list of attributes for the collect NFT.
*
* This is the NFT description visible on marketplaces like OpenSea.
*/
attributes?: MetadataAttribute[];
/**
* The collect NFT image.
*
* This is the NFT image visible on marketplaces like OpenSea.
*
* DO NOT use this as primary storage for publication media. Use the `media` property instead.
* In the case your publication has many media consider to use this field as a static representation
* of the collect NFT. For example if the publication is an album of audio files this could be
* used as album cover image. If the publication is a gallery of images, this could be the gallery
* cover image.
*
* DO NOT use this as media cover image.
* For individual media cover image (e.g. the video thumbnail image) use the `media[n].cover` (see {@link MediaObject}).
*/
image?: MetadataImage;
};

export type CreateTextualPostRequest = BasePostRequest & {
Expand Down
25 changes: 17 additions & 8 deletions packages/domain/src/use-cases/publications/__helpers__/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ import {
ContentFocus,
FreeCollectPolicyConfig,
MediaObject,
NftAttribute,
NftAttributeDisplayType,
MetadataAttribute,
MetadataAttributeDisplayType,
MetadataImage,
NftMetadata,
NoCollectPolicyConfig,
SimpleChargeCollectPolicyConfig,
Expand Down Expand Up @@ -62,25 +63,33 @@ export function mockMediaObject(overrides?: Partial<MediaObject>): MediaObject {
};
}

export function mockDateNftAttribute(): NftAttribute {
export function mockMetadataImage(overrides?: Partial<MetadataImage>): MetadataImage {
return {
displayType: NftAttributeDisplayType.Date,
url: faker.image.imageUrl(),
mimeType: ImageType.JPEG,
...overrides,
};
}

export function mockDateMetadataAttribute(): MetadataAttribute {
return {
displayType: MetadataAttributeDisplayType.Date,
traitType: faker.lorem.word(),
value: faker.date.past(),
};
}

export function mockNumberNftAttribute(): NftAttribute {
export function mockNumberMetadataAttribute(): MetadataAttribute {
return {
displayType: NftAttributeDisplayType.Number,
displayType: MetadataAttributeDisplayType.Number,
traitType: faker.lorem.word(),
value: faker.datatype.number(),
};
}

export function mockStringNftAttribute(): NftAttribute {
export function mockStringMetadataAttribute(): MetadataAttribute {
return {
displayType: NftAttributeDisplayType.String,
displayType: MetadataAttributeDisplayType.String,
traitType: faker.lorem.word(),
value: faker.lorem.word(),
};
Expand Down
31 changes: 23 additions & 8 deletions packages/domain/src/use-cases/publications/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,54 +53,69 @@ export enum ContentWarning {
SPOILER = 'Spoiler',
}

export enum NftAttributeDisplayType {
export enum MetadataAttributeDisplayType {
Number = 'Number',
String = 'String',
Date = 'Date',
}

export type NftAttribute =
export type MetadataAttribute =
| {
displayType: NftAttributeDisplayType.Date;
displayType: MetadataAttributeDisplayType.Date;
value: Date;
traitType: string;
}
| {
displayType: NftAttributeDisplayType.Number;
displayType: MetadataAttributeDisplayType.Number;
value: number;
traitType: string;
}
| {
displayType: NftAttributeDisplayType.String;
displayType: MetadataAttributeDisplayType.String;
value: string;
traitType: string;
};

export type MetadataImage = {
url: Url;
mimeType: ImageType;
};

export type NftMetadata = {
/**
* The name of the NFT.
* The name of the collect NFT.
*
* This is the NFT name visible on marketplaces like OpenSea.
*/
name: string;
/**
* The description of the NFT.
* The description of the collect NFT.
*
* This is the NFT description visible on marketplaces like OpenSea.
*/
description?: string;
/**
* A list of attributes for the NFT.
*
* @deprecated Use the `attributes` field at the request object top level.
*/
attributes: NftAttribute[];
attributes?: MetadataAttribute[];
/**
* This is the URL that will appear below the asset's image on OpenSea and other marketplaces.
* It will allow users to leave OpenSea and view the item on the external site.
*/
externalUrl?: Url;
/**
* Legacy to support OpenSea schema, store any NFT image here.
*
* @deprecated Use the `image` field at the request object top level.
*/
image?: Url;
/**
* This is the mime type of the image. This is used if you are uploading more advanced
* cover images as sometimes IPFS does not emit the content header so this solves that.
*
* @deprecated Use the `image` field at the request object top level.
*/
imageMimeType?: ImageType;
};
Expand Down
14 changes: 14 additions & 0 deletions packages/react/src/deprecated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ import {
UnknownFollowModuleSettings,
WhoReactedResult,
} from '@lens-protocol/api-bindings';
import {
MetadataAttribute,
MetadataAttributeDisplayType,
} from '@lens-protocol/domain/use-cases/publications';
import { AnyTransactionRequest } from '@lens-protocol/domain/use-cases/transactions';
import { LoginError } from '@lens-protocol/domain/use-cases/wallets';

Expand Down Expand Up @@ -298,3 +302,13 @@ export enum ReactionType {
UPVOTE = ReactionTypes.Upvote,
DOWNVOTE = ReactionTypes.Downvote,
}

/**
* @deprecated Use {@link MetadataAttribute} instead.
*/
export type NftAttribute = MetadataAttribute;

/**
* @deprecated Use {@link MetadataAttributeDisplayType} instead.
*/
export type NftAttributeDisplayType = MetadataAttributeDisplayType;
Loading

0 comments on commit 9428efe

Please sign in to comment.