diff --git a/docs/docs/developers/api/get-ai-attributed-tracks-by-user-handle.api.mdx b/docs/docs/developers/api/get-ai-attributed-tracks-by-user-handle.api.mdx deleted file mode 100644 index 4d9487a45c7..00000000000 --- a/docs/docs/developers/api/get-ai-attributed-tracks-by-user-handle.api.mdx +++ /dev/null @@ -1,889 +0,0 @@ ---- -id: get-ai-attributed-tracks-by-user-handle -title: 'Get AI Attributed Tracks by User Handle' -description: "Gets the AI generated tracks attributed to a user using the user's handle" -sidebar_label: 'Get AI Tracks by Handle' -hide_title: true -hide_table_of_contents: true -api: eJzFGdtu2zb0Vwi9tB3c2CnaYfBbhrRdHgYMa7uXIBBoibJZU6JKUnYMw//ec0hdbeqSpMAemkTk4bnfewwMXetgeR8UmikdPMyCmOlI8dxwmQXL4DMzmpgNIzd3ZM0ypqhhMTGKRltNqDGKrwp7IgkliAN+8Gxtn+DnK002NIsFC2aBzPE54L2LHWZEetPg+Oqwrg7kGyL6q3qXU0VTZpC/5f0xyOAD3tdoOfKZU7MJzpm/cYhqSMV+FFwxoG5UwWaBjjYspcHyGJhDjjg18JKtg9NpVpORSaKZqcj8KJg6XND5CsJmRboCWjIh3LBUo0L0ludXyEJSCJJIRXK65pnVAHkNf9ePfiOCp9y8CTws8cywNVMdniz0s1hKmIk2U8mg/UIejxOydr+7RUqV3UlKt5UfoNqZNj6yHoVrqUZku79luWIReuID+cSZsO6H78B3BqggnoQWwsBRDK/hgIGO0PvLz1zQAwRBm52KhREVJFyAg5IKYKqgIfj1Rk5QsZWuBu6XsBLIcGNdnirDtQktSQwAwahmYSmuoHAl4J5l1RGNYxaHHXXgs1xqg39pumP4O5X1Sx2uDiGavKs3K10M0RZZKaYJ2IYfl5HqqETVJe1sEbokNUz5kzMbpJwis+LEBOO0WAkekRrBFIeiQrRZs18OD/xRIe/y+TGLJGj77S019O3fTGtICRW7G0ZjUKlPU2AcCnFFDdlTTTRfZ8A1SFCHHqYaPKamUBh9kdxN98oOU18qLBPYaihCGkAeZ8hN/BxuHtDldC4zDc4G9+8WC/zVpfmliCLQGSCKJCSvzCAIzXPQuE2x8+8a4Y6XdOTqO3gZ2kdhSTLcUUGeW1BUKWoDH3MnnjfV4x7Dai/V1hJPUyAeRrLIEGdcuBoHfyZ0JxU8r++ggDpV2oDXYSz3mZA0pitXyHQI8FgiREh3lIvyHHhMqeDZtgzJGp+Ly/qzinkXjLMRcSsRRvVy/WHxCP88hpoF7/9YPMI/7931YgEPFwvf7anidhnYKAsrbk5nruXB67TouwG9+o4dhajnFkrJjrN97z2aJISUwsYhXAj5GPNatoFcSQmJOUPQVEo/lU7u9gOk/DGUybhFy8Q20deh/UIHd1oEFYx61vmDCeYH2TCK4KZ15QRy2JyALXf3tC4XEeeF6QasF8T1xD5Pcpx5bmzMnScJsSrSOjqZisI91AXbTCZSCLlnTWooD1R90LS3ZbJoZwTMHYxCpdxhE+QOIKvyhNuvstpjrsC605cvdC4ajnSR51CCWxyUJyBgk2GkQQ8uYi7DFRU0i5BOGV8lTMVHuOdmE/JMgzahf7+4MXxr5PbyGH4aW2JK1sYTWUvNXnOWPVDOgcsBp5wFKy6957ZkhflGGjkeXL+/Xzx6sbzDfDgcDG1Cpwsv8bt813G8MKUvPSFltv3Jm6ZKM4VDqCvTDwE5LxiC8LuHl6k+15sAXHqjF3LPVpr3JN1YuoHOeylk1H/ZWyzOwtZrUXA5W5LAp2179n8X8XN+JmXrdt7wApylOa9xOpnRC9FKvD4JW1mw77rQcQR16CALMwh6lkK9Ml1kVb9qPInWC9jHTt+Y/kqTjzAoKFakxL0lMPJBt61tow5XXBEaOdbaFrYF7tTqb3st1m5qvQZp9bB+56773Z7UBB+Mpv0EYIZ9DGEUGAwvHeLcQHmGprCuONQQXa5JgpxnMHmFVT/RyaRtuEqDdr3V7XBcIxZWww5eYjz6xp0/adxapDQjDz744J2PmIIUR5hSUp29wDbTrRKW0E3bZIHrs2Uwt1vAucvG86P7fZo7NueUh83GDxsES8Et5QolcDw0JtfL+Tzm2o15kBd2HCbGK3TlQl9Fcr67DnDA41niimmpipt/7i73d/YR+e+auFuk5m6urxbWlpBhUmp9sRxfp28Vz8aMWj+/dOVZuoNhj2YOjsete1pdHUudV5vXVse3bJ5XG4iu6kF9G5AcHx+PKxgKvilxOuGx23KgQcAEGCBg4oQKzQbk/YXbS6+4W3YIWnvUHRUFAgW4dHgxl9VCc4BytS19AeHJC84BNppt6jMZGVt7DtAud6ov0MDZfnOAVgXyAmLdZeeIXM0K9aUU29vHMaJt2GfSnbZ7HGDkfM/Z8PGAH4q7CvmkZPD633KAfUPO//fEy0lVL7OOySsOy7enBxxC3Orw6bnp+fvOAd317F5f4kJP3X9O5a69hO3w52Bvoojl7ei+2IGiO9T1/vPHr9Bm/ATrQbW2 -sidebar_class_name: 'get api-method' -info_path: developers/api/api -custom_edit_url: null ---- - -import ApiTabs from '@theme/ApiTabs' -import DiscriminatorTabs from '@theme/DiscriminatorTabs' -import MethodEndpoint from '@theme/ApiExplorer/MethodEndpoint' -import SecuritySchemes from '@theme/ApiExplorer/SecuritySchemes' -import MimeTabs from '@theme/MimeTabs' -import ParamsItem from '@theme/ParamsItem' -import ResponseSamples from '@theme/ResponseSamples' -import SchemaItem from '@theme/SchemaItem' -import SchemaTabs from '@theme/SchemaTabs' -import Heading from '@theme/Heading' -import OperationTabs from '@theme/OperationTabs' -import TabItem from '@theme/TabItem' - - - - - -Gets the AI generated tracks attributed to a user using the user's handle - - - -
- -

Path Parameters

-
-
- -
-
-
- -

Query Parameters

-
-
- -
-
-
- -

Header Parameters

-
-
- -
-
-
-
- - -
Success
-
- - - - -
- - Schema - -
-
    - -
    - - - data - object[] - - -
    -
  • -
    - Array [ -
    -
  • - -
    - - - artwork - object - - required - - -
    - - - -
    -
    -
    - - - - - - - - - - - -
    - - - remix_of - object - - -
    - -
    - - - - tracks - - object[] - - -
    -
  • -
    - Array [ -
    -
  • - -
  • -
    - ] -
    -
  • -
    -
    -
    -
    -
    -
    - - - - - - -
    - - - user - object - - required - - -
    - - - - -
    - - - - cover_photo - - object - - -
    - - -
    -
    -
    - - - - - - - - - - - - - - - - - -
    - - - - profile_picture - - object - - -
    - - - -
    -
    -
    - - - - - - - - - - - -
    -
    -
    - - - - - - - - -
  • -
    - ] -
    -
  • -
    -
    -
    -
-
-
- - - -
-
-
-
-
- -
Bad request
-
-
- -
Server error
-
-
-
-
-
diff --git a/docs/docs/developers/api/sidebar.ts b/docs/docs/developers/api/sidebar.ts index 06dff36dda3..adbc34f77e1 100644 --- a/docs/docs/developers/api/sidebar.ts +++ b/docs/docs/developers/api/sidebar.ts @@ -22,12 +22,6 @@ const sidebar: SidebarsConfig = { label: 'Get User by Handle', className: 'api-method get', }, - { - type: 'doc', - id: 'developers/api/get-ai-attributed-tracks-by-user-handle', - label: 'Get AI Attributed Tracks by User Handle', - className: 'api-method get', - }, { type: 'doc', id: 'developers/api/get-user-id-from-wallet', diff --git a/docs/docs/developers/upload-track-metadata.mdx b/docs/docs/developers/upload-track-metadata.mdx index 4082efb3fd2..66c82b014e6 100644 --- a/docs/docs/developers/upload-track-metadata.mdx +++ b/docs/docs/developers/upload-track-metadata.mdx @@ -25,7 +25,6 @@ Contains required and optional fields for uploading a track. releaseDate?: Date; // Should not be in the future. Defaults to today's date. tags?: string; // Comma separated list of tags remixOf?: { tracks: Array<{ parentTrackId: string }> }; // For specifying the track(s) that your track is a remix of - aiAttributionUserId?: string; // Audius user ID of the artist whom your AI-generated track was trained on. Note: Only artists who have opted into AI attribution can be used. isStreamGated?: boolean; // Whether streaming your track is only available to users who meet certain criteria, which must be specified by `streamConditions`. streamConditions?: AccessConditions; // See "Specifying Stream Conditions" section below isDownloadGated?: boolean; // Whether downloading your track is only available to users who meet certain criteria, which must be specified by `downloadConditions`. Note that stream gated tracks are automatically download gated, whereas the reverse is not true. @@ -70,7 +69,6 @@ const { trackId } = await audiusSdk.tracks.uploadTrack({ releaseDate: new Date('2022-09-30'), tags: 'plantlife,love,monstera', remixOf: { tracks: [{ parentTrackId: 'KVx2xpO' }] }, - aiAttributionUserId: '3aE1p', isStreamGated: true, streamConditions: { tipUserId: '7eP5n', // Require tipping user to unlock track for streaming diff --git a/docs/sidebars.js b/docs/sidebars.js index 4297ca49138..384574ff167 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -208,7 +208,6 @@ module.exports = { 'developers/api/get-purchasers', 'developers/api/get-remixers', 'developers/api/get-top-track-tags', - 'developers/api/get-ai-attributed-tracks-by-user-handle', 'developers/api/get-related-users', 'developers/api/verify-id-token', 'developers/api/get-authorized-apps', diff --git a/packages/commands/src/user/create-user.ts b/packages/commands/src/user/create-user.ts index 50543d88ad5..5c548eda994 100644 --- a/packages/commands/src/user/create-user.ts +++ b/packages/commands/src/user/create-user.ts @@ -24,11 +24,6 @@ export const createUserCommand = new Command('create') '-e, --email ', 'The email for the new user (chosen randomly if not specified)' ) - .option( - '-ai, --allow-ai-attribution [isAllowed]', - "Whether to allow other users to attribute AI tracks using this user's likeness", - parseBoolean - ) .addOption(outputFormatOption) .action(async (handle, options) => { const audiusSdk = await initializeAudiusSdk() @@ -37,8 +32,7 @@ export const createUserCommand = new Command('create') const { email = `audius-cmd+${handle || rand}@audius.co`, - password = 'password', - allowAiAttribution + password = 'password' } = options const hedgehog = getHedgehog() @@ -47,7 +41,6 @@ export const createUserCommand = new Command('create') const { metadata: newMetadata } = await audiusSdk.users.createUser({ metadata: { - allowAiAttribution, bio: `account generated by audius-cmd ${rand}`, handle: handle || `handle${rand}`, location: `location${rand}`, diff --git a/packages/commands/src/user/edit-user.ts b/packages/commands/src/user/edit-user.ts index dbd96e6a166..54410f230fe 100644 --- a/packages/commands/src/user/edit-user.ts +++ b/packages/commands/src/user/edit-user.ts @@ -14,26 +14,19 @@ export const editUserCommand = new Command('edit') .option('-n, --name ', "The user's new name") .option('-b, --bio ', "The user's new bio") .option('-l, --location ', "The user's new location") - .option( - '-ai, --allow-ai-attribution ', - "Whether to allow other users to attribute AI tracks using this user's likeness", - parseBoolean - ) .addOption(outputFormatOption) - .action( - async (handle, { name, bio, location, allowAiAttribution, output }) => { - const audiusSdk = await initializeAudiusSdk({ handle }) - const userId = await getCurrentUserId() + .action(async (handle, { name, bio, location, output }) => { + const audiusSdk = await initializeAudiusSdk({ handle }) + const userId = await getCurrentUserId() - const result = await audiusSdk.users.updateProfile({ - userId, - metadata: { name, bio, location, allowAiAttribution } - }) + const result = await audiusSdk.users.updateProfile({ + userId, + metadata: { name, bio, location } + }) - if (output === 'json') { - console.log(JSON.stringify(result)) - } else { - console.log(chalk.green('Successfully updated user!')) - } + if (output === 'json') { + console.log(JSON.stringify(result)) + } else { + console.log(chalk.green('Successfully updated user!')) } - ) + }) diff --git a/packages/common/src/adapters/track.ts b/packages/common/src/adapters/track.ts index 62ace9125f1..af7ce63d24a 100644 --- a/packages/common/src/adapters/track.ts +++ b/packages/common/src/adapters/track.ts @@ -116,7 +116,6 @@ export const userTrackMetadataFromSDK = ( license: (input.license as License) ?? null, // Nullable fields - ai_attribution_user_id: input.aiAttributionUserId ?? null, allowed_api_keys: input.allowedApiKeys ?? null, artists: input.artists ? transformAndCleanList(input.artists, resourceContributorFromSDK) @@ -271,7 +270,6 @@ export const trackMetadataForUploadToSdk = ( previewStartSeconds: input.preview_start_seconds ?? undefined, previewCid: input.preview_cid ?? '', ddexApp: input.ddex_app ?? '', - aiAttributionUserId: OptionalId.parse(input.ai_attribution_user_id), audioUploadId: input.audio_upload_id ?? undefined, duration: input.duration ?? undefined, musicalKey: input.musical_key diff --git a/packages/common/src/adapters/user.ts b/packages/common/src/adapters/user.ts index 86d2fc56fe2..964dd675f68 100644 --- a/packages/common/src/adapters/user.ts +++ b/packages/common/src/adapters/user.ts @@ -173,7 +173,6 @@ export const userMetadataToSdk = ( 'name', 'handle', 'is_deactivated', - 'allow_ai_attribution', 'profile_type', 'spl_usdc_payout_wallet' ]) diff --git a/packages/common/src/api/tan-query/lineups/useAiTracks.ts b/packages/common/src/api/tan-query/lineups/useAiTracks.ts deleted file mode 100644 index 4cb33eef732..00000000000 --- a/packages/common/src/api/tan-query/lineups/useAiTracks.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { useEffect } from 'react' - -import { EntityType, OptionalId } from '@audius/sdk' -import { - InfiniteData, - useInfiniteQuery, - useQueryClient -} from '@tanstack/react-query' -import { useDispatch } from 'react-redux' - -import { userTrackMetadataFromSDK } from '~/adapters/track' -import { transformAndCleanList } from '~/adapters/utils' -import { useQueryContext } from '~/api/tan-query/utils' -import { PlaybackSource } from '~/models' -import { aiPageLineupActions, aiPageSelectors } from '~/store/pages' -import { fetchAiUser } from '~/store/pages/ai/slice' - -import { QUERY_KEYS } from '../queryKeys' -import { LineupData, QueryKey, QueryOptions } from '../types' -import { useCurrentUserId } from '../users/account/useCurrentUserId' -import { primeTrackData } from '../utils/primeTrackData' - -import { useLineupQuery } from './useLineupQuery' - -const DEFAULT_PAGE_SIZE = 10 - -type UseAiTracksArgs = { - handle: string - pageSize?: number -} - -export const getAiTracksQueryKey = ({ - handle, - pageSize = DEFAULT_PAGE_SIZE -}: UseAiTracksArgs) => - [QUERY_KEYS.aiTracks, handle, { pageSize }] as unknown as QueryKey< - InfiniteData - > - -export const useAiTracks = ( - { handle, pageSize = DEFAULT_PAGE_SIZE }: UseAiTracksArgs, - options?: QueryOptions -) => { - const { audiusSdk } = useQueryContext() - const { data: currentUserId } = useCurrentUserId() - const queryClient = useQueryClient() - const dispatch = useDispatch() - - useEffect(() => { - dispatch(fetchAiUser({ handle })) - }, [dispatch, handle]) - - const queryData = useInfiniteQuery({ - queryKey: getAiTracksQueryKey({ handle, pageSize }), - initialPageParam: 0, - getNextPageParam: (lastPage: LineupData[], allPages) => { - if (lastPage.length < pageSize) return undefined - return allPages.length * pageSize - }, - queryFn: async ({ pageParam }) => { - const sdk = await audiusSdk() - - const { data: tracks } = - await sdk.full.users.getAIAttributedTracksByUserHandle({ - handle, - userId: OptionalId.parse(currentUserId), - limit: pageSize, - offset: pageParam, - filterTracks: 'public', - sort: 'date' - }) - - if (!tracks) return [] - - const processedTracks = transformAndCleanList( - tracks, - userTrackMetadataFromSDK - ) - primeTrackData({ tracks: processedTracks, queryClient }) - - // Update lineup when new data arrives - dispatch( - aiPageLineupActions.fetchLineupMetadatas(pageParam, pageSize, false, { - tracks: processedTracks - }) - ) - - return processedTracks.map((t) => ({ - id: t.track_id, - type: EntityType.TRACK - })) - }, - select: (data) => data?.pages.flat(), - ...options, - enabled: options?.enabled !== false && !!handle - }) - - return useLineupQuery({ - lineupData: queryData.data ?? [], - queryData, - queryKey: getAiTracksQueryKey({ - handle, - pageSize - }), - lineupActions: aiPageLineupActions, - lineupSelector: aiPageSelectors.getLineup, - playbackSource: PlaybackSource.TRACK_TILE, - pageSize - }) -} diff --git a/packages/common/src/messages/edit.ts b/packages/common/src/messages/edit.ts index 1faf5c5d5fa..2b5cdc47b23 100644 --- a/packages/common/src/messages/edit.ts +++ b/packages/common/src/messages/edit.ts @@ -68,21 +68,12 @@ export const priceAndAudienceMessages = { export const advancedTrackMessages = { title: 'Advanced', description: 'Share metadata to help manage your music.', - isAiGenerated: 'AI-Generated', bpm: { header: 'Tempo', label: 'BPM', validError: 'Must be a valid decimal number' }, musicalKey: 'Key', - aiGenerated: { - header: 'AI Generated', - description: 'Mark this track as AI generated', - tooltip: - 'If your AI-generated track was trained on an existing Audius artist, you can give them credit here. Only users who have opted-in will appear in this list.', - placeholder: 'Search for Users', - requiredError: 'Valid user must be selected.' - }, apiAllowed: { header: 'Disallow Streaming via the API', description: diff --git a/packages/common/src/messages/settings.ts b/packages/common/src/messages/settings.ts index 547de4a9255..4ad1917bd2e 100644 --- a/packages/common/src/messages/settings.ts +++ b/packages/common/src/messages/settings.ts @@ -16,7 +16,6 @@ export const settingsMessages = { matrixMode: 'Matrix', signOut: 'Sign Out', - aiGeneratedCardTitle: 'AI Generated music', appearanceTitle: 'Appearance', inboxSettingsCardTitle: 'Inbox Settings', commentSettingsCardTitle: 'Comment Settings', @@ -29,8 +28,6 @@ export const settingsMessages = { verificationCardTitle: 'Verification', desktopAppCardTitle: 'Download the Desktop App', - aiGeneratedCardDescription: - 'Opt in to allow AI models to be trained on your likeness, and to let users credit you in their AI generated works.', appearanceDescription: "Enable dark mode or choose 'Auto' to change with your system settings.", inboxSettingsCardDescription: @@ -50,8 +47,6 @@ export const settingsMessages = { labelAccountCardDescription: 'Identify as a record label on your Audius profile.', - aiGeneratedEnabled: 'Enabled', - aiGeneratedButtonText: 'AI Generated Music Settings', inboxSettingsButtonText: 'Inbox Settings', commentSettingsButtonText: 'Comment Settings', notificationsButtonText: 'Configure Notifications', diff --git a/packages/common/src/models/Search.ts b/packages/common/src/models/Search.ts index dfda833d3bf..af5118f691b 100644 --- a/packages/common/src/models/Search.ts +++ b/packages/common/src/models/Search.ts @@ -16,7 +16,6 @@ type BaseUser = Pick< export type SearchUser = UserMultihash & UserImage & BaseUser & { - allow_ai_attribution?: boolean album_count: null bio: string followee_count: null @@ -39,7 +38,6 @@ export type SearchUser = UserMultihash & } export type SearchTrack = TrackImage & { - ai_attribution_user_id?: number _co_sign: undefined description: string | null genre: string diff --git a/packages/common/src/models/Track.ts b/packages/common/src/models/Track.ts index 252eacf0f3a..d7fb7fc2c1e 100644 --- a/packages/common/src/models/Track.ts +++ b/packages/common/src/models/Track.ts @@ -147,7 +147,6 @@ type CoverArtSizesWithMirror = CoverArtSizes & { } export type TrackMetadata = { - ai_attribution_user_id?: Nullable allowed_api_keys?: Nullable audio_upload_id?: Nullable blocknumber: number diff --git a/packages/common/src/models/User.ts b/packages/common/src/models/User.ts index c46017118d1..2d54e48fbfc 100644 --- a/packages/common/src/models/User.ts +++ b/packages/common/src/models/User.ts @@ -19,7 +19,6 @@ export type SocialPlatform = 'x' | 'instagram' | 'tiktok' export type UserMetadata = { album_count: number - allow_ai_attribution?: boolean artist_coin_badge?: Nullable<{ mint: string logo_uri: string diff --git a/packages/common/src/schemas/metadata.ts b/packages/common/src/schemas/metadata.ts index 8e241fbf2b8..d180c8376fb 100644 --- a/packages/common/src/schemas/metadata.ts +++ b/packages/common/src/schemas/metadata.ts @@ -53,7 +53,6 @@ const trackMetadataSchema = { isrc: null, iswc: null, is_playlist_upload: false, - ai_attribution_user_id: null, ddex_release_ids: null, ddex_app: null, artists: null, @@ -137,7 +136,6 @@ export const newCollectionMetadata = (fields?: any, validate = false) => { } const userMetadataSchema = { - allow_ai_attribution: false, wallet: '', name: null, handle: '', diff --git a/packages/common/src/schemas/upload/uploadFormSchema.ts b/packages/common/src/schemas/upload/uploadFormSchema.ts index 1e8fc2cd19b..6bbe1402e17 100644 --- a/packages/common/src/schemas/upload/uploadFormSchema.ts +++ b/packages/common/src/schemas/upload/uploadFormSchema.ts @@ -146,7 +146,6 @@ const createSdkSchema = () => z .object({ track_id: z.optional(z.number()).nullable(), - ai_attribution_user_id: z.optional(z.number()).nullable(), allowed_api_keys: z.optional(z.array(z.string())).nullable(), description: z .optional(z.string().max(MAX_DESCRIPTION_LENGTH)) diff --git a/packages/common/src/store/lineup/registry.ts b/packages/common/src/store/lineup/registry.ts index e07141fd0e9..6a76a246f9c 100644 --- a/packages/common/src/store/lineup/registry.ts +++ b/packages/common/src/store/lineup/registry.ts @@ -1,7 +1,5 @@ import { LineupState } from '~/models/Lineup' import { - aiPageLineupActions, - aiPageSelectors, collectionPageLineupActions, collectionPageSelectors, feedPageLineupActions, @@ -35,10 +33,6 @@ type LineupEntry = { } export const lineupRegistry: Record = { - [aiPageLineupActions.prefix]: { - actions: aiPageLineupActions, - selector: aiPageSelectors.getLineup - }, [collectionPageLineupActions.prefix]: { actions: collectionPageLineupActions, selector: collectionPageSelectors.getCollectionTracksLineup diff --git a/packages/common/src/store/pages/ai/lineup/actions.ts b/packages/common/src/store/pages/ai/lineup/actions.ts deleted file mode 100644 index 6e62dfdf0ad..00000000000 --- a/packages/common/src/store/pages/ai/lineup/actions.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { LineupActions } from '../../../lineup/actions' - -export const PREFIX = 'AI_TRACKS' - -class TracksActions extends LineupActions { - constructor() { - super(PREFIX) - } -} - -export const tracksActions = new TracksActions() diff --git a/packages/common/src/store/pages/ai/lineup/reducer.ts b/packages/common/src/store/pages/ai/lineup/reducer.ts deleted file mode 100644 index d28d9dfd72e..00000000000 --- a/packages/common/src/store/pages/ai/lineup/reducer.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { RESET_SUCCEEDED, stripPrefix } from '~/store/lineup/actions' -import { initialLineupState } from '~/store/lineup/reducer' - -import { PREFIX } from './actions' - -export const initialState = { - ...initialLineupState, - prefix: PREFIX -} - -const actionsMap: { [key in string]: any } = { - [RESET_SUCCEEDED](_state: typeof initialState) { - const newState = initialState - return newState - } -} - -const tracks = (state = initialState, action: { type: string }) => { - const baseActionType = stripPrefix(PREFIX, action.type) - const matchingReduceFunction = actionsMap[baseActionType] - if (!matchingReduceFunction) return state - return matchingReduceFunction(state, action) -} - -export default tracks diff --git a/packages/common/src/store/pages/ai/selectors.ts b/packages/common/src/store/pages/ai/selectors.ts deleted file mode 100644 index 78b3115dabc..00000000000 --- a/packages/common/src/store/pages/ai/selectors.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CommonState } from '~/store/commonStore' - -export const getBaseState = (state: CommonState) => state.pages.ai - -export const getLineup = (state: CommonState) => getBaseState(state).tracks - -export const getAiUserId = (state: CommonState) => - getBaseState(state).page.userId - -export const getAiUserHandle = (state: CommonState) => - getBaseState(state).page.handle - -export const getCount = (state: CommonState) => getBaseState(state).page.count diff --git a/packages/common/src/store/pages/ai/slice.ts b/packages/common/src/store/pages/ai/slice.ts deleted file mode 100644 index f609366d466..00000000000 --- a/packages/common/src/store/pages/ai/slice.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { createSlice, PayloadAction } from '@reduxjs/toolkit' -import { combineReducers } from 'redux' - -import { Status } from '~/models/Status' -import { asLineup } from '~/store/lineup/reducer' - -import { ID } from '../../../models/Identifiers' - -import { PREFIX as aiTracksPrefix } from './lineup/actions' -import aiTracksReducer, { - initialState as initialLineupState -} from './lineup/reducer' - -export type AiPageState = { - userId: ID | null - handle: string | null - status: Status - count: number | null - tracks: typeof initialLineupState -} - -export type FetchAiUserAction = PayloadAction<{ - handle?: string - userId?: ID -}> - -const initialState: AiPageState = { - userId: null, - handle: null, - status: Status.IDLE, - count: null, - tracks: initialLineupState -} - -const slice = createSlice({ - name: 'application/pages/ai', - initialState, - reducers: { - reset: (state) => { - state.userId = null - }, - fetchAiUser: (state, action: FetchAiUserAction) => { - const { handle, userId } = action.payload - state.status = Status.LOADING - if (handle) { - state.handle = handle - } - if (userId) { - state.userId = userId - } - }, - fetchAiUserSucceeded: (state, action: PayloadAction<{ userId: ID }>) => { - const { userId } = action.payload - state.userId = userId - state.status = Status.SUCCESS - }, - fetchAiUserFailed: (state) => { - state.status = Status.ERROR - }, - setCount: (state, action: PayloadAction<{ count: number }>) => { - const { count } = action.payload - state.count = count - } - } -}) - -const aiLineupReducer = asLineup(aiTracksPrefix, aiTracksReducer) - -export const { reset, setCount, fetchAiUser, fetchAiUserSucceeded } = - slice.actions - -export default combineReducers({ - page: slice.reducer, - tracks: aiLineupReducer -}) - -export const actions = slice.actions diff --git a/packages/common/src/store/pages/index.ts b/packages/common/src/store/pages/index.ts index a35197c8bc6..751ec286075 100644 --- a/packages/common/src/store/pages/index.ts +++ b/packages/common/src/store/pages/index.ts @@ -77,15 +77,6 @@ export { } from './remixes/slice' export * as remixesPageSelectors from './remixes/selectors' -export { - default as aiPageLineupReducer, - initialState as aiPageLineupInitialState -} from './ai/lineup/reducer' -export { tracksActions as aiPageLineupActions } from './ai/lineup/actions' -export { default as aiPageReducer, actions as aiPageActions } from './ai/slice' -export type { FetchAiUserAction } from './ai/slice' -export * as aiPageSelectors from './ai/selectors' - export { default as profilePageFeedLineupReducer } from './profile/lineups/feed/reducer' export { feedActions as profilePageFeedLineupActions } from './profile/lineups/feed/actions' export { default as profilePageTracksLineupReducer } from './profile/lineups/tracks/reducer' diff --git a/packages/common/src/store/pages/settings/actions.ts b/packages/common/src/store/pages/settings/actions.ts index 046e39dfb02..4201429d5ad 100644 --- a/packages/common/src/store/pages/settings/actions.ts +++ b/packages/common/src/store/pages/settings/actions.ts @@ -45,8 +45,6 @@ export const SET_BROWSER_NOTIFICATION_SETTINGS_OFF = export const BROWSER_PUSH_NOTIFICATION_FAILED = 'SETTINGS/BROWSER_PUSH_NOTIFICATION_FAILED' -export const SET_AI_ATTRIBUTION = 'SETTINGS/SET_AI_ATTRIBUTION' - export function getNotificationSettings() { return { type: GET_NOTIFICATION_SETTINGS } } @@ -132,10 +130,6 @@ export function browserPushNotificationFailed(error: string) { return { type: BROWSER_PUSH_NOTIFICATION_FAILED, error } } -export function setAiAttribution(enabled: boolean) { - return { type: SET_AI_ATTRIBUTION, allowAiAttribution: enabled } -} - export type ToggleNotificationSetting = ReturnType< typeof toggleNotificationSetting > @@ -183,8 +177,6 @@ export type BrowserPushNotificationFailed = ReturnType< typeof browserPushNotificationFailed > -export type SetAiAttribution = ReturnType - export type SettingActions = | RequestPushNotificationPermissions | ToggleNotificationSetting diff --git a/packages/common/src/store/pages/settings/reducer.ts b/packages/common/src/store/pages/settings/reducer.ts index e3ff524627f..6bcddd98909 100644 --- a/packages/common/src/store/pages/settings/reducer.ts +++ b/packages/common/src/store/pages/settings/reducer.ts @@ -10,8 +10,7 @@ import { TOGGLE_PUSH_NOTIFICATION_SETTING, TogglePushNotificationSetting, SET_BROWSER_NOTIFICATION_PERMISSION, - SET_BROWSER_NOTIFICATION_ENABLED, - SET_AI_ATTRIBUTION + SET_BROWSER_NOTIFICATION_ENABLED } from './actions' import { SettingsPageState, @@ -144,9 +143,6 @@ const actionsMap: ActionsMap = { ...state, [emailFrequency]: action.frequency } - }, - [SET_AI_ATTRIBUTION](_state, _action) { - return _state } } diff --git a/packages/common/src/store/reducers.ts b/packages/common/src/store/reducers.ts index c35476037e8..45220458f8e 100644 --- a/packages/common/src/store/reducers.ts +++ b/packages/common/src/store/reducers.ts @@ -16,7 +16,6 @@ import musicConfettiReducer, { MusicConfettiState } from './music-confetti/slice' import { HistoryPageState, LibraryPageState } from './pages' -import ai from './pages/ai/slice' import audioRewardsSlice from './pages/audio-rewards/slice' import { chatReducer } from './pages/chat' import collection from './pages/collection/reducer' @@ -178,7 +177,6 @@ export const reducers = (storage: Storage, history?: History) => ({ // Pages pages: combineReducers({ - ai, audioRewards: audioRewardsSlice.reducer, chat: chatReducer, collection, @@ -285,7 +283,6 @@ export type CommonState = { } pages: { - ai: ReturnType audioRewards: ReturnType chat: ReturnType collection: CollectionsPageState diff --git a/packages/common/src/store/ui/modals/parentSlice.ts b/packages/common/src/store/ui/modals/parentSlice.ts index 20d5ff72a60..04bc2d8ce8f 100644 --- a/packages/common/src/store/ui/modals/parentSlice.ts +++ b/packages/common/src/store/ui/modals/parentSlice.ts @@ -47,7 +47,6 @@ export const initialState: BasicModalsState = { ProfileActions: { isOpen: false }, PublishContentModal: { isOpen: false }, AlbumTrackRemoveConfirmation: { isOpen: false }, - AiAttributionSettings: { isOpen: false }, PremiumContentPurchaseModal: { isOpen: false }, CreateChatModal: { isOpen: false }, ChatBlastModal: { isOpen: false }, diff --git a/packages/common/src/store/ui/modals/types.ts b/packages/common/src/store/ui/modals/types.ts index e4a1c4ce190..e7a0685cf43 100644 --- a/packages/common/src/store/ui/modals/types.ts +++ b/packages/common/src/store/ui/modals/types.ts @@ -82,7 +82,6 @@ export type Modals = | 'ProfileActions' | 'PublishContentModal' | 'LabelAccount' - | 'AiAttributionSettings' | 'DuplicateAddConfirmation' | 'PremiumContentPurchaseModal' | 'CreateChatModal' diff --git a/packages/common/src/utils/route.ts b/packages/common/src/utils/route.ts index f2bfe0e9b9b..fdc480126be 100644 --- a/packages/common/src/utils/route.ts +++ b/packages/common/src/utils/route.ts @@ -140,7 +140,6 @@ export const PROFILE_PAGE_TRACKS = '/:handle/tracks' export const PROFILE_PAGE_ALBUMS = '/:handle/albums' export const PROFILE_PAGE_PLAYLISTS = '/:handle/playlists' export const PROFILE_PAGE_REPOSTS = '/:handle/reposts' -export const PROFILE_PAGE_AI_ATTRIBUTED_TRACKS = '/:handle/ai' export const PROFILE_PAGE_COMMENTS = '/:handle/comments' // Opaque id routes diff --git a/packages/discovery-provider/integration_tests/queries/test_get_tracks.py b/packages/discovery-provider/integration_tests/queries/test_get_tracks.py index 230ab362c07..9ac592c5c6a 100644 --- a/packages/discovery-provider/integration_tests/queries/test_get_tracks.py +++ b/packages/discovery-provider/integration_tests/queries/test_get_tracks.py @@ -573,27 +573,3 @@ def test_get_remixes_of_with_multiple_events(app): assert ( response["count"] == 3 ), f"Expected count of 3, got {response['count']} - count may be inflated by duplicates" - - -def test_get_ai_attributed_tracks(app): - """Test getting tracks with AI attribution""" - - with app.app_context(): - db = get_db() - - populate_tracks(db) - - with db.scoped_session() as session: - tracks = _get_tracks( - session, - { - "user_id": 1287289, - "offset": 0, - "limit": 10, - "ai_attributed_only": True, - "sort": "date", - }, - ) - assert len(tracks) == 2 - assert tracks[0]["track_id"] == 12 - assert tracks[1]["track_id"] == 3 diff --git a/packages/discovery-provider/src/api/v1/users.py b/packages/discovery-provider/src/api/v1/users.py index 8a175f7f8d7..e810c592639 100644 --- a/packages/discovery-provider/src/api/v1/users.py +++ b/packages/discovery-provider/src/api/v1/users.py @@ -620,75 +620,6 @@ def get(self, handle, authed_user_id): return super()._get(handle, authed_user_id) -USER_AI_ATTRIBUTED_TRACKS = USER_HANDLE_TRACKS + "/ai_attributed" - - -@full_ns.route(USER_AI_ATTRIBUTED_TRACKS) -class HandleFullAITrackList(Resource): - @record_metrics - @cache(ttl_sec=5) - def _get(self, handle, authed_user_id=None): - args = user_tracks_route_parser.parse_args() - - current_user_id = get_current_user_id(args) - - sort = args.get("sort", None) - sort_method = format_sort_method(args) - sort_direction = format_sort_direction(args) - offset = format_offset(args) - limit = format_limit(args) - filter_tracks = args.get("filter_tracks", "all") - - args = { - "handle": handle, - "current_user_id": current_user_id, - "authed_user_id": authed_user_id, - "with_users": True, - "filter_deleted": True, - "sort": sort, - "sort_method": sort_method, - "sort_direction": sort_direction, - "limit": limit, - "offset": offset, - "filter_tracks": filter_tracks, - "ai_attributed_only": True, - } - tracks = get_tracks(args) - tracks = list(map(extend_track, tracks)) - return success_response(tracks) - - @full_ns.doc( - id="""Get AI Attributed Tracks by User Handle""", - description="""Gets the AI generated tracks attributed to a user using the user's handle""", - params={ - "handle": "A User handle", - }, - responses={200: "Success", 400: "Bad request", 500: "Server error"}, - ) - @full_ns.expect(user_tracks_route_parser) - @auth_middleware(user_tracks_route_parser) - @full_ns.marshal_with(full_tracks_response) - def get(self, handle, authed_user_id=None): - return self._get(handle, authed_user_id) - - -@ns.route(USER_AI_ATTRIBUTED_TRACKS) -class HandleAITrackList(HandleFullAITrackList): - @ns.doc( - id="""Get AI Attributed Tracks by User Handle""", - description="""Gets the AI generated tracks attributed to a user using the user's handle""", - params={ - "handle": "A User handle", - }, - responses={200: "Success", 400: "Bad request", 500: "Server error"}, - ) - @ns.expect(user_tracks_route_parser) - @auth_middleware(user_tracks_route_parser) - @ns.marshal_with(tracks_response) - def get(self, handle, authed_user_id): - return super()._get(handle, authed_user_id) - - USER_REPOSTS_ROUTE = "//reposts" reposts_response = make_response("reposts", ns, fields.List(activity_model)) diff --git a/packages/discovery-provider/src/queries/get_tracks.py b/packages/discovery-provider/src/queries/get_tracks.py index ae6cdb4afe5..cf5525bfc9a 100644 --- a/packages/discovery-provider/src/queries/get_tracks.py +++ b/packages/discovery-provider/src/queries/get_tracks.py @@ -126,12 +126,7 @@ def _get_tracks(session, args): # Allow filtering of tracks by a certain creator if args.get("user_id"): user_id = args.get("user_id") - if args.get("ai_attributed_only"): - base_query = base_query.filter( - TrackWithAggregates.ai_attribution_user_id == args.get("user_id") - ) - else: - base_query = base_query.filter(TrackWithAggregates.owner_id == user_id) + base_query = base_query.filter(TrackWithAggregates.owner_id == user_id) # Allow filtering of deletes if "filter_deleted" in args and args.get("filter_deleted") is not None: diff --git a/packages/discovery-provider/src/tasks/entity_manager/entities/track.py b/packages/discovery-provider/src/tasks/entity_manager/entities/track.py index 7b381937344..383449aa7da 100644 --- a/packages/discovery-provider/src/tasks/entity_manager/entities/track.py +++ b/packages/discovery-provider/src/tasks/entity_manager/entities/track.py @@ -536,17 +536,6 @@ def validate_track_tx(params: ManageEntityParameters): if track_id not in params.existing_records["Track"]: raise IndexingValidationError(f"Track {track_id} does not exist") - if params.action != Action.DELETE and params.action != Action.DOWNLOAD: - ai_attribution_user_id = params.metadata.get("ai_attribution_user_id") - if ai_attribution_user_id: - ai_attribution_user = params.existing_records["User"][ - ai_attribution_user_id - ] - if not ai_attribution_user or not ai_attribution_user.allow_ai_attribution: - raise IndexingValidationError( - f"Cannot AI attribute user {ai_attribution_user}" - ) - def get_handle(params: ManageEntityParameters): # TODO: get the track owner user handle diff --git a/packages/harmony/src/assets/icons/Robot.svg b/packages/harmony/src/assets/icons/Robot.svg deleted file mode 100644 index c63a7f0b24c..00000000000 --- a/packages/harmony/src/assets/icons/Robot.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/packages/harmony/src/components/music-badge/MusicBadge.stories.tsx b/packages/harmony/src/components/music-badge/MusicBadge.stories.tsx index 0325cb6fd57..c1a1b0e2465 100644 --- a/packages/harmony/src/components/music-badge/MusicBadge.stories.tsx +++ b/packages/harmony/src/components/music-badge/MusicBadge.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from '@storybook/react' -import IconRobot from '~harmony/assets/icons/Robot.svg' +import { IconTrending } from '~harmony/icons' import { MusicBadge } from './MusicBadge' @@ -15,7 +15,7 @@ type Story = StoryObj export const Default: Story = { args: { - icon: IconRobot, + icon: IconTrending, children: 'Example Badge' } } diff --git a/packages/harmony/src/foundations/color/primitive.css b/packages/harmony/src/foundations/color/primitive.css index bb00e79b8a9..f23f71d5796 100644 --- a/packages/harmony/src/foundations/color/primitive.css +++ b/packages/harmony/src/foundations/color/primitive.css @@ -61,7 +61,6 @@ #1ba1f1ff 104.43% ); --harmony-trending-blue: #216fdcff; - --harmony-ai-green: #1fd187ff; --harmony-glass-overlay: #ffffffd9; } @@ -118,7 +117,6 @@ html[data-theme='day'] { #1ba1f1ff 104.43% ); --harmony-trending-blue: #216fdcff; - --harmony-ai-green: #1fd187ff; --harmony-glass-overlay: #ffffffd9; } @@ -175,7 +173,6 @@ html[data-theme='dark'] { #58b9f4ff 104.43% ); --harmony-trending-blue: #2a85e8ff; - --harmony-ai-green: #1ecf7aff; --harmony-glass-overlay: #2f334899; } @@ -232,6 +229,5 @@ html[data-theme='matrix'] { #20e290ff 104.43% ); --harmony-trending-blue: #1eeb6fff; - --harmony-ai-green: #1eeb57ff; --harmony-glass-overlay: #01010199; } diff --git a/packages/harmony/src/foundations/color/primitive.ts b/packages/harmony/src/foundations/color/primitive.ts index d7253e4f88b..396cb8ea690 100644 --- a/packages/harmony/src/foundations/color/primitive.ts +++ b/packages/harmony/src/foundations/color/primitive.ts @@ -43,7 +43,6 @@ export const primitiveTheme = { neutral: '#6C6780FF' }, special: { - aiGreen: '#1FD187FF', background: '#F6F5F7FF', blue: '#1BA1F1FF', darkRed: '#BB0218FF', @@ -110,7 +109,6 @@ export const primitiveTheme = { neutral: '#C6C8D6FF' }, special: { - aiGreen: '#1ECF7AFF', background: '#202131FF', blue: '#58B9F4FF', darkRed: '#C43047FF', @@ -177,7 +175,6 @@ export const primitiveTheme = { neutral: '#3EF56BFF' }, special: { - aiGreen: '#1EEB57FF', background: '#000000FF', blue: '#20E290FF', darkRed: '#D63C5AFF', diff --git a/packages/harmony/src/icons/Changelog.stories.mdx b/packages/harmony/src/icons/Changelog.stories.mdx index ac49d9192e9..1e13484f201 100644 --- a/packages/harmony/src/icons/Changelog.stories.mdx +++ b/packages/harmony/src/icons/Changelog.stories.mdx @@ -636,3 +636,12 @@ Removed Collectible icon + + + +## 10/27/25 + +Removed Robot icon + + + diff --git a/packages/harmony/src/icons/UtilityIcons.stories.mdx b/packages/harmony/src/icons/UtilityIcons.stories.mdx index 0440234602f..a0ec44f2abf 100644 --- a/packages/harmony/src/icons/UtilityIcons.stories.mdx +++ b/packages/harmony/src/icons/UtilityIcons.stories.mdx @@ -146,7 +146,6 @@ Utility icons are simple, single-color glyphs that identify labels and actions a | | Remove | circle | minus | - | - | | | RepeatOff | Arrow | Repeat | Off | - | | | Repost | Arrows | Repost | - | - | -| | Robot | Robot | Face | - | - | | | Rocket | Rocket | - | - | - | | | Save | Plus | - | - | - | | | Search | magnifying | glass | - | - | diff --git a/packages/harmony/src/icons/utilityIcons.ts b/packages/harmony/src/icons/utilityIcons.ts index 02ada5d6fea..ba3cd7b74e7 100644 --- a/packages/harmony/src/icons/utilityIcons.ts +++ b/packages/harmony/src/icons/utilityIcons.ts @@ -102,7 +102,6 @@ import IconRemixSVG from '../assets/icons/Remix.svg' import IconRemoveSVG from '../assets/icons/Remove.svg' import IconRepeatOffSVG from '../assets/icons/RepeatOff.svg' import IconRepostSVG from '../assets/icons/Repost.svg' -import IconRobotSVG from '../assets/icons/Robot.svg' import IconRocketSVG from '../assets/icons/Rocket.svg' import IconSaveSVG from '../assets/icons/Save.svg' import IconSearchSVG from '../assets/icons/Search.svg' @@ -294,7 +293,6 @@ export const IconError = IconErrorSVG as IconComponent export const IconRepost = IconRepostSVG as IconComponent export const IconWallet = IconWalletSVG as IconComponent export const IconExplore = IconExploreSVG as IconComponent -export const IconRobot = IconRobotSVG as IconComponent export const IconWand = IconWandSVG as IconComponent export const IconExternalLink = IconExternalLinkSVG as IconComponent export const IconRocket = IconRocketSVG as IconComponent diff --git a/packages/mobile/src/components/details-tile/DetailsTileAiAttribution.tsx b/packages/mobile/src/components/details-tile/DetailsTileAiAttribution.tsx deleted file mode 100644 index b2830773a76..00000000000 --- a/packages/mobile/src/components/details-tile/DetailsTileAiAttribution.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { useEffect } from 'react' - -import { useUser } from '@audius/common/api' -import type { ID } from '@audius/common/models' -import { aiPageActions, aiPageSelectors } from '@audius/common/store' -import { TouchableOpacity } from 'react-native' -import { useDispatch, useSelector } from 'react-redux' - -import { IconRobot } from '@audius/harmony-native' -import { MusicBadge } from 'app/harmony-native/components/MusicBadge/MusicBadge' -import { useNavigation } from 'app/hooks/useNavigation' - -const { fetchAiUser, reset } = aiPageActions -const { getAiUserId } = aiPageSelectors - -const messages = { - aiGenerated: 'AI Generated' -} - -export const DetailsTileAiAttribution = ({ userId }: { userId: ID }) => { - const navigation = useNavigation() - const dispatch = useDispatch() - const aiUserId = useSelector(getAiUserId) - const { data: user } = useUser(aiUserId) - - useEffect(() => { - dispatch(fetchAiUser({ userId })) - return function cleanup() { - dispatch(reset()) - } - }, [dispatch, userId]) - - const handlePress = () => { - navigation.navigate('AiGeneratedTracks', { userId }) - } - - return user ? ( - - - {messages.aiGenerated} - - - ) : null -} diff --git a/packages/mobile/src/components/details-tile/DetailsTileBadge.tsx b/packages/mobile/src/components/details-tile/DetailsTileBadge.tsx deleted file mode 100644 index c3815c29633..00000000000 --- a/packages/mobile/src/components/details-tile/DetailsTileBadge.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import type { PropsWithChildren } from 'react' - -import Color from 'color' -import type { TouchableOpacityProps } from 'react-native-gesture-handler' -import { TouchableOpacity } from 'react-native-gesture-handler' - -import { IconRobot, Text, Flex, Button } from '@audius/harmony-native' - -type DetailsTileBadgeProps = PropsWithChildren< - Pick & { - color: string - } -> - -export const DetailsTileBadge = (props: DetailsTileBadgeProps) => { - const { children, color, onPress } = props - - const rootStyles = { - borderWidth: 1, - borderStyle: 'solid' as const, - borderColor: new Color(color).fade(0.5).string(), - backgroundColor: new Color(color).fade(0.8).string() - } - - return ( - - - - - {children} - - - - ) -} diff --git a/packages/mobile/src/harmony-native/components/MusicBadge/MusicBadge.stories.tsx b/packages/mobile/src/harmony-native/components/MusicBadge/MusicBadge.stories.tsx index e1abc392a12..4545df12c25 100644 --- a/packages/mobile/src/harmony-native/components/MusicBadge/MusicBadge.stories.tsx +++ b/packages/mobile/src/harmony-native/components/MusicBadge/MusicBadge.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from '@storybook/react' -import { IconRobot } from '@audius/harmony-native' +import { IconTrending } from '@audius/harmony-native' import type { MusicBadgeProps } from './MusicBadge' import { MusicBadge } from './MusicBadge' @@ -17,7 +17,7 @@ const meta: Meta = { color: { description: 'Color', control: { type: 'radio' }, - options: ['aiGreen', 'trendingBlue'] + options: ['trendingBlue'] } }, render: (props) => @@ -29,7 +29,7 @@ type Story = StoryObj export const Default: Story = { args: { - icon: IconRobot, + icon: IconTrending, children: 'Example Badge' } } @@ -37,15 +37,15 @@ export const Default: Story = { export const Accent: Story = { args: { variant: 'accent', - icon: IconRobot, + icon: IconTrending, children: 'Example Badge' } } export const Color: Story = { args: { - color: 'aiGreen', - icon: IconRobot, + color: 'trendingBlue', + icon: IconTrending, children: 'Example Badge' } } diff --git a/packages/mobile/src/harmony-native/icons.tsx b/packages/mobile/src/harmony-native/icons.tsx index e54ed9152a3..b3758c5db23 100644 --- a/packages/mobile/src/harmony-native/icons.tsx +++ b/packages/mobile/src/harmony-native/icons.tsx @@ -144,7 +144,6 @@ export { default as IconError } from '@audius/harmony/src/assets/icons/Error.svg export { default as IconRepost } from '@audius/harmony/src/assets/icons/Repost.svg' export { default as IconWallet } from '@audius/harmony/src/assets/icons/Wallet.svg' export { default as IconExplore } from '@audius/harmony/src/assets/icons/Explore.svg' -export { default as IconRobot } from '@audius/harmony/src/assets/icons/Robot.svg' export { default as IconWand } from '@audius/harmony/src/assets/icons/Wand.svg' export { default as IconExternalLink } from '@audius/harmony/src/assets/icons/ExternalLink.svg' export { default as IconRocket } from '@audius/harmony/src/assets/icons/Rocket.svg' diff --git a/packages/mobile/src/screens/ai-generated-tracks-screen/AiGeneratedTracksScreen.tsx b/packages/mobile/src/screens/ai-generated-tracks-screen/AiGeneratedTracksScreen.tsx deleted file mode 100644 index 984990a9069..00000000000 --- a/packages/mobile/src/screens/ai-generated-tracks-screen/AiGeneratedTracksScreen.tsx +++ /dev/null @@ -1,138 +0,0 @@ -import { useCallback, useEffect } from 'react' - -import { useUser } from '@audius/common/api' -import { - lineupSelectors, - aiPageLineupActions as tracksActions, - aiPageActions, - aiPageSelectors -} from '@audius/common/store' -import { TouchableOpacity, View } from 'react-native' -import { useDispatch, useSelector } from 'react-redux' - -import { IconRobot } from '@audius/harmony-native' -import { Text, Screen, ScreenContent, ScreenHeader } from 'app/components/core' -import { Lineup } from 'app/components/lineup' -import { UserBadges } from 'app/components/user-badges' -import { useNavigation } from 'app/hooks/useNavigation' -import { useProfileRoute } from 'app/hooks/useRoute' -import { makeStyles } from 'app/styles' -import { spacing } from 'app/styles/spacing' - -import { ShareAiTracksTile } from './ShareAiTracksTile' - -const { makeGetLineupMetadatas } = lineupSelectors -const { getAiUserId, getLineup } = aiPageSelectors -const { fetchAiUser, reset } = aiPageActions - -const getAiTracksLineup = makeGetLineupMetadatas(getLineup) - -const messages = { - header: 'AI Generated Tracks', - headerText: 'Tracks generated with AI trained on music by ' -} - -const iconSize = { height: spacing(6), width: spacing(6) } - -const useStyles = makeStyles(({ spacing, palette, typography }) => ({ - header: { - flexDirection: 'row', - flexWrap: 'wrap', - paddingHorizontal: spacing(7), - paddingVertical: spacing(3), - backgroundColor: palette.white - }, - headerText: { - fontSize: typography.fontSize.medium, - lineHeight: typography.fontSize.medium * 1.3, - textAlign: 'left' - }, - userBadgeTitle: { - fontSize: typography.fontSize.medium, - fontFamily: typography.fontByWeight.medium, - color: palette.secondary - } -})) - -export const AiGeneratedTracksScreen = () => { - const styles = useStyles() - const navigation = useNavigation() - const { params } = useProfileRoute<'AiGeneratedTracks'>() - const { userId } = params - const dispatch = useDispatch() - const lineup = useSelector(getAiTracksLineup) - const aiUserId = useSelector(getAiUserId) - const { data: user } = useUser(aiUserId) - - useEffect(() => { - dispatch(fetchAiUser({ userId })) - return function cleanup() { - dispatch(reset()) - dispatch(tracksActions.reset()) - } - }, [dispatch, userId]) - - useEffect(() => { - if (user?.handle) { - dispatch( - tracksActions.fetchLineupMetadatas(0, 10, false, { - aiUserHandle: user.handle - }) - ) - } - }, [dispatch, user]) - - const loadMore = useCallback( - (offset: number, limit: number, overwrite: boolean) => { - if (user?.handle) { - dispatch( - tracksActions.fetchLineupMetadatas(offset, limit, overwrite, { - aiUserHandle: user.handle - }) - ) - } - }, - [dispatch, user] - ) - - const handleGoToProfile = useCallback(() => { - navigation.navigate('Profile', { id: userId }) - }, [navigation, userId]) - - return ( - - - - - {messages.headerText} - - - {user.name} - - - - - ) : null - } - ListFooterComponent={} - actions={tracksActions} - lineup={lineup} - loadMore={loadMore} - /> - - - ) -} diff --git a/packages/mobile/src/screens/ai-generated-tracks-screen/ShareAiTracksTile.tsx b/packages/mobile/src/screens/ai-generated-tracks-screen/ShareAiTracksTile.tsx deleted file mode 100644 index 9c3f8424c84..00000000000 --- a/packages/mobile/src/screens/ai-generated-tracks-screen/ShareAiTracksTile.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { View, Image } from 'react-native' - -import RobotFace from 'app/assets/images/robotFace.png' -import { Text, Link } from 'app/components/core' -import { makeStyles, shadow } from 'app/styles' - -const AUDIUS_AI_BLOG_LINK = - 'https://help.audius.co/help/What-should-I-know-about-AI-generated-music-on-Audius-0a5a8' - -const messages = { - title: 'Share Your AI-Generated Tracks', - description: - "Join in by uploading your own AI-made tracks! Just mark them as AI-Generated during the upload process and tag the artist you'd like to credit.", - learnMore: 'Learn More' -} - -const useStyles = makeStyles(({ spacing, palette, typography }) => ({ - root: { - marginVertical: spacing(4), - marginHorizontal: spacing(3), - padding: spacing(6), - borderWidth: 1, - borderRadius: spacing(2), - backgroundColor: palette.white, - borderColor: palette.neutralLight7, - ...shadow() - }, - title: { - flexDirection: 'row', - alignItems: 'center', - gap: spacing(4) - }, - robotImage: { - height: spacing(16), - width: spacing(16) - }, - titleText: { - marginRight: spacing(25), - ...typography.h1, - lineHeight: typography.h1.fontSize * 1.3, - marginVertical: spacing(2) - }, - description: { - fontSize: typography.fontSize.medium, - lineHeight: typography.body.fontSize * 1.3, - marginVertical: spacing(4) - }, - learnMoreLink: { - alignSelf: 'flex-start' - }, - learnMore: { - fontSize: typography.fontSize.medium, - lineHeight: typography.body.fontSize * 1.2, - color: palette.secondary - } -})) - -export const ShareAiTracksTile = () => { - const styles = useStyles() - return ( - - - - {messages.title} - - {messages.description} - - {messages.learnMore} - - - ) -} diff --git a/packages/mobile/src/screens/ai-generated-tracks-screen/index.ts b/packages/mobile/src/screens/ai-generated-tracks-screen/index.ts deleted file mode 100644 index 551269dee63..00000000000 --- a/packages/mobile/src/screens/ai-generated-tracks-screen/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './AiGeneratedTracksScreen' diff --git a/packages/mobile/src/screens/app-screen/AppTabScreen.tsx b/packages/mobile/src/screens/app-screen/AppTabScreen.tsx index 6c41c931fba..561cc8bc18b 100644 --- a/packages/mobile/src/screens/app-screen/AppTabScreen.tsx +++ b/packages/mobile/src/screens/app-screen/AppTabScreen.tsx @@ -24,7 +24,6 @@ import { FilterButtonScreen } from '@audius/harmony-native' import type { FilterButtonScreenParams } from '@audius/harmony-native' import { useDrawer } from 'app/hooks/useDrawer' import { setLastNavAction } from 'app/hooks/useNavigation' -import { AiGeneratedTracksScreen } from 'app/screens/ai-generated-tracks-screen' import { AppDrawerContext } from 'app/screens/app-drawer-screen' import { AudioScreen } from 'app/screens/audio-screen' import { ChangeEmailModalScreen } from 'app/screens/change-email-screen/ChangeEmailScreen' @@ -93,7 +92,6 @@ export type AppTabScreenParamList = { Followers: { userId: ID } Following: { userId: ID } Mutuals: { userId: ID } - AiGeneratedTracks: { userId: ID } RelatedArtists: { userId: ID } SupportingUsers: { userId: ID } TopSupporters: { userId: ID; source: TipSource } @@ -222,10 +220,6 @@ export const AppTabScreen = ({ baseScreen, Stack }: AppTabScreenProps) => { - { twitter_handle: twitterHandle, instagram_handle: instagramHandle, tiktok_handle: tikTokHandle, - supporting_count: supportingCount, - allow_ai_attribution + supporting_count: supportingCount } = useProfileUser({ select: (user) => ({ user_id: user.user_id, @@ -61,8 +60,7 @@ export const ProfileHeader = memo(() => { twitter_handle: user.twitter_handle, instagram_handle: user.instagram_handle, tiktok_handle: user.tiktok_handle, - supporting_count: user.supporting_count, - allow_ai_attribution: user.allow_ai_attribution + supporting_count: user.supporting_count }) }).user ?? {} @@ -91,7 +89,6 @@ export const ProfileHeader = memo(() => { hasMutuals || hasMultipleSocials || isSupporting || - allow_ai_attribution || (comments && comments?.length > 0 && isRecentCommentsEnabled) useEffect(() => { diff --git a/packages/mobile/src/screens/profile-screen/ProfileHeader/ProfileInfoTiles.tsx b/packages/mobile/src/screens/profile-screen/ProfileHeader/ProfileInfoTiles.tsx index f407d03021c..b7644206521 100644 --- a/packages/mobile/src/screens/profile-screen/ProfileHeader/ProfileInfoTiles.tsx +++ b/packages/mobile/src/screens/profile-screen/ProfileHeader/ProfileInfoTiles.tsx @@ -24,7 +24,6 @@ import Animated, { import { IconUserFollowing, - IconRobot, IconUserGroup, Text, IconTrophy, @@ -77,7 +76,6 @@ const useInfoTileStyles = makeStyles(({ spacing }) => ({ })) const messages = { - aiGeneratedTracks: 'AI Generated Tracks', comments: 'Comments', mutuals: 'Mutuals', relatedArtists: 'Related Artists', @@ -326,18 +324,17 @@ export const ProfileInfoTiles = () => { user_id, current_user_followee_follow_count, supporting_count, - allow_ai_attribution: hasAiAttribution, supporter_count - } = useProfileUser({ - select: (user) => ({ - supporting_count: user.supporting_count, - supporter_count: user.supporter_count, - current_user_followee_follow_count: - user.current_user_followee_follow_count, - user_id: user.user_id, - allow_ai_attribution: user.allow_ai_attribution - }) - }).user ?? {} + } = + useProfileUser({ + select: (user) => ({ + supporting_count: user.supporting_count, + supporter_count: user.supporter_count, + current_user_followee_follow_count: + user.current_user_followee_follow_count, + user_id: user.user_id + }) + }).user ?? {} const { isEnabled: isRecentCommentsEnabled } = useFeatureFlag( FeatureFlags.RECENT_COMMENTS @@ -433,18 +430,6 @@ export const ProfileInfoTiles = () => { ) : null} - {hasAiAttribution ? ( - - {messages.viewAll} - - } - /> - ) : null} diff --git a/packages/mobile/src/screens/track-screen/TrackScreenDetailsTile.tsx b/packages/mobile/src/screens/track-screen/TrackScreenDetailsTile.tsx index dbfe3a9116b..ad750c7b2e6 100644 --- a/packages/mobile/src/screens/track-screen/TrackScreenDetailsTile.tsx +++ b/packages/mobile/src/screens/track-screen/TrackScreenDetailsTile.tsx @@ -79,7 +79,6 @@ import { Tag } from 'app/components/core' import { DeletedTile } from 'app/components/details-tile/DeletedTile' import { DetailsProgressInfo } from 'app/components/details-tile/DetailsProgressInfo' import { DetailsTileActionButtons } from 'app/components/details-tile/DetailsTileActionButtons' -import { DetailsTileAiAttribution } from 'app/components/details-tile/DetailsTileAiAttribution' import { DetailsTileHasAccess } from 'app/components/details-tile/DetailsTileHasAccess' import { DetailsTileNoAccess } from 'app/components/details-tile/DetailsTileNoAccess' import { DetailsTileStats } from 'app/components/details-tile/DetailsTileStats' @@ -229,7 +228,6 @@ export const TrackScreenDetailsTile = ({ const isLongFormContent = track?.genre === Genre.PODCASTS || track?.genre === Genre.AUDIOBOOKS - const aiAttributionUserId = track?.ai_attribution_user_id const isUSDCPurchaseGated = isContentUSDCPurchaseGated(streamConditions) const { data: remixContest } = useRemixContest(trackId) const isRemixContest = !!remixContest @@ -285,12 +283,6 @@ export const TrackScreenDetailsTile = ({ const trendingRank = useTrackRank(trackId) const badges = [ - aiAttributionUserId ? ( - - ) : null, trendingRank ? ( {trendingRank} diff --git a/packages/mobile/src/store/sagas.ts b/packages/mobile/src/store/sagas.ts index aa7ba61b4fb..8280eb8f980 100644 --- a/packages/mobile/src/store/sagas.ts +++ b/packages/mobile/src/store/sagas.ts @@ -25,7 +25,6 @@ import analyticsSagas from 'common/store/analytics/sagas' import backendSagas from 'common/store/backend/sagas' import tracksSagas from 'common/store/cache/tracks/sagas' import changePasswordSagas from 'common/store/change-password/sagas' -import aiSagas from 'common/store/pages/ai/sagas' import rewardsPageSagas from 'common/store/pages/audio-rewards/sagas' import collectionPageSagas from 'common/store/pages/collection/sagas' import deactivateAccountSagas from 'common/store/pages/deactivate-account/sagas' @@ -126,7 +125,6 @@ export default function* rootSaga() { ...historySagas(), ...rewardsPageSagas(), ...settingsSagas(), - ...aiSagas(), ...premiumTracksSagas(), ...searchTracksLineupSagas(), diff --git a/packages/mobile/src/utils/theme.ts b/packages/mobile/src/utils/theme.ts index 0c8689942b6..8e4623e584a 100644 --- a/packages/mobile/src/utils/theme.ts +++ b/packages/mobile/src/utils/theme.ts @@ -10,8 +10,6 @@ const { getTheme, getSystemAppearance } = themeSelectors export { Theme } from '@audius/common/models' export type ThemeColors = { - aiPrimary: string - aiSecondary: string background: string backgroundSecondary: string backgroundSurface: string @@ -83,8 +81,6 @@ const createMobileThemeFromHarmony = ( const { color } = harmonyTheme return { - aiPrimary: color.special.aiGreen, - aiSecondary: color.special.aiGreen, // No direct mapping, using aiGreen background: color.special.background, backgroundSecondary: color.background.surface1, backgroundSurface: color.background.surface1, diff --git a/packages/web/src/app/web-player/WebPlayer.jsx b/packages/web/src/app/web-player/WebPlayer.jsx index b3bc0ca5331..ae212426adc 100644 --- a/packages/web/src/app/web-player/WebPlayer.jsx +++ b/packages/web/src/app/web-player/WebPlayer.jsx @@ -50,7 +50,6 @@ import TrendingGenreSelectionPage from 'components/trending-genre-selection/Tren import { USDCBalanceFetcher } from 'components/usdc-balance-fetcher/USDCBalanceFetcher' import { useEnvironment } from 'hooks/useEnvironment' import { MAIN_CONTENT_ID, MainContentContext } from 'pages/MainContentContext' -import { AiAttributedTracksPage } from 'pages/ai-attributed-tracks-page' import { ArtistCoinsExplorePage } from 'pages/artist-coins-explore-page/ArtistCoinsExplorePage' import { LaunchpadPage } from 'pages/artist-coins-launchpad-page' import { MobileArtistCoinsSortPage } from 'pages/artist-coins-sort-page/MobileArtistCoinsSortPage' @@ -174,7 +173,6 @@ const { TOP_SUPPORTERS_USERS_ROUTE, publicSiteRoutes, CHAT_PAGE, - PROFILE_PAGE_AI_ATTRIBUTED_TRACKS, PROFILE_PAGE_COMMENTS, PAYMENTS_PAGE, WITHDRAWALS_PAGE, @@ -892,11 +890,6 @@ const WebPlayer = (props) => { path={PROFILE_PAGE_COMMENTS} component={CommentHistoryPage} /> - - `${tracksActions.prefix}:${getAiUserId(state)}` - -class TracksSagas extends LineupSagas { - constructor() { - super( - tracksActions.prefix, - tracksActions, - getLineup, - getTracks, - undefined, - undefined, - sourceSelector - ) - } -} - -export default function sagas() { - return new TracksSagas().getSagas() -} diff --git a/packages/web/src/common/store/pages/ai/sagas.ts b/packages/web/src/common/store/pages/ai/sagas.ts deleted file mode 100644 index 995a351e021..00000000000 --- a/packages/web/src/common/store/pages/ai/sagas.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { queryUser, queryUserByHandle } from '@audius/common/api' -import { User } from '@audius/common/models' -import { aiPageActions, FetchAiUserAction } from '@audius/common/store' -import { Maybe } from '@audius/common/utils' -import { takeEvery, call, put } from 'typed-redux-saga' - -import { waitForRead } from 'utils/sagaHelpers' - -import tracksSagas from './lineups/tracks/sagas' - -const { fetchAiUser, fetchAiUserSucceeded, fetchAiUserFailed } = aiPageActions - -function* watchFetchAiUser() { - yield takeEvery(fetchAiUser.type, fetchAiUserWorker) -} - -function* fetchAiUserWorker(action: FetchAiUserAction) { - yield* call(waitForRead) - const { handle, userId } = action.payload - - let user: Maybe - - if (handle) { - user = yield* call(queryUserByHandle, handle) - } - - if (userId) { - user = yield* call(queryUser, userId) - } - - if (user) { - yield* put(fetchAiUserSucceeded({ userId: user.user_id })) - } else { - yield* put(fetchAiUserFailed()) - } -} - -export default function sagas() { - return [...tracksSagas(), watchFetchAiUser] -} diff --git a/packages/web/src/common/store/pages/settings/sagas.ts b/packages/web/src/common/store/pages/settings/sagas.ts index 2a72d8900f6..a4e192025e4 100644 --- a/packages/web/src/common/store/pages/settings/sagas.ts +++ b/packages/web/src/common/store/pages/settings/sagas.ts @@ -1,8 +1,4 @@ -import { - getUserQueryKey, - queryAccountUser, - queryCurrentUserId -} from '@audius/common/api' +import { queryCurrentUserId } from '@audius/common/api' import { settingsPageActions as actions, getContext, @@ -11,7 +7,6 @@ import { import { getErrorMessage } from '@audius/common/utils' import { call, put, takeEvery } from 'typed-redux-saga' -import { queryClient } from 'services/query-client' import { waitForWrite } from 'utils/sagaHelpers' import errorSagas from './errorSagas' @@ -62,37 +57,6 @@ function* watchUpdateEmailFrequency() { ) } -function* watchSetAiAttribution() { - const audiusBackendInstance = yield* getContext('audiusBackendInstance') - const sdk = yield* getSDK() - yield* takeEvery( - actions.SET_AI_ATTRIBUTION, - function* (action: actions.SetAiAttribution) { - const { allowAiAttribution } = action - const accountUser = yield* call(queryAccountUser) - if (!accountUser) return - if (accountUser.allow_ai_attribution === allowAiAttribution) return - - accountUser.allow_ai_attribution = allowAiAttribution - - yield* call(audiusBackendInstance.updateCreator, { - metadata: accountUser, - sdk - }) - - queryClient.setQueryData(getUserQueryKey(accountUser.user_id), { - ...accountUser, - allow_ai_attribution: allowAiAttribution - }) - } - ) -} - export default function sagas() { - return [ - watchGetSettings, - watchUpdateEmailFrequency, - watchSetAiAttribution, - errorSagas - ] + return [watchGetSettings, watchUpdateEmailFrequency, errorSagas] } diff --git a/packages/web/src/components/ai-attribution-modal/AiAttributionDropdown.tsx b/packages/web/src/components/ai-attribution-modal/AiAttributionDropdown.tsx deleted file mode 100644 index a122ea0fbb9..00000000000 --- a/packages/web/src/components/ai-attribution-modal/AiAttributionDropdown.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { useCallback, useState } from 'react' - -import { imageProfilePicEmpty } from '@audius/common/assets' -import { SquareSizes, Kind } from '@audius/common/models' -import { SelectProps } from 'antd' -import { useDispatch } from 'react-redux' -import { createSelector } from 'reselect' - -import { fetchSearch } from 'common/store/search-ai-bar/actions' -import { getSearchResults } from 'common/store/search-ai-bar/selectors' -import { useSelector } from 'utils/reducer' - -import DropdownInput from './DropdownInput' -import { SearchBarResult } from './SearchBarResult' - -const selectSearchResults = createSelector(getSearchResults, (results) => { - const items = results - .map((user) => ({ - text: user.name, - value: user.user_id, - disabled: !user.allow_ai_attribution, - el: ( - - ) - })) - .filter((item) => item.text) - return { items } -}) - -type AiAttributionDropdownProps = SelectProps & { - error?: string | false - helperText?: string | false -} - -export const AiAttributionDropdown = (props: AiAttributionDropdownProps) => { - const dispatch = useDispatch() - const users = useSelector(selectSearchResults) - const [searchInput, setSearchInput] = useState('') - - const handleSearch = useCallback( - (searchInput: string) => { - dispatch(fetchSearch(searchInput)) - setSearchInput(searchInput) - }, - [dispatch] - ) - - return ( - - ) -} diff --git a/packages/web/src/components/ai-attribution-modal/DropdownInput.jsx b/packages/web/src/components/ai-attribution-modal/DropdownInput.jsx deleted file mode 100644 index 542d516a41a..00000000000 --- a/packages/web/src/components/ai-attribution-modal/DropdownInput.jsx +++ /dev/null @@ -1,184 +0,0 @@ -import { Component } from 'react' - -import { IconCaretDown } from '@audius/harmony' -import Select from 'antd/lib/select' -import cn from 'classnames' -import PropTypes from 'prop-types' - -import { HelperText } from 'components/data-entry/HelperText' - -import styles from './DropdownInput.module.css' - -const Option = Select.Option - -class DropdownInput extends Component { - state = { - focused: false - } - - onVisibleChange = (visible) => { - this.setState({ - focused: visible - }) - } - - onSelect = (value) => { - this.setState({ - focused: false - }) - this.props.onSelect(value) - } - - render() { - const { - 'aria-label': ariaLabel, - menu, - defaultValue, - label, - labelStyle, - dropdownStyle, - dropdownInputStyle, - helperText, - layout, - size, - variant, - disabled, - isRequired, - error, - id, - focused = this.state.focused, - footer, - input, - onSearch, - value - } = this.props - let { placeholder } = this.props - - if (isRequired && placeholder) placeholder = placeholder + ' *' - - const style = { - [styles.horizontal]: layout === 'horizontal', - [styles.vertical]: layout === 'vertical', - [styles.large]: size === 'large', - [styles.medium]: size === 'medium', - [styles.small]: size === 'small', - [styles.alternative]: variant === 'alternative', - [styles.focused]: focused, - [styles.disabled]: disabled, - [styles.error]: error - } - - const options = menu.items.map((item, i) => { - if (item.id && item.text && !item.el) { - return ( - - ) - } else if (item.text && item.el) { - return ( - - ) - } else { - return ( - - ) - } - }) - - // Add dropdown footer if given - if (footer) { - options.push( -
- {footer} -
- ) - } - - let goodDefault = false - menu.items.forEach((item) => { - if (defaultValue === item || defaultValue === item.text) { - goodDefault = true - } - }) - const defaultValueProp = goodDefault - ? { - defaultValue - } - : {} - - return ( -
- {label && !value ? ( - - ) : null} -
- - -
- {helperText ? ( - {helperText} - ) : null} -
- ) - } -} - -DropdownInput.propTypes = { - placeholder: PropTypes.string, - defaultValue: PropTypes.string, - menu: PropTypes.object, - label: PropTypes.string, - labelStyle: PropTypes.string, - dropdownStyle: PropTypes.string, - dropdownInputStyle: PropTypes.string, - size: PropTypes.oneOf(['small', 'medium', 'large']), - layout: PropTypes.oneOf(['horizontal', 'vertical']), - variant: PropTypes.oneOf(['default', 'alternative']), - disabled: PropTypes.bool, - mount: PropTypes.oneOf(['parent', 'page', 'body']), - isRequired: PropTypes.bool, - error: PropTypes.bool, - onSelect: PropTypes.func -} - -export default DropdownInput diff --git a/packages/web/src/components/ai-attribution-modal/DropdownInput.module.css b/packages/web/src/components/ai-attribution-modal/DropdownInput.module.css deleted file mode 100644 index dd460846864..00000000000 --- a/packages/web/src/components/ai-attribution-modal/DropdownInput.module.css +++ /dev/null @@ -1,264 +0,0 @@ -.wrapper { - width: 100%; - display: flex; - position: relative; -} - -.wrapper.horizontal { - flex-direction: row; - align-items: center; -} -.wrapper.horizontal .label { - margin-right: 8px; -} - -.wrapper.vertical { - flex-direction: column; -} -.wrapper.vertical .label { - margin-bottom: 4px; -} - -.label { - z-index: 5; - position: absolute; - pointer-events: none; - top: 16px; - left: 19px; - margin-bottom: 4px; - font-size: var(--harmony-font-l); - line-height: 18px; - font-weight: var(--harmony-font-medium); - color: var(--harmony-n-400); - transition: all 0.3s ease; -} - -.labelFocus { - transform: translate(-3px, -8px); - font-size: var(--harmony-font-s); - line-height: 14px; -} - -.dropdownInput { - position: relative; - width: 100%; - text-align: left; -} - -.dropdownInput > :global(.ant-select) { - width: 100%; - outline: none; - height: 100%; -} - -.wrapper.large > .dropdownInput { - height: 50px; -} -.wrapper.medium > .dropdownInput { - height: 34px; -} -.wrapper.small > .dropdownInput { - height: 24px; -} -.wrapper.large > .dropdownInput > :global(.ant-select) { - font-size: var(--harmony-font-m); -} -.wrapper.medium > .dropdownInput > :global(.ant-select) { - font-size: var(--harmony-font-xs); -} -.wrapper.small > .dropdownInput > :global(.ant-select) { - font-size: var(--harmony-font-xs); -} - -.wrapper > .dropdownInput :global(.ant-select-selection-item), -.wrapper > .dropdownInput :global(.ant-select-selection-search) { - height: 100%; -} -.wrapper.focused > .dropdownInput :global(.ant-select-selection-search) { - padding-top: 8px; -} -.hasValue > .dropdownInput :global(.ant-select-selection-search) { - height: 100%; - padding-top: 0px; -} -.wrapper.large > .dropdownInput :global(.ant-select-selection-item), -.wrapper.large > .dropdownInput :global(.ant-select-selection-search) { - line-height: 48px; -} -.wrapper.medium > .dropdownInput :global(.ant-select-selection-item), -.wrapper.medium > .dropdownInput :global(.ant-select-selection-search) { - line-height: 32px; -} -.wrapper.small > .dropdownInput :global(.ant-select-selection-item), -.wrapper.small > .dropdownInput :global(.ant-select-selection-search) { - line-height: 22px; -} - -.wrapper .dropdownInput :global(.ant-select-selection-search input) { - height: calc(100% - 2px) !important; - font-weight: 500; - color: var(--harmony-neutral); -} -.wrapper.large .dropdownInput :global(.ant-select-selection-search input) { - line-height: 48px; -} -.wrapper.medium .dropdownInput :global(.ant-select-selection-search input) { - line-height: 32px; -} -.wrapper.small .dropdownInput :global(.ant-select-selection-search input) { - line-height: 22px; -} - -.wrapper .dropdownInput :global(.ant-select-selection-search) { - left: 16px; - right: 16px; -} -.wrapper .dropdownInput :global(.ant-select-selector) { - height: 100%; - background-color: var(--harmony-n-25); - border: 1px solid var(--harmony-n-100) !important; - border-radius: 4px; - transition: border ease-in-out 0.1s; - padding: 0 16px; - box-shadow: none !important; -} -.alternative .dropdownInput :global(.ant-select-selector) { - background-color: var(--harmony-white); -} - -.wrapper .dropdownInput:hover :global(.ant-select-selector) { - border-color: var(--harmony-n-200) !important; -} -.wrapper.focused .dropdownInput :global(.ant-select-selector) { - border-color: var(--harmony-secondary) !important; -} -.wrapper.error .dropdownInput :global(.ant-select-selector) { - border-color: var(--harmony-red) !important; -} -.wrapper.error .dropdownInput :global(.ant-select-selector:hover) { - border-color: var(--harmony-dark-red) !important; -} -.wrapper.disabled .dropdownInput :global(.ant-select-selector) { - background-color: var(--harmony-n-100); - cursor: default !important; -} - -.placeholder { - height: 100%; - color: var(--harmony-n-400); - font-weight: 500; -} - -.wrapper.large .placeholder { - line-height: 48px; - font-size: var(--harmony-font-m); -} -.wrapper.medium .placeholder { - line-height: 32px; - font-size: var(--harmony-font-xs); -} -.wrapper.small .placeholder { - line-height: 22px; - font-size: var(--harmony-font-xs); -} - -.arrow { - position: absolute; - top: 50%; - right: 16px; - transform: translateY(-50%); - height: 6px; - width: 10px; - cursor: pointer; -} - -.arrow path { - fill: var(--harmony-n-400); -} - -.dropdownInput :global(.ant-select-selection-item) { - opacity: 1 !important; - position: absolute; - /* This is pretty hacky, but we can't override display: flex here to center since - ant relies on being able to inline style the component to display: none. - */ - - color: var(--harmony-neutral); - font-weight: 500; -} -.wrapper.large .dropdownInput :global(.ant-select-selection-item) { - font-size: var(--harmony-font-m); -} -.wrapper.medium .dropdownInput :global(.ant-select-selection-item) { - font-size: var(--harmony-font-xs); -} -.wrapper.small .dropdownInput :global(.ant-select-selection-item) { - font-size: var(--harmony-font-xs); -} - -/* Dropdown */ -.select { - padding: 8px 0; - border-radius: 6px; -} -.select:has(.footer) { - padding-bottom: 0; -} -.select :global(.rc-virtual-list-holder-inner) { - padding: 0 8px; -} -:global(.ant-select-dropdown) { - background-color: var(--harmony-white); - box-shadow: - 0 0 2px 0 rgba(133, 129, 153, 0.3), - 0 2px 5px -2px rgba(133, 129, 153, 0.3); - animation-duration: 0.18s; -} -.select, -.select > div { - background: var(--harmony-white); -} -:global(.ant-select-dropdown) { - z-index: var(--harmony-layer-popup); - padding: 8px 0; - margin-top: 4px; - text-align: left; - background: var(--harmony-white); -} -.select :global(.ant-select-item) { - min-height: unset; - text-align: left; - padding: 2px 8px; - border-radius: 4px; - font-size: var(--harmony-font-xs); - font-weight: var(--harmony-font-medium); - color: var(--harmony-neutral); - transition: all ease-in-out 0.04s; -} - -.select - :global( - .ant-select-item-option-selected:not(.ant-select-item-option-active) - ) { - background-color: unset; -} - -.select :global(.ant-select-item-option-active), -.select - :global(.ant-select-item-option-selected.ant-select-item-option-active) { - background: var(--harmony-secondary); - color: var(--darkmode-static-white); -} - -.large.select :global(.ant-select-item) { - font-size: var(--harmony-font-m); - line-height: 28px; -} - -.select .footer:global(.ant-select-item-option) { - cursor: default; - margin: 0 -8px; - padding: 0px !important; - background-color: unset; - color: var(--harmony-neutral); -} diff --git a/packages/web/src/components/ai-attribution-modal/SearchBarResult.module.css b/packages/web/src/components/ai-attribution-modal/SearchBarResult.module.css deleted file mode 100644 index f9c18a698ef..00000000000 --- a/packages/web/src/components/ai-attribution-modal/SearchBarResult.module.css +++ /dev/null @@ -1,82 +0,0 @@ -.userInfo { - display: inline-flex; - margin-right: auto; -} - -.imageContainer { - margin-right: 8px; - width: 33px; - height: 33px; - display: flex; - align-items: center; - align-self: center; -} - -.userImageContainerSkeleton { - border-radius: 50%; -} - -.image { - width: 33px; - height: 33px; - display: block; - border-radius: 2px; - border: 1px solid var(--harmony-n-100); - transition: border 0.18 ease-in-out; -} - -.userImage { - border-radius: 50%; -} - -.emptyUserImage { - background-color: var(--default-profile-picture-background); -} - -.textContainer { - display: inline-flex; - flex-direction: column; - justify-content: center; -} - -.disabled { - opacity: 0.4; -} - -.primaryContainer { - display: inline-flex; - align-items: center; - font-family: var(--harmony-font-family); - font-size: var(--harmony-font-xs); - font-weight: var(--harmony-font-medium); - line-height: normal; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.primaryText { - display: inline-block; - max-width: 194px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.secondaryContainer { - color: var(--harmony-neutral); - font-family: var(--harmony-font-family); - font-size: var(--harmony-font-2xs); - font-weight: var(--harmony-font-medium); - line-height: 10px; - margin-top: 4px; - display: flex; -} - -.primaryContainer .verified { - margin-left: 4px; -} - -.secondaryContainer .verified { - margin-left: 4px; -} diff --git a/packages/web/src/components/ai-attribution-modal/SearchBarResult.tsx b/packages/web/src/components/ai-attribution-modal/SearchBarResult.tsx deleted file mode 100644 index 0788d9acf6e..00000000000 --- a/packages/web/src/components/ai-attribution-modal/SearchBarResult.tsx +++ /dev/null @@ -1,182 +0,0 @@ -import { memo, useCallback } from 'react' - -import { imageBlank as placeholderArt } from '@audius/common/assets' -import { useImageSize } from '@audius/common/hooks' -import { - Kind, - Name, - BadgeTier, - SquareSizes, - WidthSizes, - ID -} from '@audius/common/models' -import { Nullable } from '@audius/common/utils' -import { Flex, spacing, Tag } from '@audius/harmony' -import cn from 'classnames' - -import { make } from 'common/store/analytics/actions' -import DynamicImage from 'components/dynamic-image/DynamicImage' -import UserBadges from 'components/user-badges/UserBadges' -import { XShareButton } from 'components/x-share-button/XShareButton' -import { preload } from 'utils/image' - -import styles from './SearchBarResult.module.css' - -const messages = { - disabledTag: 'Ai Attrib. Not Enabled', - tweet: (handle: string) => - `Hey ${handle}, imagine AI generated tracks inspired by your sound! 🤖 Enable AI generated music on @AudiusMusic and see what your fans create using your tunes as their muse.` -} - -type ImageProps = { - kind: Kind - isUser: boolean - id: ID - artwork: any - defaultImage: string - size: SquareSizes | WidthSizes -} - -const Image = memo((props: ImageProps) => { - const { defaultImage, artwork, size, isUser } = props - const { imageUrl } = useImageSize({ - artwork, - targetSize: size, - defaultImage, - preloadImageFn: preload - }) - return ( - - ) -}) - -type SearchBarResultProps = { - kind: Kind - id: ID - userId: number - primary: string - secondary?: string - artwork: any - size: SquareSizes | WidthSizes - defaultImage: string - isVerifiedUser: boolean - tier?: BadgeTier - allowAiAttribution?: boolean - name: string - handle: string -} - -export const SearchBarResult = memo((props: SearchBarResultProps) => { - const { - kind, - id, - userId, - primary, - secondary, - artwork, - size, - defaultImage = placeholderArt, - isVerifiedUser, - tier, - allowAiAttribution, - name, - handle - } = props - const isUser = kind === Kind.USERS - - const handleXShare = useCallback( - (xHandle: string, otherXHandle?: Nullable) => { - const shareText = messages.tweet(xHandle) - const analytics = make(Name.NOTIFICATIONS_CLICK_TIP_SENT_TWITTER_SHARE, { - text: shareText - }) - return { - shareText, - analytics - } - }, - [] - ) - - return ( - - - -
- -
{primary}
- {isUser && ( - - )} -
- {secondary ? ( - - {secondary} - {!isUser && ( - - )} - - ) : null} -
-
- {!allowAiAttribution ? ( - <> - {messages.disabledTag} - - - ) : null} -
- ) -}) diff --git a/packages/web/src/components/ai-attribution-settings-modal/AiAttributionSettingsModal.module.css b/packages/web/src/components/ai-attribution-settings-modal/AiAttributionSettingsModal.module.css deleted file mode 100644 index 90c72e1f005..00000000000 --- a/packages/web/src/components/ai-attribution-settings-modal/AiAttributionSettingsModal.module.css +++ /dev/null @@ -1,55 +0,0 @@ -.root { - width: 720px; -} - -.title { - color: var(--harmony-n-600); - text-transform: uppercase; -} - -.titleIcon path { - fill: var(--harmony-n-600); -} - -.content { - display: inline-flex; - flex-direction: column; - gap: var(--harmony-unit-4); -} - -.switchLabel { - display: inline-flex; - align-items: center; - justify-content: space-between; - width: 100%; -} - -.switchLabelText { - font-size: var(--harmony-font-xl); - font-weight: var(--harmony-font-bold); -} - -.description { - font-size: var(--harmony-font-l); - font-weight: var(--harmony-font-medium); - line-height: 150%; -} - -.markdownFrame { - background: var(--harmony-background); - box-shadow: inset 0px 0px 8px rgba(0, 0, 0, 0.1); - border-radius: 16px; - padding: 24px 24px 0px 24px; - margin-bottom: 24px; -} - -.eula { - border-top: 1px solid rgba(0, 0, 0, 0.08); - border-left: 1px solid rgba(0, 0, 0, 0.08); - border-right: 1px solid rgba(0, 0, 0, 0.08); - border-radius: 16px 16px 0px 0px; - padding: 24px 32px 32px; - background: var(--harmony-white); - scroll-padding-right: 4px; - overflow: scroll; -} diff --git a/packages/web/src/components/ai-attribution-settings-modal/AiAttributionSettingsModal.tsx b/packages/web/src/components/ai-attribution-settings-modal/AiAttributionSettingsModal.tsx deleted file mode 100644 index d14d3c087f6..00000000000 --- a/packages/web/src/components/ai-attribution-settings-modal/AiAttributionSettingsModal.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import { useCallback } from 'react' - -import { useCurrentAccountUser } from '@audius/common/api' -import { settingsPageActions } from '@audius/common/store' -import { - Modal, - ModalContent, - ModalHeader, - ModalTitle, - IconRobot, - Button -} from '@audius/harmony' -import { useDispatch } from 'react-redux' - -import { useModalState } from 'common/hooks/useModalState' -import { MarkdownViewer } from 'components/markdown-viewer' - -import styles from './AiAttributionSettingsModal.module.css' -const { setAiAttribution } = settingsPageActions - -const messages = { - title: 'AI Generated Music Settings', - label: 'Allow AI-generated music based on my likeness', - description1: - 'By opting in, you grant permission for AI models to be trained using your musical likeness, opening up a world of possibilities for you and your fans.', - description2: - ' With this feature enabled, a special section will appear on your profile, showcasing any AI-generated tracks that emulate your sound.', - - disable: 'Disable', - accept: 'Agree & Enable' -} - -const eula = ` -**ARTIST AI AGREEMENT** - -This Artist AI Agreement (the “**Agreement”**) constitutes a legally binding agreement between Tiki Labs, Inc. (“**we**”, “**us**”, or “**our**”) and each Service User that opts to use the AI Service (as defined below). This Agreement form a part of, and a hereby incorporated into, the [Standard Terms](https://audius.co/legal/terms-of-use) and together with all other Ancillary Documents make up the Platform Terms of Use. Capitalized terms used but not defined herein have the meanings given them in the Platform Standard Terms. - -1. **Distribution of AI Tracks**: We will allow Service Users to deliver to us sound recordings, musical works or covers or other works (the “**AI Tracks**”) generated using artificial intelligence or other machine learning technologies (the “**AI Service**”) including, but not limited to: applicable stems of sound recordings, music recording session files, digital audio workstation project files, sound design and instrument settings, the final version(s) of sound recordings, musical compositions, lyrics of the musical compositions, recordings of your voice, photographs or artwork representing your name and likeness, and other such elements of the aforementioned. -2. **Rights and Usage**: - 1. You hereby grant to us a perpetual, non-exclusive, royalty free, worldwide, transferrable, assignable, right and license, to use, reproduce, publish, perform, display and distribute all or any portion of the AI Tracks pursuant to this Agreement. Such license includes, without limitation, a license to your name and likeness, voice, sound recordings and underlying compositions to the extent used in the creation of or training of AI Tracks. - 2. For the purposes of and pursuant to the terms of this Agreement, you hereby waive any and all “moral” rights claims to your voice, name and likeness under applicable law, including, without limitation, as set forth under the Visual Artists Rights Act of 1990 (VARA), the Lanham Act (15 U.S.C. §1051), the General Data Protection Regulation (GDPR), the Data Protection Act 2018 (DPA), the Human Rights Act 1998 (HRA) and the European Convention on Human Rights (ECHR). -3. **Representations, Warranties and Indemnity**: You represent, warrant, covenant, and agree that you are free to enter into and perform this Agreement, and are not and will not be under any disability, restriction or prohibition, contractual or otherwise (including with any record label, distributor, music publisher, or any other third party) with respect to your right to execute this Agreement, grant all of the rights granted to us hereunder, and fully perform each and every term hereof. You agree not to initiate any action, suit or proceeding against us with respect to the validity of the copyright of the AI Tracks (including with respect to the copyrightability of AI-generated elements incorporated therein). You agree to indemnify and hold us and our licensees, employees, affiliates and distributors harmless against any claim, liability, cost and expense in connection with any claim that is inconsistent with any agreement, covenant, representation, or warranty made by you herein. You will reimburse us upon demand for any payment made by us at any time in respect of any claim, liability, damage or expense to which the foregoing indemnity relates. -` - -export const AiAttributionSettingsModal = () => { - const [isOpen, setIsOpen] = useModalState('AiAttributionSettings') - const { data: allowAiAttribution } = useCurrentAccountUser({ - select: (user) => user?.allow_ai_attribution - }) - const dispatch = useDispatch() - - const handleClose = useCallback(() => { - setIsOpen(false) - }, [setIsOpen]) - - const handleSubmit = useCallback(() => { - dispatch(setAiAttribution(!allowAiAttribution)) - handleClose() - }, [dispatch, allowAiAttribution, handleClose]) - - return ( - - - } - /> - - - {messages.description1} - {messages.description2} -
- -
- {allowAiAttribution ? ( - - ) : ( - - )} -
-
- ) -} diff --git a/packages/web/src/components/ai-attribution-settings-modal/index.ts b/packages/web/src/components/ai-attribution-settings-modal/index.ts deleted file mode 100644 index 9cad6c9e3fe..00000000000 --- a/packages/web/src/components/ai-attribution-settings-modal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './AiAttributionSettingsModal' diff --git a/packages/web/src/components/ai-generated-button/AiGeneratedCallout.module.css b/packages/web/src/components/ai-generated-button/AiGeneratedCallout.module.css deleted file mode 100644 index d0c31a842e2..00000000000 --- a/packages/web/src/components/ai-generated-button/AiGeneratedCallout.module.css +++ /dev/null @@ -1,53 +0,0 @@ -.root { - border-radius: 8px; - box-shadow: - 0px 0px 4px rgba(0, 0, 0, 0.04), - 0px 4px 8px rgba(0, 0, 0, 0.06); - background: var(--harmony-white); - overflow: hidden; - display: flex; - flex-direction: column; - align-items: flex-start; - cursor: pointer; -} - -.title { - padding: 10px 4px; - display: flex; - background: linear-gradient( - 180deg, - var(--ai-primary) 0%, - var(--ai-secondary) 100% - ); - align-items: center; - color: var(--harmony-white); - font-weight: var(--harmony-font-bold); - font-size: var(--harmony-font-m); - line-height: 20px; - width: 100%; - display: flex; - justify-content: space-evenly; - border-bottom: 1px solid var(--harmony-n-150); -} - -.body { - margin-bottom: 12px; -} - -.description { - padding: 8px 12px 0px; - font-size: var(--harmony-font-s); - font-weight: var(--harmony-font-medium); - color: var(--harmony-neutral); - line-height: 16px; -} - -.iconRobot { - width: 24px; - height: 24px; - margin-right: 4px; -} - -.iconRobot path { - fill: var(--harmony-white); -} diff --git a/packages/web/src/components/ai-generated-button/AiGeneratedCallout.tsx b/packages/web/src/components/ai-generated-button/AiGeneratedCallout.tsx deleted file mode 100644 index 05637068002..00000000000 --- a/packages/web/src/components/ai-generated-button/AiGeneratedCallout.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import { useCallback } from 'react' - -import { - IconArrowRight as IconArrow, - IconRobot, - PlainButton, - Box -} from '@audius/harmony' -import { useDispatch } from 'react-redux' - -import { push } from 'utils/navigation' -import { profilePageAiAttributedTracks } from 'utils/route' - -import styles from './AiGeneratedCallout.module.css' - -const messages = { - title: 'AI Generated Tracks', - description: 'AI made music, designed to imitate this artist.', - listenNow: 'Listen now' -} - -export const AiGeneratedCallout = ({ handle }: { handle: string }) => { - const dispatch = useDispatch() - - const handleClick = useCallback(() => { - dispatch(push(profilePageAiAttributedTracks(handle))) - }, [dispatch, handle]) - - return ( -
-
- - {messages.title} -
-
-
{messages.description}
- - - {messages.listenNow} - - -
-
- ) -} diff --git a/packages/web/src/components/edit/fields/AdvancedField.tsx b/packages/web/src/components/edit/fields/AdvancedField.tsx index 8d64069a98e..5569ab79fb2 100644 --- a/packages/web/src/components/edit/fields/AdvancedField.tsx +++ b/packages/web/src/components/edit/fields/AdvancedField.tsx @@ -14,7 +14,6 @@ import { Flex, IconCcBy as IconCreativeCommons, IconInfo, - IconRobot, Text } from '@audius/harmony' import cn from 'classnames' @@ -23,7 +22,6 @@ import { get, set } from 'lodash' import { z } from 'zod' import { toFormikValidationSchema } from 'zod-formik-adapter' -import { AiAttributionDropdown } from 'components/ai-attribution-modal/AiAttributionDropdown' import { ContextualMenu, SelectedValue, @@ -48,10 +46,8 @@ import { SwitchRowField } from './SwitchRowField' const { computeLicense, ALL_RIGHTS_RESERVED_TYPE, computeLicenseVariables } = creativeCommons -const IS_AI_ATTRIBUTED = 'isAiAttribution' const BLOCK_THIRD_PARTY_STREAMING = 'blockThirdPartyStreaming' const ALLOWED_API_KEYS = 'allowed_api_keys' -const AI_USER_ID = 'ai_attribution_user_id' const ISRC = 'isrc' const ISWC = 'iswc' const RELEASE_DATE = 'release_date' @@ -92,10 +88,8 @@ const iswcRegex = /^T-?\d{3}.?\d{3}.?\d{3}.?-?\d$/i const AdvancedFormSchema = z .object({ - [IS_AI_ATTRIBUTED]: z.optional(z.boolean()), [BLOCK_THIRD_PARTY_STREAMING]: z.optional(z.boolean()), [ALLOWED_API_KEYS]: z.optional(z.array(z.string()).nullable()), - [AI_USER_ID]: z.optional(z.number().nullable()), [ISRC]: z.optional(z.string().nullable()), [ISWC]: z.optional(z.string().nullable()), [ALLOW_ATTRIBUTION]: z.optional(z.boolean()), @@ -107,10 +101,6 @@ const AdvancedFormSchema = z [COVER_ORIGINAL_ARTIST]: z.optional(z.string().nullable()), [IS_COVER]: z.optional(z.boolean()) }) - .refine((form) => !form[IS_AI_ATTRIBUTED] || form[AI_USER_ID], { - message: messages.aiGenerated.requiredError, - path: [AI_USER_ID] - }) .refine((form) => !form[ISRC] || isrcRegex.test(form[ISRC]), { message: messages.isrc.validError, path: [ISRC] @@ -136,8 +126,6 @@ const getInitialBpm = (bpm: number | null | undefined) => { } export const AdvancedField = ({ isUpload }: AdvancedFieldProps) => { - const [{ value: aiUserId }, _ignored, { setValue: setAiUserId }] = - useTrackField(AI_USER_ID) const [{ value: isrcValue }, _ignored2, { setValue: setIsrc }] = useTrackField(ISRC) const [{ value: releaseDate }, _ignored3, { setValue: setReleaseDate }] = @@ -186,8 +174,6 @@ export const AdvancedField = ({ isUpload }: AdvancedFieldProps) => { const initialValues = useMemo(() => { const initialValues = {} - set(initialValues, AI_USER_ID, aiUserId) - set(initialValues, IS_AI_ATTRIBUTED, !!aiUserId) set(initialValues, ISRC, isrcValue) set(initialValues, ISWC, iswcValue) set(initialValues, ALLOWED_API_KEYS, allowedApiKeys) @@ -203,7 +189,6 @@ export const AdvancedField = ({ isUpload }: AdvancedFieldProps) => { set(initialValues, IS_COVER, isCover) return initialValues as AdvancedFormValues }, [ - aiUserId, isrcValue, iswcValue, allowedApiKeys, @@ -220,11 +205,6 @@ export const AdvancedField = ({ isUpload }: AdvancedFieldProps) => { const onSubmit = useCallback( (values: AdvancedFormValues) => { - if (get(values, IS_AI_ATTRIBUTED)) { - setAiUserId(get(values, AI_USER_ID) ?? aiUserId) - } else { - setAiUserId(null) - } if (get(values, BLOCK_THIRD_PARTY_STREAMING)) { setAllowedApiKeys([env.API_KEY]) } else { @@ -268,8 +248,6 @@ export const AdvancedField = ({ isUpload }: AdvancedFieldProps) => { releaseDate, setIsCommentsDisabled, commentsDisabled, - setAiUserId, - aiUserId, setAllowedApiKeys, setCoverOriginalSongTitle, coverOriginalSongTitle, @@ -305,11 +283,6 @@ export const AdvancedField = ({ isUpload }: AdvancedFieldProps) => { if (iswcValue) { value.push() } - if (aiUserId) { - value.push( - - ) - } if (bpm) { value.push( { ) } - return {value} + return {value} }, [ license, isrcValue, iswcValue, - aiUserId, bpm, musicalKey, commentsDisabled, @@ -374,11 +346,6 @@ const AdvancedModalFields = ({ isUpload }: { isUpload?: boolean }) => { const { isEnabled: isRightsAndCoversEnabled } = useFeatureFlag( FeatureFlags.RIGHTS_AND_COVERS ) - const [aiUserIdField, aiUserHelperFields, { setValue: setAiUserId }] = - useField({ - name: AI_USER_ID, - type: 'select' - }) const [{ value: allowAttribution }] = useField(ALLOW_ATTRIBUTION) const [{ value: commercialUse }] = useField(COMMERCIAL_USE) const [{ value: derivativeWorks }] = useField(DERIVATIVE_WORKS) @@ -399,9 +366,6 @@ const AdvancedModalFields = ({ isUpload }: { isUpload?: boolean }) => { const licenseIcons = computeLicenseIcons(licenseType) - const dropdownHasError = - aiUserHelperFields.touched && aiUserHelperFields.error - const { isEnabled: isCommentsEnabled } = useFeatureFlag( FeatureFlags.COMMENTS_ENABLED ) @@ -639,23 +603,6 @@ const AdvancedModalFields = ({ isUpload }: { isUpload?: boolean }) => { ) : null} - - { - setAiUserId(value ?? null) - }} - /> - - + {'hello'} + {value} {value} diff --git a/packages/web/src/components/track/AiTrackSection.module.css b/packages/web/src/components/track/AiTrackSection.module.css deleted file mode 100644 index 12a76f66233..00000000000 --- a/packages/web/src/components/track/AiTrackSection.module.css +++ /dev/null @@ -1,70 +0,0 @@ -.root { - padding: 18px 24px; - border-top: 1px solid var(--harmony-n-150); -} - -.title { - display: flex; - align-items: center; - justify-content: flex-start; - color: var(--harmony-neutral); - font-weight: var(--harmony-font-bold); - font-size: var(--harmony-font-s); - line-height: 18px; - letter-spacing: 0.05em; - text-transform: uppercase; - margin-bottom: 4px; -} - -.iconRobot { - width: 16px; - height: 16px; - margin-right: 8px; -} - -.iconRobot path { - fill: var(--harmony-neutral); -} - -.description { - display: flex; - font-size: var(--harmony-font-s); - line-height: 17px; - font-weight: var(--harmony-font-medium); - color: var(--harmony-neutral); - margin-bottom: 16px; - text-align: left; -} - -.link { - color: var(--harmony-secondary); - font-size: var(--harmony-font-s); - line-height: 17px; - font-weight: var(--harmony-font-medium); -} - -.link:hover { - cursor: pointer; - text-decoration: underline; -} - -.attributedUser { - margin-left: 4px; - display: flex; - align-items: center; - color: var(--harmony-secondary); -} - -.attributedUser:hover { - color: var(--harmony-secondary); - cursor: pointer; - text-decoration: underline; -} - -.attributedUser:active { - color: var(--harmony-s-500); -} - -.badgeIcon { - margin-left: 4px; -} diff --git a/packages/web/src/components/track/AiTrackSection.tsx b/packages/web/src/components/track/AiTrackSection.tsx deleted file mode 100644 index a16ec3e5927..00000000000 --- a/packages/web/src/components/track/AiTrackSection.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import { useCallback } from 'react' - -import { useUser } from '@audius/common/api' -import { ID, User } from '@audius/common/models' -import { route } from '@audius/common/utils' -import { - IconArrowRight as IconArrow, - IconRobot, - PlainButton -} from '@audius/harmony' -import cn from 'classnames' -import { useDispatch } from 'react-redux' - -import { ArtistPopover } from 'components/artist/ArtistPopover' -import UserBadges from 'components/user-badges/UserBadges' -import { emptyStringGuard } from 'pages/track-page/utils' -import { push } from 'utils/navigation' -import { profilePageAiAttributedTracks } from 'utils/route' - -import styles from './AiTrackSection.module.css' -const { profilePage } = route - -const messages = { - title: 'Generated With AI', - description: 'This song was made by an AI that has been trained to imitate', - viewMore: 'View More' -} - -type AiTrackSectionProps = { - attributedUserId: ID - className?: string - descriptionClassName?: string -} - -export const AiTrackSection = ({ - attributedUserId, - className, - descriptionClassName -}: AiTrackSectionProps) => { - const dispatch = useDispatch() - const { data: user } = useUser(attributedUserId) - - const renderArtist = useCallback( - (entity: User) => ( - -

- dispatch(push(profilePage(emptyStringGuard(entity.handle)))) - } - > - {entity.name} - -

-
- ), - [dispatch] - ) - const handleClickViewMore = useCallback(() => { - dispatch( - push(profilePageAiAttributedTracks(emptyStringGuard(user?.handle))) - ) - }, [dispatch, user]) - - return ( -
-
- - {messages.title} -
-
- {messages.description} - {user ? renderArtist(user) : null} -
- - {messages.viewMore} - -
- ) -} diff --git a/packages/web/src/components/track/GiantTrackTile.tsx b/packages/web/src/components/track/GiantTrackTile.tsx index 7d7529f003c..6426f011d25 100644 --- a/packages/web/src/components/track/GiantTrackTile.tsx +++ b/packages/web/src/components/track/GiantTrackTile.tsx @@ -45,7 +45,6 @@ import { spacing } from '@audius/harmony' import IconCalendarMonth from '@audius/harmony/src/assets/icons/CalendarMonth.svg' -import IconRobot from '@audius/harmony/src/assets/icons/Robot.svg' import IconTrending from '@audius/harmony/src/assets/icons/Trending.svg' import IconVisibilityHidden from '@audius/harmony/src/assets/icons/VisibilityHidden.svg' import { useTheme } from '@emotion/react' @@ -64,7 +63,6 @@ import Tooltip from 'components/tooltip/Tooltip' import { ComponentPlacement } from 'components/types' import { UserGeneratedText } from 'components/user-generated-text' -import { AiTrackSection } from './AiTrackSection' import { CardTitle } from './CardTitle' import { GatedContentSection } from './GatedContentSection' import GiantArtwork from './GiantArtwork' @@ -115,7 +113,6 @@ const messages = { } type GiantTrackTileProps = { - aiAttributionUserId: Nullable artistHandle: string coSign: Nullable credits: string @@ -163,7 +160,6 @@ type GiantTrackTileProps = { } export const GiantTrackTile = ({ - aiAttributionUserId, artistHandle, coSign, description, @@ -615,11 +611,6 @@ export const GiantTrackTile = ({ justifyContent='flex-end' css={{ position: 'absolute', right: 'var(--harmony-unit-6)' }} > - {aiAttributionUserId ? ( - - {messages.generatedWithAi} - - ) : null} {trendingRank ? ( {trendingRank} @@ -651,10 +642,6 @@ export const GiantTrackTile = ({ ) : null} - {aiAttributionUserId ? ( - - ) : null} - -} - -const AiPage = ({ containerRef }: AiPageProps) => { - const isMobile = useIsMobile() - const content = isMobile ? AiPageMobileContent : AiPageDesktopContent - - return {content} -} - -export default AiPage diff --git a/packages/web/src/pages/ai-attributed-tracks-page/AiPageProvider.tsx b/packages/web/src/pages/ai-attributed-tracks-page/AiPageProvider.tsx deleted file mode 100644 index 6eeb461b186..00000000000 --- a/packages/web/src/pages/ai-attributed-tracks-page/AiPageProvider.tsx +++ /dev/null @@ -1,158 +0,0 @@ -import { useEffect, useCallback, ComponentType, RefObject } from 'react' - -import { useUser } from '@audius/common/api' -import { useCurrentTrack } from '@audius/common/hooks' -import { ID } from '@audius/common/models' -import { - lineupSelectors, - aiPageLineupActions as tracksActions, - aiPageActions, - aiPageSelectors, - queueSelectors, - playerSelectors -} from '@audius/common/store' -import { route } from '@audius/common/utils' -import { connect, useSelector } from 'react-redux' -import { useParams } from 'react-router' -import { Dispatch } from 'redux' - -import { LineupVariant } from 'components/lineup/types' -import { AppState } from 'store/types' -import { push as pushRoute } from 'utils/navigation' - -import { AiPageProps as DesktopRemixesPageProps } from './components/desktop/AiPage' -import { AiPageProps as MobileRemixesPageProps } from './components/mobile/AiPage' -const { profilePage } = route - -const { makeGetCurrent } = queueSelectors -const { getPlaying, getBuffering } = playerSelectors -const { getAiUserId, getLineup } = aiPageSelectors -const { fetchAiUser, reset } = aiPageActions -const { makeGetLineupMetadatas } = lineupSelectors - -const messages = { - title: 'AI Generated Tracks' -} - -type OwnProps = { - containerRef: RefObject - children: - | ComponentType - | ComponentType -} - -type mapStateProps = ReturnType -type AiPageProviderProps = OwnProps & - ReturnType & - ReturnType - -const AiPageProvider = ({ - containerRef, - children: Children, - tracks, - fetchAiUser, - currentQueueItem, - isPlaying, - isBuffering, - pause, - play, - loadMore, - goToRoute, - reset, - resetTracks -}: AiPageProviderProps) => { - const { handle } = useParams<{ handle: string }>() - const currentTrack = useCurrentTrack() - const aiUserId = useSelector(getAiUserId) - const { data: user } = useUser(aiUserId) - - useEffect(() => { - fetchAiUser(handle) - }, [fetchAiUser, handle]) - - useEffect(() => { - return function cleanup() { - reset() - resetTracks() - } - }, [reset, resetTracks]) - - const goToArtistPage = useCallback(() => { - if (user) { - goToRoute(profilePage(user?.handle)) - } - }, [goToRoute, user]) - - useEffect(() => { - if (user && !user.allow_ai_attribution) { - goToRoute(profilePage(user?.handle)) - } - }, [user, goToRoute]) - - const getLineupProps = () => { - return { - selfLoad: true, - variant: LineupVariant.MAIN, - containerRef, - lineup: tracks, - playingUid: currentQueueItem.uid, - playingSource: currentQueueItem.source, - playingTrackId: currentTrack?.track_id ?? null, - playing: isPlaying, - buffering: isBuffering, - pauseTrack: pause, - playTrack: play, - actions: tracksActions, - scrollParent: containerRef as any, - loadMore: (offset: number, limit: number) => { - loadMore(offset, limit, { aiUserHandle: handle ?? null }) - } - } - } - - const childProps = { - title: messages.title, - user, - goToArtistPage, - getLineupProps - } - - return -} - -function makeMapStateToProps() { - const getRemixesTracksLineup = makeGetLineupMetadatas(getLineup) - const getCurrentQueueItem = makeGetCurrent() - - const mapStateToProps = (state: AppState) => { - return { - tracks: getRemixesTracksLineup(state), - currentQueueItem: getCurrentQueueItem(state), - isPlaying: getPlaying(state), - isBuffering: getBuffering(state) - } - } - return mapStateToProps -} - -function mapDispatchToProps(dispatch: Dispatch) { - return { - goToRoute: (route: string) => dispatch(pushRoute(route)), - fetchAiUser: (handle: string, userId?: ID) => - dispatch(fetchAiUser({ handle, userId })), - loadMore: ( - offset: number, - limit: number, - payload: { aiUserHandle: string | null } - ) => - dispatch( - tracksActions.fetchLineupMetadatas(offset, limit, false, payload) - ), - pause: () => dispatch(tracksActions.pause()), - play: (uid?: string) => dispatch(tracksActions.play(uid)), - reset: () => dispatch(reset()), - resetTracks: () => dispatch(tracksActions.reset()) - } -} - -export default connect(makeMapStateToProps, mapDispatchToProps)(AiPageProvider) diff --git a/packages/web/src/pages/ai-attributed-tracks-page/components/desktop/AiPage.module.css b/packages/web/src/pages/ai-attributed-tracks-page/components/desktop/AiPage.module.css deleted file mode 100644 index c008be7d856..00000000000 --- a/packages/web/src/pages/ai-attributed-tracks-page/components/desktop/AiPage.module.css +++ /dev/null @@ -1,27 +0,0 @@ -.headerSecondary { - display: inline-flex; - align-items: center; - justify-content: center; - color: var(--harmony-neutral); - font-size: var(--harmony-font-xl); - font-weight: var(--harmony-font-medium); - letter-spacing: 0.71px; -} - -.headerSecondary .iconVerified { - margin-left: 4px; -} - -.headerSecondary .link { - cursor: pointer; - margin: 0px 4px; - color: var(--harmony-secondary); - transition: all 0.18s ease-in-out; - display: flex; - align-items: center; -} - -.headerSecondary .link:hover { - color: var(--harmony-s-500); - text-decoration: underline; -} diff --git a/packages/web/src/pages/ai-attributed-tracks-page/components/desktop/AiPage.tsx b/packages/web/src/pages/ai-attributed-tracks-page/components/desktop/AiPage.tsx deleted file mode 100644 index b6952f56309..00000000000 --- a/packages/web/src/pages/ai-attributed-tracks-page/components/desktop/AiPage.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import { User } from '@audius/common/models' -import { IconRobot } from '@audius/harmony' - -import { Header } from 'components/header/desktop/Header' -import Lineup, { LineupProps } from 'components/lineup/Lineup' -import Page from 'components/page/Page' -import UserBadges from 'components/user-badges/UserBadges' -import { fullAiPage } from 'utils/route' -import { withNullGuard } from 'utils/withNullGuard' - -import styles from './AiPage.module.css' -import { ShareAiTracksTile } from './ShareAiTracksTile' - -const messages = { - aiAttributed: 'Tracks generated with AI trained on music', - by: 'by', - - getDescription: (artistName: string) => - `${messages.aiAttributed} ${messages.by} ${artistName}` -} - -export type AiPageProps = { - title: string - user: User | undefined - getLineupProps: () => LineupProps - goToArtistPage: () => void -} - -const g = withNullGuard(({ user, ...p }: AiPageProps) => user && { ...p, user }) - -const AiPage = g(({ title, user, getLineupProps, goToArtistPage }) => { - const renderHeader = () => ( -
- {messages.aiAttributed} {messages.by} -
- {user.name} - -
- - } - containerStyles={styles.header} - /> - ) - - return ( - - } /> - - ) -}) - -export default AiPage diff --git a/packages/web/src/pages/ai-attributed-tracks-page/components/desktop/ShareAiTracksTile.module.css b/packages/web/src/pages/ai-attributed-tracks-page/components/desktop/ShareAiTracksTile.module.css deleted file mode 100644 index d139a38a009..00000000000 --- a/packages/web/src/pages/ai-attributed-tracks-page/components/desktop/ShareAiTracksTile.module.css +++ /dev/null @@ -1,67 +0,0 @@ -.tile { - border: 1px solid var(--harmony-n-100); - background-color: var(--harmony-white); - box-shadow: - 0 0 1px 0 var(--tile-shadow-1), - 0 1px 0 0 var(--tile-shadow-2), - 0 2px 5px -2px var(--tile-shadow-3); - display: flex; - overflow: hidden; - border-radius: 8px; - transition: all 0.2 ease-in-out; - user-select: none; - margin: 0px auto 12px; - padding: var(--harmony-unit-6); -} - -.content { - display: flex; - flex-direction: column; - row-gap: var(--harmony-unit-4); -} - -.title { - display: flex; - flex-direction: row; - align-items: center; - column-gap: var(--harmony-unit-4); -} - -.robotImage { - height: var(--harmony-unit-16); - width: var(--harmony-unit-16); -} - -.titleTextRoot { - display: inline-flex; - flex-direction: column; - row-gap: var(--harmony-unit-2); -} - -.titleText { - font-size: var(--harmony-font-2xl); - font-weight: var(--harmony-font-bold); - text-align: left; -} - -.description { - font-size: var(--harmony-font-l); - font-weight: var(--harmony-font-medium); - text-align: left; - line-height: 20px; -} - -.learnMore { - /* left-aligns learn-more link with title */ - margin-left: calc(var(--harmony-unit-16) + var(--harmony-unit-4)); - align-self: flex-start; - font-size: var(--harmony-font-m); - font-weight: var(--harmony-font-medium); - color: var(--harmony-secondary); - text-align: left; -} - -.learnMore:active, -.learnMore:hover { - color: var(--harmony-s-500); -} diff --git a/packages/web/src/pages/ai-attributed-tracks-page/components/desktop/ShareAiTracksTile.tsx b/packages/web/src/pages/ai-attributed-tracks-page/components/desktop/ShareAiTracksTile.tsx deleted file mode 100644 index 21bc954fb4f..00000000000 --- a/packages/web/src/pages/ai-attributed-tracks-page/components/desktop/ShareAiTracksTile.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { route } from '@audius/common/utils' - -import RobotFace from 'assets/img/robotFace.png' - -import styles from './ShareAiTracksTile.module.css' - -const { AUDIUS_AI_BLOG_LINK } = route - -const messages = { - title: 'Share Your AI-Generated Tracks', - description: - "Join in by uploading your own AI-made tracks! Just mark them as AI-Generated during the upload process and tag the artist you'd like to credit.", - learnMore: 'Learn More' -} - -export const ShareAiTracksTile = () => { - return ( -
-
-
- ai - - {messages.title} - {messages.description} - -
- - {messages.learnMore} - -
-
- ) -} diff --git a/packages/web/src/pages/ai-attributed-tracks-page/components/mobile/AiPage.module.css b/packages/web/src/pages/ai-attributed-tracks-page/components/mobile/AiPage.module.css deleted file mode 100644 index ac8c29d0ac0..00000000000 --- a/packages/web/src/pages/ai-attributed-tracks-page/components/mobile/AiPage.module.css +++ /dev/null @@ -1,60 +0,0 @@ -.header > * { - display: flex; - align-items: center; -} - -.iconRobot { - height: 24px; - width: 24px; - margin-right: 8px; -} - -.subHeader { - padding: var(--harmony-unit-3) var(--harmony-unit-6); - text-align: left; - margin: 0px calc(var(--harmony-unit-3) * -1); - display: flex; - flex-direction: column; - justify-content: flex-start; - margin-bottom: 10px; - background-color: var(--harmony-white); - font-weight: var(--harmony-font-medium); - font-size: var(--harmony-font-m); - line-height: 130%; - box-shadow: - 0px 0px 4px rgba(0, 0, 0, 0.04), - 0px 4px 8px rgba(0, 0, 0, 0.06); -} - -.user { - display: inline-flex; - align-items: center; - flex-wrap: wrap; - justify-content: center; - color: var(--harmony-neutral); - font-size: var(--harmony-font-m); - font-weight: var(--harmony-font-medium); - letter-spacing: 0.57px; - line-height: 20px; -} - -.iconVerified { - margin-left: 4px; -} - -.link { - margin: 0 4px 0 0; - color: var(--harmony-secondary); - display: flex; - align-items: center; -} - -.container { - padding: 0px 12px; - width: 100%; -} - -.tracksContainer { - width: 100%; - padding-top: 48px; -} diff --git a/packages/web/src/pages/ai-attributed-tracks-page/components/mobile/AiPage.tsx b/packages/web/src/pages/ai-attributed-tracks-page/components/mobile/AiPage.tsx deleted file mode 100644 index 81cdbf2d149..00000000000 --- a/packages/web/src/pages/ai-attributed-tracks-page/components/mobile/AiPage.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { useEffect, useContext } from 'react' - -import { User } from '@audius/common/models' -import { IconRobot } from '@audius/harmony' -import cn from 'classnames' - -import Header from 'components/header/mobile/Header' -import { HeaderContext } from 'components/header/mobile/HeaderContextProvider' -import Lineup, { LineupProps } from 'components/lineup/Lineup' -import MobilePageContainer from 'components/mobile-page-container/MobilePageContainer' -import { useSubPageHeader } from 'components/nav/mobile/NavContext' -import UserBadges from 'components/user-badges/UserBadges' -import { fullAiPage } from 'utils/route' -import { isMatrix } from 'utils/theme/theme' -import { withNullGuard } from 'utils/withNullGuard' - -import styles from './AiPage.module.css' -import { ShareAiTracksTile } from './ShareAiTracksTile' - -const messages = { - aiAttributed: 'Tracks generated with AI trained on music', - by: 'by', - getDescription: (artistName: string) => - `${messages.aiAttributed} ${messages.by} ${artistName}` -} - -export type AiPageProps = { - title: string - user: User | undefined - getLineupProps: () => LineupProps - goToArtistPage: () => void -} - -const g = withNullGuard(({ user, ...p }: AiPageProps) => user && { ...p, user }) - -const AiPage = g(({ title, user, getLineupProps, goToArtistPage }) => { - useSubPageHeader() - - const { setHeader } = useContext(HeaderContext) - useEffect(() => { - setHeader( - <> -
- - {title} - - } - /> - - ) - }, [setHeader, title]) - - return ( - -
-
- {messages.aiAttributed} {messages.by} - - {user.name} - - -
- } /> -
-
- ) -}) - -export default AiPage diff --git a/packages/web/src/pages/ai-attributed-tracks-page/components/mobile/ShareAiTracksTile.module.css b/packages/web/src/pages/ai-attributed-tracks-page/components/mobile/ShareAiTracksTile.module.css deleted file mode 100644 index 2d32909de43..00000000000 --- a/packages/web/src/pages/ai-attributed-tracks-page/components/mobile/ShareAiTracksTile.module.css +++ /dev/null @@ -1,59 +0,0 @@ -.tile { - border: 1px solid var(--harmony-n-100); - background-color: var(--harmony-white); - box-shadow: - 0 0 1px 0 var(--tile-shadow-1), - 0 1px 0 0 var(--tile-shadow-2), - 0 2px 5px -2px var(--tile-shadow-3); - display: flex; - overflow: hidden; - border-radius: 8px; - transition: all 0.2 ease-in-out; - user-select: none; - margin: 0px auto 12px; - padding: var(--harmony-unit-6); -} - -.content { - display: flex; - flex-direction: column; - row-gap: var(--harmony-unit-4); -} - -.title { - display: flex; - flex-direction: row; - align-items: center; - column-gap: var(--harmony-unit-4); -} - -.robotImage { - height: var(--harmony-unit-16); - width: var(--harmony-unit-16); -} - -.titleText { - font-size: var(--harmony-font-l); - font-weight: var(--harmony-font-bold); - text-align: left; -} - -.description { - font-size: var(--harmony-font-m); - font-weight: var(--harmony-font-medium); - text-align: left; - line-height: 20px; -} - -.learnMore { - font-size: var(--harmony-font-m); - font-weight: var(--harmony-font-medium); - color: var(--harmony-secondary); - text-align: left; - align-self: flex-start; -} - -.learnMore:active, -.learnMore:hover { - color: var(--harmony-s-500); -} diff --git a/packages/web/src/pages/ai-attributed-tracks-page/components/mobile/ShareAiTracksTile.tsx b/packages/web/src/pages/ai-attributed-tracks-page/components/mobile/ShareAiTracksTile.tsx deleted file mode 100644 index 9e3b4539ba7..00000000000 --- a/packages/web/src/pages/ai-attributed-tracks-page/components/mobile/ShareAiTracksTile.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { route } from '@audius/common/utils' - -import RobotFace from 'assets/img/robotFace.png' - -import styles from './ShareAiTracksTile.module.css' - -const { AUDIUS_AI_BLOG_LINK } = route - -const messages = { - title: 'Share Your AI-Generated Tracks', - description: - "Join in by uploading your own AI-made tracks! Just mark them as AI-Generated during the upload process and tag the artist you'd like to credit.", - learnMore: 'Learn More' -} - -export const ShareAiTracksTile = () => { - return ( -
-
-
- ai - {messages.title} -
- {messages.description} - - {messages.learnMore} - -
-
- ) -} diff --git a/packages/web/src/pages/ai-attributed-tracks-page/index.ts b/packages/web/src/pages/ai-attributed-tracks-page/index.ts deleted file mode 100644 index c2d4274df72..00000000000 --- a/packages/web/src/pages/ai-attributed-tracks-page/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as AiAttributedTracksPage } from './AiPage' diff --git a/packages/web/src/pages/modals/Modals.tsx b/packages/web/src/pages/modals/Modals.tsx index 65531e018ef..98eb267557c 100644 --- a/packages/web/src/pages/modals/Modals.tsx +++ b/packages/web/src/pages/modals/Modals.tsx @@ -5,7 +5,6 @@ import { Modals as ModalTypes } from '@audius/common/store' import { CoinSuccessModal } from 'components/CoinSuccessModal' import { AddCashModal } from 'components/add-cash-modal/AddCashModal' import AddToCollectionModal from 'components/add-to-collection/desktop/AddToCollectionModal' -import { AiAttributionSettingsModal } from 'components/ai-attribution-settings-modal' import { AlbumTrackRemoveConfirmationModal } from 'components/album-track-remove-confirmation-modal/AlbumTrackRemoveConfirmationModal' import AppCTAModal from 'components/app-cta-modal/AppCTAModal' import { ArtistPickModal } from 'components/artist-pick-modal/ArtistPickModal' @@ -116,7 +115,6 @@ const commonModalsMap: { [Modal in ModalTypes]?: ComponentType } = { ClaimAllRewards: ClaimAllRewardsModal, TransferAudioMobileWarning: TransferAudioMobileDrawer, BrowserPushPermissionConfirmation: BrowserPushConfirmationModal, - AiAttributionSettings: AiAttributionSettingsModal, Welcome: WelcomeModal, PremiumContentPurchaseModal, LeavingAudiusModal, diff --git a/packages/web/src/pages/profile-page/ProfilePage.test.tsx b/packages/web/src/pages/profile-page/ProfilePage.test.tsx index 259fd088b75..c06307e32a7 100644 --- a/packages/web/src/pages/profile-page/ProfilePage.test.tsx +++ b/packages/web/src/pages/profile-page/ProfilePage.test.tsx @@ -79,8 +79,7 @@ const nonArtistUser = { created_at: '2024-01-01T00:00:00.000Z', updated_at: '2024-01-01T00:00:00.000Z', is_storage_v2: true, - handle_lc: 'test-user', - allow_ai_attribution: false + handle_lc: 'test-user' } const artistUser = { @@ -118,8 +117,7 @@ const artistUser = { created_at: '2024-01-01T00:00:00.000Z', updated_at: '2024-01-01T00:00:00.000Z', is_storage_v2: true, - handle_lc: 'test-user', - allow_ai_attribution: false + handle_lc: 'test-user' } const mockData = { diff --git a/packages/web/src/pages/profile-page/components/desktop/ProfileLeftNav.tsx b/packages/web/src/pages/profile-page/components/desktop/ProfileLeftNav.tsx index 6bb13d35f72..780f764260b 100644 --- a/packages/web/src/pages/profile-page/components/desktop/ProfileLeftNav.tsx +++ b/packages/web/src/pages/profile-page/components/desktop/ProfileLeftNav.tsx @@ -4,7 +4,6 @@ import { ID } from '@audius/common/models' import { FeatureFlags } from '@audius/common/services' import { Box, Flex, Text } from '@audius/harmony' -import { AiGeneratedCallout } from 'components/ai-generated-button/AiGeneratedCallout' import Input from 'components/data-entry/Input' import TextArea from 'components/data-entry/TextArea' import { TipAudioButton } from 'components/tipping/tip-audio/TipAudioButton' @@ -41,7 +40,6 @@ type ProfileLeftNavProps = { editMode: boolean loading: boolean isDeactivated: boolean - allowAiAttribution: boolean twitterHandle: string onUpdateTwitterHandle: (handle: string) => void instagramHandle: string @@ -71,7 +69,6 @@ export const ProfileLeftNav = (props: ProfileLeftNavProps) => { editMode, loading, isDeactivated, - allowAiAttribution, twitterHandle, onUpdateTwitterHandle, instagramHandle, @@ -232,7 +229,6 @@ export const ProfileLeftNav = (props: ProfileLeftNavProps) => { - {allowAiAttribution ? : null} {isArtist ? : null} {showUploadChip ? ( diff --git a/packages/web/src/pages/profile-page/components/desktop/ProfilePage.tsx b/packages/web/src/pages/profile-page/components/desktop/ProfilePage.tsx index 0648ff0aef6..24adc130e35 100644 --- a/packages/web/src/pages/profile-page/components/desktop/ProfilePage.tsx +++ b/packages/web/src/pages/profile-page/components/desktop/ProfilePage.tsx @@ -668,7 +668,6 @@ const ProfilePage = ({ handle={handle} bio={bio} location={location} - allowAiAttribution={!!profile?.allow_ai_attribution} twitterHandle={twitterHandle} instagramHandle={instagramHandle} tikTokHandle={tikTokHandle} diff --git a/packages/web/src/pages/settings-page/components/desktop/SettingsPage.module.css b/packages/web/src/pages/settings-page/components/desktop/SettingsPage.module.css index 860e4a7e506..aab687601f6 100644 --- a/packages/web/src/pages/settings-page/components/desktop/SettingsPage.module.css +++ b/packages/web/src/pages/settings-page/components/desktop/SettingsPage.module.css @@ -51,12 +51,6 @@ fill: var(--harmony-static-white); } -.aiAttributionEnabled { - color: var(--harmony-green); - font-size: var(--harmony-font-s); - font-weight: var(--harmony-font-medium); -} - .showPrivateKey { line-height: var(--harmony-unit-5); } diff --git a/packages/web/src/pages/settings-page/components/desktop/SettingsPage.tsx b/packages/web/src/pages/settings-page/components/desktop/SettingsPage.tsx index 1bb60900719..d86d3a42ce9 100644 --- a/packages/web/src/pages/settings-page/components/desktop/SettingsPage.tsx +++ b/packages/web/src/pages/settings-page/components/desktop/SettingsPage.tsx @@ -32,7 +32,6 @@ import { IconMessages, IconNotificationOn as IconNotification, IconReceive, - IconRobot, IconSettings, IconSignOut, IconVerified, @@ -159,9 +158,6 @@ export const SettingsPage = () => { ) const [, setIsInboxSettingsModalVisible] = useModalState('InboxSettings') const [, setIsCommentSettingsModalVisible] = useModalState('CommentSettings') - const [, setIsAIAttributionSettingsModalVisible] = useModalState( - 'AiAttributionSettings' - ) useEffect(() => { dispatch(getNotificationSettings()) @@ -246,10 +242,6 @@ export const SettingsPage = () => { setIsCommentSettingsModalVisible(true) }, [setIsCommentSettingsModalVisible]) - const openAiAttributionSettingsModal = useCallback(() => { - setIsAIAttributionSettingsModalVisible(true) - }, [setIsAIAttributionSettingsModalVisible]) - const onTwitterLogin = useCallback( (uuid: string, profile: TwitterProfile) => dispatch(accountActions.twitterLogin({ uuid, profile })), @@ -369,9 +361,6 @@ export const SettingsPage = () => { return options }, [showMatrix]) - const { data: allowAiAttribution } = useCurrentAccountUser({ - select: (user) => user?.allow_ai_attribution - }) const { isEnabled: isCommentsEnabled } = useFlag( FeatureFlags.COMMENTS_ENABLED ) @@ -517,24 +506,6 @@ export const SettingsPage = () => { - } - title={settingsMessages.aiGeneratedCardTitle} - description={settingsMessages.aiGeneratedCardDescription} - > - {allowAiAttribution ? ( - - {settingsMessages.aiGeneratedEnabled} - - ) : null} - - {isDownloadDesktopEnabled ? ( } diff --git a/packages/web/src/pages/track-page/components/desktop/TrackPage.tsx b/packages/web/src/pages/track-page/components/desktop/TrackPage.tsx index 78cd604eed6..d6dadde9fad 100644 --- a/packages/web/src/pages/track-page/components/desktop/TrackPage.tsx +++ b/packages/web/src/pages/track-page/components/desktop/TrackPage.tsx @@ -106,7 +106,6 @@ const TrackPage = ({ previewing={previewing} trackTitle={defaults.title} trackId={defaults.trackId} - aiAttributionUserId={defaults.aiAttributionUserId} userId={user?.user_id ?? 0} artistHandle={emptyStringGuard(user?.handle)} tags={defaults.tags} diff --git a/packages/web/src/pages/track-page/components/mobile/TrackHeader.tsx b/packages/web/src/pages/track-page/components/mobile/TrackHeader.tsx index 10be614f19d..bfaa0b32082 100644 --- a/packages/web/src/pages/track-page/components/mobile/TrackHeader.tsx +++ b/packages/web/src/pages/track-page/components/mobile/TrackHeader.tsx @@ -27,7 +27,6 @@ import { IconArtistCoin } from '@audius/harmony' import IconCalendarMonth from '@audius/harmony/src/assets/icons/CalendarMonth.svg' -import IconRobot from '@audius/harmony/src/assets/icons/Robot.svg' import IconTrending from '@audius/harmony/src/assets/icons/Trending.svg' import IconVisibilityHidden from '@audius/harmony/src/assets/icons/VisibilityHidden.svg' import cn from 'classnames' @@ -36,7 +35,6 @@ import { useDispatch } from 'react-redux' import { DownloadMobileAppDrawer } from 'components/download-mobile-app-drawer/DownloadMobileAppDrawer' import { UserLink } from 'components/link' import { SearchTag } from 'components/search-bar/SearchTag' -import { AiTrackSection } from 'components/track/AiTrackSection' import { GatedContentSection } from 'components/track/GatedContentSection' import { TrackArtwork } from 'components/track/TrackArtwork' import { TrackDogEar } from 'components/track/TrackDogEar' @@ -134,7 +132,6 @@ type TrackHeaderProps = { isRemix: boolean fieldVisibility: FieldVisibility coSign: Remix | null - aiAttributedUserId: Nullable onClickMobileOverflow: ( trackId: ID, overflowActions: OverflowAction[] @@ -174,7 +171,6 @@ const TrackHeader = ({ commentCount, commentsDisabled, tags, - aiAttributedUserId, onPlay, onPreview, onShare, @@ -348,11 +344,6 @@ const TrackHeader = ({ {renderHeaderText()} - {aiAttributedUserId ? ( - - {messages.generatedWithAi} - - ) : null} {trendingRank ? ( {trendingRank} @@ -442,13 +433,6 @@ const TrackHeader = ({ onClickReposts={onClickReposts} onClickComments={onClickComments} /> - {aiAttributedUserId ? ( - - ) : null} {description ? ( diff --git a/packages/web/src/pages/track-page/utils.ts b/packages/web/src/pages/track-page/utils.ts index 6947a1731b6..ace844b4a4f 100644 --- a/packages/web/src/pages/track-page/utils.ts +++ b/packages/web/src/pages/track-page/utils.ts @@ -37,7 +37,6 @@ export const getTrackDefaults = (heroTrack: Track | null) => ({ isDownloadGated: heroTrack?.is_download_gated ?? false, downloadConditions: heroTrack?.download_conditions ?? null, isPublishing: heroTrack?._is_publishing ?? false, - aiAttributionUserId: heroTrack?.ai_attribution_user_id ?? null, allowedApiKeys: heroTrack?.allowed_api_keys ?? null, fieldVisibility: { ...defaultFieldVisibility, diff --git a/packages/web/src/store/sagas.ts b/packages/web/src/store/sagas.ts index 1038b2715e7..8bdd4ae99b7 100644 --- a/packages/web/src/store/sagas.ts +++ b/packages/web/src/store/sagas.ts @@ -28,7 +28,6 @@ import backendSagas from 'common/store/backend/sagas' import collectionsSagas from 'common/store/cache/collections/webSagas' import tracksSagas from 'common/store/cache/tracks/sagas' import changePasswordSagas from 'common/store/change-password/sagas' -import aiSagas from 'common/store/pages/ai/sagas' import rewardsPageSagas from 'common/store/pages/audio-rewards/sagas' import collectionSagas from 'common/store/pages/collection/sagas' import deactivateAccountSagas from 'common/store/pages/deactivate-account/sagas' @@ -94,7 +93,6 @@ export default function* rootSaga() { signOutSagas(), // Pages - aiSagas(), collectionSagas(), chatSagas(), dashboardSagas(), @@ -189,7 +187,6 @@ export function* testRootSaga() { // signOutSagas(), // Pages - // aiSagas(), // collectionSagas(), // chatSagas(), // dashboardSagas(),