diff --git a/__tests__/components/common/profile/ProfileNameWithAiMarker.test.tsx b/__tests__/components/common/profile/ProfileNameWithAiMarker.test.tsx new file mode 100644 index 0000000000..32012a1873 --- /dev/null +++ b/__tests__/components/common/profile/ProfileNameWithAiMarker.test.tsx @@ -0,0 +1,38 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; +import ProfileNameWithAiMarker from "@/components/common/profile/ProfileNameWithAiMarker"; +import { ApiProfileClassification } from "@/generated/models/ApiProfileClassification"; + +describe("ProfileNameWithAiMarker", () => { + it("includes an accessible AI label while keeping the emoji decorative", () => { + render( + + + ai-bot + + + ); + + expect( + screen.getByRole("link", { name: /ai profile ai-bot/i }) + ).toBeInTheDocument(); + expect(screen.getByText("AI profile")).toHaveClass("tw-sr-only"); + expect(screen.getByText("🤖")).toHaveAttribute("aria-hidden", "true"); + }); + + it("does not add an AI label for non-AI profiles", () => { + render( + + + human + + + ); + + expect(screen.getByRole("link", { name: "human" })).toBeInTheDocument(); + expect(screen.queryByText("AI profile")).not.toBeInTheDocument(); + expect(screen.queryByText("🤖")).not.toBeInTheDocument(); + }); +}); diff --git a/__tests__/components/user/user-page-header/name/UserPageHeaderName.test.tsx b/__tests__/components/user/user-page-header/name/UserPageHeaderName.test.tsx index 09444c5d76..9c1fd08797 100644 --- a/__tests__/components/user/user-page-header/name/UserPageHeaderName.test.tsx +++ b/__tests__/components/user/user-page-header/name/UserPageHeaderName.test.tsx @@ -1,26 +1,39 @@ -import { render, screen } from '@testing-library/react'; -import type { ApiIdentity } from '@/generated/models/ApiIdentity'; -import { ApiProfileClassification } from '@/generated/models/ApiProfileClassification'; -import { CLASSIFICATIONS } from '@/entities/IProfile'; -import UserPageHeaderName from '@/components/user/user-page-header/name/UserPageHeaderName'; +import { render, screen } from "@testing-library/react"; +import type { ApiIdentity } from "@/generated/models/ApiIdentity"; +import { ApiProfileClassification } from "@/generated/models/ApiProfileClassification"; +import { CLASSIFICATIONS } from "@/entities/IProfile"; +import UserPageHeaderName from "@/components/user/user-page-header/name/UserPageHeaderName"; -jest.mock('@/components/user/user-page-header/name/UserPageHeaderNameWrapper', () => ({ - __esModule: true, - default: (props: any) =>
{props.children}
, -})); +jest.mock( + "@/components/user/user-page-header/name/UserPageHeaderNameWrapper", + () => ({ + __esModule: true, + default: (props: any) => ( +
{props.children}
+ ), + }) +); -jest.mock('@/components/user/user-page-header/name/classification/UserPageClassificationWrapper', () => ({ - __esModule: true, - default: (props: any) =>
{props.children}
, -})); +jest.mock( + "@/components/user/user-page-header/name/classification/UserPageClassificationWrapper", + () => ({ + __esModule: true, + default: (props: any) => ( +
{props.children}
+ ), + }) +); -jest.mock('@/components/user/utils/user-cic-type/UserCICTypeIconWrapper', () => ({ - __esModule: true, - default: () =>
, -})); +jest.mock( + "@/components/user/utils/user-cic-type/UserCICTypeIconWrapper", + () => ({ + __esModule: true, + default: () =>
, + }) +); const baseProfile: ApiIdentity = { - id: '1', + id: "1", handle: null, normalised_handle: null, pfp: null, @@ -28,16 +41,16 @@ const baseProfile: ApiIdentity = { rep: 0, level: 0, tdh: 0, - consolidation_key: '', - display: '', - primary_wallet: '', + consolidation_key: "", + display: "", + primary_wallet: "", banner1: null, banner2: null, classification: ApiProfileClassification.Pseudonym, sub_classification: null, }; -function renderComponent(profile: Partial, mainAddress = '0xabc') { +function renderComponent(profile: Partial, mainAddress = "0xabc") { const combined = { ...baseProfile, ...profile } as ApiIdentity; return render( , mainAddress = '0xabc') { ); } -describe('UserPageHeaderName', () => { - it('shows handle and classification when handle exists', () => { - renderComponent({ handle: 'Alice', classification: ApiProfileClassification.Bot }); - expect(screen.getByText('Alice')).toBeInTheDocument(); +describe("UserPageHeaderName", () => { + it("shows handle and classification when handle exists", () => { + renderComponent({ + handle: "Alice", + classification: ApiProfileClassification.Bot, + }); + expect(screen.getByText("Alice")).toBeInTheDocument(); expect( screen.getByText(CLASSIFICATIONS[ApiProfileClassification.Bot].title) ).toBeInTheDocument(); }); - it('shows display when handle missing', () => { - renderComponent({ handle: null, display: 'Display Name' }); - expect(screen.getByText('Display Name')).toBeInTheDocument(); + it("shows display when handle missing", () => { + renderComponent({ handle: null, display: "Display Name" }); + expect(screen.getByText("Display Name")).toBeInTheDocument(); }); - it('falls back to main address when no other name', () => { - renderComponent({ handle: null, display: '' }, '0x123'); - expect(screen.getByText('0x123')).toBeInTheDocument(); + it("falls back to main address when no other name", () => { + renderComponent({ handle: null, display: "" }, "0x123"); + expect(screen.getByText("0x123")).toBeInTheDocument(); + }); + + it("shows a robot emoji for AI classification", () => { + renderComponent({ + handle: "Robo", + classification: ApiProfileClassification.Ai, + }); + + expect(screen.getByText("🤖")).toBeInTheDocument(); + expect(screen.getByText("AI profile")).toHaveClass("tw-sr-only"); + expect(screen.getByTestId("name-wrapper")).toHaveTextContent("Robo"); + }); + + it("does not show a robot emoji for non-AI classifications", () => { + renderComponent({ + handle: "Alice", + classification: ApiProfileClassification.Organization, + }); + + expect(screen.queryByText("🤖")).not.toBeInTheDocument(); }); }); diff --git a/__tests__/components/waves/drop/SingleWaveDropAuthor.test.tsx b/__tests__/components/waves/drop/SingleWaveDropAuthor.test.tsx index a179875b92..07f6c555dc 100644 --- a/__tests__/components/waves/drop/SingleWaveDropAuthor.test.tsx +++ b/__tests__/components/waves/drop/SingleWaveDropAuthor.test.tsx @@ -1,6 +1,7 @@ import React from "react"; import { render, screen } from "@testing-library/react"; import { SingleWaveDropAuthor } from "@/components/waves/drop/SingleWaveDropAuthor"; +import { ApiProfileClassification } from "@/generated/models/ApiProfileClassification"; jest.mock("next/link", () => ({ __esModule: true, @@ -33,7 +34,11 @@ jest.mock("@/components/utils/tooltip/UserProfileTooltipWrapper", () => ({ })); describe("SingleWaveDropAuthor", () => { - const createDrop = (handle: string | null, primaryAddress: string) => + const createDrop = ( + handle: string | null, + primaryAddress: string, + classification: ApiProfileClassification = ApiProfileClassification.Pseudonym + ) => ({ id: "drop-1", author: { @@ -41,6 +46,7 @@ describe("SingleWaveDropAuthor", () => { primary_address: primaryAddress, pfp: null, level: 3, + classification, }, }) as any; @@ -69,4 +75,17 @@ describe("SingleWaveDropAuthor", () => { "0x1111111111111111111111111111111111111111" ); }); + + it("renders a robot emoji before the name for AI profiles", () => { + render( + + ); + + expect(screen.getByText("🤖")).toBeInTheDocument(); + expect( + screen.getByRole("link", { name: /ai profile ai-bot/i }) + ).toBeInTheDocument(); + }); }); diff --git a/__tests__/components/waves/drops/DropMinimalIdentityRow.test.tsx b/__tests__/components/waves/drops/DropMinimalIdentityRow.test.tsx new file mode 100644 index 0000000000..ae90a5de39 --- /dev/null +++ b/__tests__/components/waves/drops/DropMinimalIdentityRow.test.tsx @@ -0,0 +1,110 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; +import { ApiProfileClassification } from "@/generated/models/ApiProfileClassification"; +import DropMinimalIdentityRow from "@/components/waves/drops/DropMinimalIdentityRow"; + +jest.mock("next/link", () => ({ + __esModule: true, + default: ({ href, children, ...props }: any) => ( + + {children} + + ), +})); + +jest.mock("next/navigation", () => ({ + useRouter: () => ({ + push: jest.fn(), + }), +})); + +jest.mock("@/components/utils/tooltip/UserProfileTooltipWrapper", () => ({ + __esModule: true, + default: ({ user, children }: any) => ( +
+ {children} +
+ ), +})); + +jest.mock("@/components/waves/drops/time/WaveDropTime", () => ({ + __esModule: true, + default: () =>
, +})); + +describe("DropMinimalIdentityRow", () => { + const createDrop = ( + handle: string | null, + primaryAddress: string, + classification: ApiProfileClassification + ) => + ({ + id: "drop-1", + created_at: 1710000000000, + author: { + id: "profile-1", + handle, + primary_address: primaryAddress, + classification, + }, + }) as any; + + it("renders a robot emoji before the author name for AI profiles", () => { + render( + + ); + + expect(screen.getByText("🤖")).toBeInTheDocument(); + expect( + screen.getByRole("link", { name: /ai profile ai-bot/i }) + ).toBeInTheDocument(); + }); + + it("does not render a robot emoji for non-AI profiles", () => { + render( + + ); + + expect(screen.getByRole("link", { name: "human" })).toBeInTheDocument(); + expect(screen.getByTestId("tooltip-wrapper")).not.toHaveTextContent("🤖"); + }); + + it("uses the handle for the tooltip lookup when present", () => { + render( + + ); + + expect(screen.getByTestId("tooltip-wrapper")).toHaveAttribute( + "data-user", + "alice" + ); + }); + + it("uses the primary address for the tooltip lookup when the handle is missing", () => { + render( + + ); + + expect( + screen.getByRole("link", { + name: "0x1111111111111111111111111111111111111111", + }) + ).toBeInTheDocument(); + expect(screen.getByTestId("tooltip-wrapper")).toHaveAttribute( + "data-user", + "0x1111111111111111111111111111111111111111" + ); + }); +}); diff --git a/__tests__/components/waves/drops/WaveDropHeader.test.tsx b/__tests__/components/waves/drops/WaveDropHeader.test.tsx new file mode 100644 index 0000000000..d88ce98352 --- /dev/null +++ b/__tests__/components/waves/drops/WaveDropHeader.test.tsx @@ -0,0 +1,152 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; +import { ApiProfileClassification } from "@/generated/models/ApiProfileClassification"; +import WaveDropHeader from "@/components/waves/drops/WaveDropHeader"; + +jest.mock("next/link", () => ({ + __esModule: true, + default: ({ href, children, ...props }: any) => ( + + {children} + + ), +})); + +jest.mock("next/navigation", () => ({ + useRouter: () => ({ + push: jest.fn(), + }), +})); + +jest.mock("@/components/user/utils/UserCICAndLevel", () => ({ + __esModule: true, + default: () =>
, + UserCICAndLevelSize: { + SMALL: "small", + }, +})); + +jest.mock("@/components/utils/tooltip/UserProfileTooltipWrapper", () => ({ + __esModule: true, + default: ({ user, children }: any) => ( +
+ {children} +
+ ), +})); + +jest.mock("@/components/waves/drops/DropAuthorBadges", () => ({ + DropAuthorBadges: () =>
, +})); + +jest.mock("@/components/waves/drops/time/WaveDropTime", () => ({ + __esModule: true, + default: () =>
, +})); + +jest.mock("@heroicons/react/24/outline", () => ({ + EllipsisVerticalIcon: () =>
, +})); + +jest.mock("@/contexts/CompactModeContext", () => ({ + useCompactMode: () => false, +})); + +describe("WaveDropHeader", () => { + const createDrop = ( + handle: string | null, + primaryAddress: string, + classification: ApiProfileClassification + ) => + ({ + id: "drop-1", + created_at: 1710000000000, + author: { + id: "profile-1", + handle, + primary_address: primaryAddress, + level: 3, + classification, + }, + wave: { + id: "wave-1", + name: "Wave Name", + }, + parts: [], + }) as any; + + it("renders a robot emoji before the author name for AI profiles", () => { + render( + + ); + + expect(screen.getByText("🤖")).toBeInTheDocument(); + expect( + screen.getByRole("link", { name: /ai profile ai-bot/i }) + ).toBeInTheDocument(); + }); + + it("does not render a robot emoji for non-AI profiles", () => { + render( + + ); + + expect(screen.getByRole("link", { name: "human" })).toBeInTheDocument(); + expect(screen.getByTestId("tooltip-wrapper")).not.toHaveTextContent("🤖"); + }); + + it("uses the handle for the tooltip lookup when present", () => { + render( + + ); + + expect(screen.getByTestId("tooltip-wrapper")).toHaveAttribute( + "data-user", + "alice" + ); + }); + + it("uses the primary address for the tooltip lookup when the handle is missing", () => { + render( + + ); + + expect( + screen.getByRole("link", { + name: "0x1111111111111111111111111111111111111111", + }) + ).toBeInTheDocument(); + expect(screen.getByTestId("tooltip-wrapper")).toHaveAttribute( + "data-user", + "0x1111111111111111111111111111111111111111" + ); + }); +}); diff --git a/components/common/profile/ProfileNameWithAiMarker.tsx b/components/common/profile/ProfileNameWithAiMarker.tsx new file mode 100644 index 0000000000..184db4942e --- /dev/null +++ b/components/common/profile/ProfileNameWithAiMarker.tsx @@ -0,0 +1,43 @@ +import type { ReactNode } from "react"; +import { ApiProfileClassification } from "@/generated/models/ApiProfileClassification"; + +interface ProfileNameWithAiMarkerProps { + readonly classification: ApiProfileClassification; + readonly children: ReactNode; + readonly className?: string | undefined; + readonly markerClassName?: string | undefined; +} + +const DEFAULT_CLASS_NAME = "tw-inline-flex tw-items-center tw-gap-2"; +const MARKER_CLASS_NAME = + "tw-inline-flex tw-items-center tw-justify-center tw-leading-none"; + +export default function ProfileNameWithAiMarker({ + classification, + children, + className = DEFAULT_CLASS_NAME, + markerClassName, +}: ProfileNameWithAiMarkerProps) { + const isAiProfile = classification === ApiProfileClassification.Ai; + + return ( + + {isAiProfile && ( + <> + AI profile + + + )} + {children} + + ); +} diff --git a/components/manifold-minting/ManifoldMinting.tsx b/components/manifold-minting/ManifoldMinting.tsx index acb011c611..7331aa6900 100644 --- a/components/manifold-minting/ManifoldMinting.tsx +++ b/components/manifold-minting/ManifoldMinting.tsx @@ -318,6 +318,8 @@ function ArtistInfoStrip({ winner_main_stage_drop_ids: profile.winner_main_stage_drop_ids, artist_of_prevote_cards: profile.artist_of_prevote_cards, is_wave_creator: profile.is_wave_creator, + classification: profile.classification, + sub_classification: profile.sub_classification, }; }, [profile]); diff --git a/components/user/user-page-header/name/UserPageHeaderName.tsx b/components/user/user-page-header/name/UserPageHeaderName.tsx index 5d43fcec67..34ae8ca7bf 100644 --- a/components/user/user-page-header/name/UserPageHeaderName.tsx +++ b/components/user/user-page-header/name/UserPageHeaderName.tsx @@ -1,6 +1,7 @@ import { CLASSIFICATIONS } from "@/entities/IProfile"; import type { ApiIdentity } from "@/generated/models/ApiIdentity"; import { formatTimestampToMonthYear } from "@/helpers/Helpers"; +import ProfileNameWithAiMarker from "@/components/common/profile/ProfileNameWithAiMarker"; import UserCICTypeIconWrapper from "@/components/user/utils/user-cic-type/UserCICTypeIconWrapper"; import UserCICAndLevel, { UserCICAndLevelSize, @@ -53,9 +54,14 @@ export default function UserPageHeaderName({ {showTitle && (
-

- {displayName} -

+ + + {displayName} + +
{profile.handle && (
diff --git a/components/waves/drop/SingleWaveDropAuthor.tsx b/components/waves/drop/SingleWaveDropAuthor.tsx index 0280065648..d775de528b 100644 --- a/components/waves/drop/SingleWaveDropAuthor.tsx +++ b/components/waves/drop/SingleWaveDropAuthor.tsx @@ -1,6 +1,7 @@ "use client"; import React from "react"; +import ProfileNameWithAiMarker from "@/components/common/profile/ProfileNameWithAiMarker"; import type { ApiDrop } from "@/generated/models/ObjectSerializer"; import { resolveIpfsUrlSync } from "@/components/ipfs/IPFSContext"; import Link from "next/link"; @@ -49,7 +50,11 @@ export const SingleWaveDropAuthor: React.FC = ({
- {authorIdentity} + + {authorIdentity} + { : [], profile_wave_id: profile.profile_wave_id ?? null, is_wave_creator: profile.is_wave_creator === true, + classification: profile.classification, + sub_classification: profile.sub_classification, }; }; diff --git a/components/waves/drops/DropMinimalIdentityRow.tsx b/components/waves/drops/DropMinimalIdentityRow.tsx index 6c6316a420..a1da273d6e 100644 --- a/components/waves/drops/DropMinimalIdentityRow.tsx +++ b/components/waves/drops/DropMinimalIdentityRow.tsx @@ -1,5 +1,6 @@ "use client"; +import ProfileNameWithAiMarker from "@/components/common/profile/ProfileNameWithAiMarker"; import UserProfileTooltipWrapper from "@/components/utils/tooltip/UserProfileTooltipWrapper"; import type { ApiDrop } from "@/generated/models/ApiDrop"; import Link from "next/link"; @@ -15,6 +16,7 @@ export default function DropMinimalIdentityRow({ drop, }: DropMinimalIdentityRowProps) { const router = useRouter(); + const authorIdentity = drop.author.handle ?? drop.author.primary_address; const handleNavigation = useCallback( (event: React.MouseEvent, path: string) => { @@ -28,18 +30,17 @@ export default function DropMinimalIdentityRow({ return (

- + - handleNavigation( - event, - `/${drop.author.handle ?? drop.author.primary_address}` - ) - } + href={`/${authorIdentity}`} + onClick={(event) => handleNavigation(event, `/${authorIdentity}`)} className="tw-text-iron-200 tw-no-underline tw-transition tw-duration-300 tw-ease-out desktop-hover:hover:tw-text-opacity-80 desktop-hover:hover:tw-underline" > - {drop.author.handle ?? drop.author.primary_address} + + {authorIdentity} +

diff --git a/components/waves/drops/WaveDropHeader.tsx b/components/waves/drops/WaveDropHeader.tsx index 56ff9d1cec..9fdfe1ae60 100644 --- a/components/waves/drops/WaveDropHeader.tsx +++ b/components/waves/drops/WaveDropHeader.tsx @@ -1,5 +1,6 @@ "use client"; +import ProfileNameWithAiMarker from "@/components/common/profile/ProfileNameWithAiMarker"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { getWaveRoute } from "@/helpers/navigation.helpers"; @@ -39,6 +40,7 @@ const WaveDropHeader: React.FC = ({ }) => { const router = useRouter(); const compact = useCompactMode(); + const authorIdentity = drop.author.handle ?? drop.author.primary_address; // Memoize event handlers to prevent unnecessary re-renders const handleNavigation = useCallback( @@ -58,20 +60,17 @@ const WaveDropHeader: React.FC = ({

- + - handleNavigation( - e, - `/${drop.author.handle ?? drop.author.primary_address}` - ) - } - href={`/${drop.author.handle ?? drop.author.primary_address}`} + onClick={(e) => handleNavigation(e, `/${authorIdentity}`)} + href={`/${authorIdentity}`} className="tw-text-iron-200 tw-no-underline tw-transition tw-duration-300 tw-ease-out desktop-hover:hover:tw-text-opacity-80 desktop-hover:hover:tw-underline" > - {drop.author.handle} + + {authorIdentity} +

diff --git a/components/waves/drops/reaction-utils.ts b/components/waves/drops/reaction-utils.ts index bfb9028fcf..4610f0a2f1 100644 --- a/components/waves/drops/reaction-utils.ts +++ b/components/waves/drops/reaction-utils.ts @@ -105,5 +105,7 @@ export const toProfileMin = ( is_wave_creator: profile.is_wave_creator, artist_of_prevote_cards: profile.artist_of_prevote_cards, profile_wave_id: profile.profile_wave_id, + classification: profile.classification, + sub_classification: profile.sub_classification, }; }; diff --git a/components/waves/memes/submission/utils/buildPreviewDrop.ts b/components/waves/memes/submission/utils/buildPreviewDrop.ts index 092f30c563..42674c0230 100644 --- a/components/waves/memes/submission/utils/buildPreviewDrop.ts +++ b/components/waves/memes/submission/utils/buildPreviewDrop.ts @@ -9,6 +9,7 @@ import type { ExtendedDrop } from "@/helpers/waves/drop.helpers"; import type { OperationalData } from "../types/OperationalData"; import type { TraitsData } from "../types/TraitsData"; import { buildSubmissionMetadata } from "./submissionMetadata"; +import { ApiProfileClassification } from "@/generated/models/ApiProfileClassification"; interface PreviewMediaSelection { readonly mediaSource: "upload" | "url"; @@ -156,6 +157,9 @@ export const buildPreviewDrop = ({ connectedProfile?.winner_main_stage_drop_ids ?? [], is_wave_creator: connectedProfile?.is_wave_creator ?? false, artist_of_prevote_cards: connectedProfile?.artist_of_prevote_cards ?? [], + classification: + connectedProfile?.classification ?? ApiProfileClassification.Pseudonym, + sub_classification: connectedProfile?.sub_classification ?? null, }, created_at: now, updated_at: null, diff --git a/components/waves/specs/groups/group/edit/WaveGroupChangeDialog.tsx b/components/waves/specs/groups/group/edit/WaveGroupChangeDialog.tsx index 986f687171..80564ca7bf 100644 --- a/components/waves/specs/groups/group/edit/WaveGroupChangeDialog.tsx +++ b/components/waves/specs/groups/group/edit/WaveGroupChangeDialog.tsx @@ -21,6 +21,7 @@ import type { ApiProfileMin } from "@/generated/models/ApiProfileMin"; import type { ApiWave } from "@/generated/models/ApiWave"; import { CreateWaveGroupConfigType } from "@/types/waves.types"; import { WaveGroupType } from "../WaveGroup.types"; +import { ApiProfileClassification } from "@/generated/models/ApiProfileClassification"; const WAVE_GROUP_TO_CREATE_GROUP_TYPE = { [WaveGroupType.VIEW]: CreateWaveGroupConfigType.CAN_VIEW, @@ -80,6 +81,8 @@ const createUnknownGroupAuthor = (): ApiProfileMin => ({ artist_of_prevote_cards: [], profile_wave_id: null, is_wave_creator: false, + classification: ApiProfileClassification.Pseudonym, + sub_classification: null, }); const getSelectedGroup = (group: ApiGroup | null): ApiGroupFull | null => { diff --git a/components/waves/utils/getOptimisticDrop.ts b/components/waves/utils/getOptimisticDrop.ts index 49ac96fc59..3c4fbffd4a 100644 --- a/components/waves/utils/getOptimisticDrop.ts +++ b/components/waves/utils/getOptimisticDrop.ts @@ -90,6 +90,8 @@ export const getOptimisticDrop = ( profile_wave_id: connectedProfile.profile_wave_id, is_wave_creator: connectedProfile.is_wave_creator, artist_of_prevote_cards: connectedProfile.artist_of_prevote_cards, + classification: connectedProfile.classification, + sub_classification: connectedProfile.sub_classification, }, created_at: Date.now(), updated_at: null, diff --git a/generated/models/ApiDropResolvedIdentityProfile.ts b/generated/models/ApiDropResolvedIdentityProfile.ts index c4828979a5..c553cc6665 100644 --- a/generated/models/ApiDropResolvedIdentityProfile.ts +++ b/generated/models/ApiDropResolvedIdentityProfile.ts @@ -12,6 +12,7 @@ */ import { ApiIdentitySubscriptionTargetAction } from '../models/ApiIdentitySubscriptionTargetAction'; +import { ApiProfileClassification } from '../models/ApiProfileClassification'; import { ApiProfileRepCategorySummary } from '../models/ApiProfileRepCategorySummary'; import { HttpFile } from '../http/http'; @@ -28,6 +29,8 @@ export class ApiDropResolvedIdentityProfile { 'xtdh': number; 'xtdh_rate': number; 'level': number; + 'classification': ApiProfileClassification; + 'sub_classification': string | null; 'primary_address': string; 'subscribed_actions': Array; 'archived': boolean; @@ -116,6 +119,18 @@ export class ApiDropResolvedIdentityProfile { "type": "number", "format": "int64" }, + { + "name": "classification", + "baseName": "classification", + "type": "ApiProfileClassification", + "format": "" + }, + { + "name": "sub_classification", + "baseName": "sub_classification", + "type": "string", + "format": "" + }, { "name": "primary_address", "baseName": "primary_address", @@ -184,3 +199,5 @@ export class ApiDropResolvedIdentityProfile { public constructor() { } } + + diff --git a/generated/models/ApiProfileMin.ts b/generated/models/ApiProfileMin.ts index 66197ecb26..8e88c58dab 100644 --- a/generated/models/ApiProfileMin.ts +++ b/generated/models/ApiProfileMin.ts @@ -12,6 +12,7 @@ */ import { ApiIdentitySubscriptionTargetAction } from '../models/ApiIdentitySubscriptionTargetAction'; +import { ApiProfileClassification } from '../models/ApiProfileClassification'; import { HttpFile } from '../http/http'; export class ApiProfileMin { @@ -27,6 +28,8 @@ export class ApiProfileMin { 'xtdh': number; 'xtdh_rate': number; 'level': number; + 'classification': ApiProfileClassification; + 'sub_classification': string | null; 'primary_address': string; 'subscribed_actions': Array; 'archived': boolean; @@ -113,6 +116,18 @@ export class ApiProfileMin { "type": "number", "format": "int64" }, + { + "name": "classification", + "baseName": "classification", + "type": "ApiProfileClassification", + "format": "" + }, + { + "name": "sub_classification", + "baseName": "sub_classification", + "type": "string", + "format": "" + }, { "name": "primary_address", "baseName": "primary_address", @@ -169,3 +184,5 @@ export class ApiProfileMin { public constructor() { } } + + diff --git a/generated/models/ObjectSerializer.ts b/generated/models/ObjectSerializer.ts index 22aedf5745..c35e4520ff 100644 --- a/generated/models/ObjectSerializer.ts +++ b/generated/models/ObjectSerializer.ts @@ -403,7 +403,7 @@ import { ApiDropRater } from '../models/ApiDropRater'; import { ApiDropRatingRequest } from '../models/ApiDropRatingRequest'; import { ApiDropReaction } from '../models/ApiDropReaction'; import { ApiDropReferencedNFT } from '../models/ApiDropReferencedNFT'; -import { ApiDropResolvedIdentityProfile } from '../models/ApiDropResolvedIdentityProfile'; +import { ApiDropResolvedIdentityProfile } from '../models/ApiDropResolvedIdentityProfile'; import { ApiDropSearchStrategy } from '../models/ApiDropSearchStrategy'; import { ApiDropSubscriptionActions } from '../models/ApiDropSubscriptionActions'; import { ApiDropSubscriptionTargetAction } from '../models/ApiDropSubscriptionTargetAction'; @@ -473,7 +473,7 @@ import { ApiPageWithNextUriBase } from '../models/ApiPageWithNextUriBase'; import { ApiPageWithoutCount } from '../models/ApiPageWithoutCount'; import { ApiPaymentDetails } from '../models/ApiPaymentDetails'; import { ApiProfileClassification } from '../models/ApiProfileClassification'; -import { ApiProfileMin } from '../models/ApiProfileMin'; +import { ApiProfileMin } from '../models/ApiProfileMin'; import { ApiProfileMinsPage } from '../models/ApiProfileMinsPage'; import { ApiProfileProxy } from '../models/ApiProfileProxy'; import { ApiProfileProxyAction } from '../models/ApiProfileProxyAction'; diff --git a/helpers/ProfileHelpers.ts b/helpers/ProfileHelpers.ts index 9281accd0f..53236ff188 100644 --- a/helpers/ProfileHelpers.ts +++ b/helpers/ProfileHelpers.ts @@ -153,6 +153,8 @@ export const profileAndConsolidationsToProfileMin = ({ is_wave_creator: profile.is_wave_creator, artist_of_prevote_cards: profile.artist_of_prevote_cards, profile_wave_id: profile.profile_wave_id, + classification: profile.classification, + sub_classification: profile.sub_classification, }; })() : null; diff --git a/openapi.yaml b/openapi.yaml index 467a4f0402..fcf0a0fdb9 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -10533,6 +10533,8 @@ components: - xtdh_rate - level - tdh_rate + - classification + - sub_classification - primary_address - banner1_color - banner2_color @@ -10580,6 +10582,11 @@ components: level: type: number format: int64 + classification: + $ref: "#/components/schemas/ApiProfileClassification" + sub_classification: + type: string + nullable: true primary_address: type: string subscribed_actions: