Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: exposes params.statsFor and params.profile.metadataSource in LensConfig #686

Merged
merged 5 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/four-squids-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@lens-protocol/api-bindings": minor
"@lens-protocol/react": minor
"@lens-protocol/react-native": minor
"@lens-protocol/react-web": minor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can add react-native now too

---

**feat:** introduces `params.statsFor` and `params.profile.metadataSource` in `LensConfig`
4 changes: 2 additions & 2 deletions packages/api-bindings/src/apollo/__helpers__/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { MockedResponse, mockSingleLink } from '@apollo/client/testing';
import { DocumentNode, ExecutionResult, GraphQLError } from 'graphql';

import { SafeApolloClient } from '../SafeApolloClient';
import { createLensCache, createSnapshotCache } from '../cache';
import { createLensCache, createSnapshotCache, defaultQueryParams } from '../cache';
import { ApolloServerErrorCode } from '../errors';

export function mockLensApolloClient(
mocks: ReadonlyArray<MockedResponse<unknown>> = [],
): SafeApolloClient<NormalizedCacheObject> {
return new SafeApolloClient({
cache: createLensCache(),
cache: createLensCache(defaultQueryParams),

link: mockSingleLink(...mocks).setOnError((error) => {
throw error;
Expand Down
4 changes: 2 additions & 2 deletions packages/api-bindings/src/apollo/cache/createLensCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ export type { QueryParams };

export { defaultQueryParams } from './createQueryParamsLocalFields';

export function createLensCache(options?: QueryParams): ApolloCache<NormalizedCacheObject> {
export function createLensCache(params?: QueryParams): ApolloCache<NormalizedCacheObject> {
return new InMemoryCache({
possibleTypes: generatedIntrospection.possibleTypes,
typePolicies: createTypePolicies(options),
typePolicies: createTypePolicies(params),
});
}
117 changes: 79 additions & 38 deletions packages/api-bindings/src/apollo/cache/createQueryParamsLocalFields.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,77 @@
import { FieldReadFunction } from '@apollo/client';
import { FieldFunctionOptions, FieldReadFunction } from '@apollo/client';
import { AppId } from '@lens-protocol/domain/entities';
import { UnknownObject } from '@lens-protocol/shared-kernel';

import { ImageSizeTransform, ImageTransform, SupportedFiatType } from '../../lens';

/**
* The common query parameters used across any query.
*/
export type QueryParams = {
image: {
/**
* The size of the publication image.
*
* @defaultValue see individual fields
*/
image?: {
/**
* The size of the small publication image
*
* @defaultValue width: 400px, height: auto, keepAspectRatio: true
*/
small: ImageTransform;
small?: ImageTransform;
/**
* The size of the medium publication image
*
* @defaultValue width: 700px, height: auto, keepAspectRatio: true
*/
medium: ImageTransform;
medium?: ImageTransform;
};
profile: {
/**
* Profile related fields parameters
*
* @defaultValue see individual fields
*/
profile?: {
/**
* The size of optimized profile image
*
* @defaultValue width: 256px, height: auto, keepAspectRatio: true
*/
thumbnail: ImageTransform;
thumbnail?: ImageTransform;
/**
* The size of the cover image
*
* @defaultValue width: 1100px, height: auto, keepAspectRatio: true
*/
cover?: ImageTransform;
/**
* The source to use for fetching profile metadata details.
*
* If not provided, it will default to the global profile metadata for any profile fetched.
*
* If provided and a profile does not have bespoke profile metadata it will fallback to their global profile metadata.
*
* To know more about app specific profile metadata, see example with `appId` in {@link https://lens-protocol.github.io/metadata/functions/profile.html}.
*
* @defaultValue empty, global profile metadata
*/
cover: ImageTransform;
metadataSource?: AppId;
};
/**
* The fiat currency to use for the fx rate
*
* @defaultValue USD
*/
fxRateFor: SupportedFiatType;
fxRateFor?: SupportedFiatType;
/**
* The App Ids for which to fetch Publication and Profile Stats for.
*
* Affects mainly comments, mirrors, and quotes counts.
*
* @defaultValue empty, all apps
*/
statsFor?: AppId[];
};

function buildImageTransform(
Expand All @@ -47,6 +89,8 @@ function buildImageTransform(
* The default query parameters.
*
* A default configuration that should be good as a starting point.
*
* @internal
*/
export const defaultQueryParams: QueryParams = {
image: {
Expand All @@ -63,43 +107,40 @@ export const defaultQueryParams: QueryParams = {
/**
* @internal
*/
export type LocalOnlyFieldPolicies = {
fxRateFor: FieldReadFunction<SupportedFiatType>;

profileCoverSize: FieldReadFunction<ImageTransform>;

profilePictureSize: FieldReadFunction<ImageTransform>;

imageSmallSize: FieldReadFunction<ImageTransform>;
type WithStatsForVariable = UnknownObject & {
statsFor?: AppId[];
};

imageMediumSize: FieldReadFunction<ImageTransform>;
/**
* @internal
*/
export type LocalOnlyFieldPolicies = {
queryParams: FieldReadFunction<QueryParams>;
};

/**
* @internal
*/
export function createQueryParamsLocalFields(
params: QueryParams = defaultQueryParams,
): LocalOnlyFieldPolicies {
export function createQueryParamsLocalFields({
fxRateFor,
image,
profile,
statsFor,
}: QueryParams = {}): LocalOnlyFieldPolicies {
return {
fxRateFor() {
return params.fxRateFor;
},

profileCoverSize() {
return params.profile.cover;
},

profilePictureSize() {
return params.profile.thumbnail;
},

imageSmallSize() {
return params.image.small;
},

imageMediumSize() {
return params.image.medium;
queryParams(_, { variables }: FieldFunctionOptions<UnknownObject, WithStatsForVariable>) {
return {
image: Object.assign({}, defaultQueryParams.image, image),
profile: Object.assign(
{
metadataSource: null,
},
defaultQueryParams.profile,
profile,
),
statsFor: variables?.statsFor ?? statsFor ?? defaultQueryParams.statsFor,
fxRateFor: fxRateFor ?? defaultQueryParams.fxRateFor,
};
},
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export function createTypePolicies(
Post: createPrimaryPublicationTypePolicy(),
Comment: createPrimaryPublicationTypePolicy(),
Quote: createPrimaryPublicationTypePolicy(),
ProfileMetadata: notNormalizedType(),
PublicationMetadata: notNormalizedType(),
PublicationStats: createPublicationStatsTypePolicy(),
PublicationOperations: createPublicationOperationsTypePolicy(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,20 @@ export function createPublicationFieldPolicy(): FieldPolicy<
FieldFunctionOptions<{ request: PublicationRequest }>
> {
return {
read(_, { args, toReference }) {
read(_, { args, toReference, canRead }) {
if (!args) {
return undefined;
}

if (args.request?.forId) {
return toReference({
const ref = toReference({
__typename: PUBLICATION_TYPENAME,
id: args.request.forId,
});

if (canRead(ref)) {
return ref;
}
}

return undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {

export function createProfileOperationsTypePolicy(): StrictTypedTypePolicies['ProfileOperations'] {
return {
keyFields: false,
fields: {
canFollow: {
read(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ function isCanCollectAlias(args: PublicationOperationsCanActArgs) {

export function createPublicationOperationsTypePolicy(): StrictTypedTypePolicies['PublicationOperations'] {
return {
keyFields: false,
fields: {
canAct: {
read(
Expand Down
2 changes: 1 addition & 1 deletion packages/api-bindings/src/apollo/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export type ApolloClientConfig = {
uri: string;
logger: ILogger;
pollingInterval: number;
queryParams: QueryParams;
queryParams?: QueryParams;
};

export function createLensApolloClient({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ import {
mockEIP712TypedDataField,
} from './utils';

export function mockHidePublicationResponse(args: {
variables: HidePublicationVariables;
}): MockedResponse<HidePublicationData> {
export function mockHidePublicationResponse(
variables: HidePublicationVariables,
): MockedResponse<HidePublicationData> {
return {
request: {
query: HidePublicationDocument,
variables: args.variables,
variables,
},
result: {
data: { hidePublication: null },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { OperationVariables } from '@apollo/client';
import { MockedResponse } from '@apollo/client/testing';
import { DocumentNode } from 'graphql';

import { defaultQueryParams } from '../../../apollo';
import { PaginatedResultInfo, SupportedFiatType } from '../../graphql/generated';
import { mockPaginatedResultInfo } from '../fragments';

Expand All @@ -15,10 +16,11 @@ export function mockAnyResponse(bulk: MockedResponse) {
// any query that needs such variables. The fact one query might use a subset of these
// variables is irrelevant.
fxRateFor: SupportedFiatType.Usd,
imageMediumSize: {},
imageSmallSize: {},
profileCoverSize: {},
profilePictureSize: {},
imageMediumSize: defaultQueryParams.image?.medium ?? {},
imageSmallSize: defaultQueryParams.image?.small ?? {},
profileCoverSize: defaultQueryParams.profile?.cover ?? {},
profilePictureSize: defaultQueryParams.profile?.thumbnail ?? {},
profileMetadataSource: null,
},
},
result: bulk.result,
Expand All @@ -39,20 +41,10 @@ export function mockAnyPaginatedResponse<V extends OperationVariables, I>({
info?: PaginatedResultInfo;
query: DocumentNode;
}) {
return {
return mockAnyResponse({
request: {
query,
variables: {
...variables,
// The values below should match the superset of the variables default values used in
// any query that needs such variables. The fact one query might use a subset of these
// variables is irrelevant.
fxRateFor: SupportedFiatType.Usd,
imageMediumSize: {},
imageSmallSize: {},
profileCoverSize: {},
profilePictureSize: {},
},
variables,
},
result: {
data: {
Expand All @@ -62,5 +54,5 @@ export function mockAnyPaginatedResponse<V extends OperationVariables, I>({
},
},
},
};
});
}
56 changes: 50 additions & 6 deletions packages/api-bindings/src/lens/graphql/client.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,60 @@ extend type PaginatedResultInfo {
moreAfter: Boolean!
}

type ImageTransformParam {
type ImageTransformParams {
height: ImageSizeTransform
width: ImageSizeTransform
keepAspectRatio: Boolean
}

extend type Query {
type ImageQueryParams {
small: ImageTransformParams
medium: ImageTransformParams
}

type ProfileQueryParams {
cover: ImageTransformParams
thumbnail: ImageTransformParams
metadataSource: AppId
}

type QueryParams {
image: ImageQueryParams
profile: ProfileQueryParams
fxRateFor: SupportedFiatType
profileCoverSize: ImageTransformParam
profilePictureSize: ImageTransformParam
imageSmallSize: ImageTransformParam
imageMediumSize: ImageTransformParam
}

extend type Query {
queryParams: QueryParams!
}

fragment InjectQueryParams on Query {
queryParams @client {
image {
small @export(as: "imageSmallSize") {
height
width
keepAspectRatio
}
medium @export(as: "imageMediumSize") {
height
width
keepAspectRatio
}
}
profile {
cover @export(as: "profileCoverSize") {
height
width
keepAspectRatio
}
thumbnail @export(as: "profilePictureSize") {
height
width
keepAspectRatio
}
metadataSource @export(as: "profileMetadataSource")
}
fxRateFor @export(as: "fxRateFor")
}
}
Loading
Loading