diff --git a/package-lock.json b/package-lock.json index fac5fb4f8c..ab49edc2e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1622,6 +1622,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-4.2.0.tgz", "integrity": "sha512-xoBtGl5R9jeKUhc8ZqeYaRDx04qqJ10yhhXYGmJ4Jr8qKpvMsDQQrNUvF/wUJ4klOtmJeJM+p2Xo3zp9uaC3tw==", + "dev": true, "requires": { "keyv": "*" } @@ -4674,7 +4675,8 @@ "json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true }, "json-parse-better-errors": { "version": "1.0.2", @@ -4783,6 +4785,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.0.tgz", "integrity": "sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA==", + "dev": true, "requires": { "json-buffer": "3.0.1" } diff --git a/package.json b/package.json index 587667a5c3..b4b8653528 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "stems": "cd packages/stems && npm run start" }, "devDependencies": { + "@types/keyv": "4.2.0", "@typescript-eslint/eslint-plugin": "5.40.0", "@typescript-eslint/parser": "5.40.0", "concurrently": "7.4.0", @@ -55,7 +56,6 @@ "wait-on": "6.0.1" }, "dependencies": { - "@escape.tech/mookme": "2.2.0", - "@types/keyv": "^4.2.0" + "@escape.tech/mookme": "2.2.0" } } diff --git a/packages/common/src/models/User.ts b/packages/common/src/models/User.ts index cdc8bf28b9..34eb215c71 100644 --- a/packages/common/src/models/User.ts +++ b/packages/common/src/models/User.ts @@ -10,6 +10,7 @@ import { Timestamped } from './Timestamped' export type UserMetadata = { album_count: number + artist_pick_track_id: number | null, bio: string | null cover_photo: Nullable creator_node_endpoint: Nullable diff --git a/packages/common/src/schemas/index.ts b/packages/common/src/schemas/index.ts index e5a58fd8c4..e1172167cc 100644 --- a/packages/common/src/schemas/index.ts +++ b/packages/common/src/schemas/index.ts @@ -113,7 +113,8 @@ const userMetadataSchema = { collectibles: null, playlist_library: null, events: null, - is_deactivated: false + is_deactivated: false, + artist_pick_track_id: null } export const newUserMetadata = (fields?: any, validate = false) => { diff --git a/packages/common/src/services/audius-api-client/types.ts b/packages/common/src/services/audius-api-client/types.ts index d1b1b03e6f..f004af7e80 100644 --- a/packages/common/src/services/audius-api-client/types.ts +++ b/packages/common/src/services/audius-api-client/types.ts @@ -22,6 +22,7 @@ export type OpaqueID = string export type APIUser = { album_count: number + artist_pick_track_id: Nullable blocknumber: number balance: string associated_wallets_balance: string diff --git a/packages/common/src/services/audius-backend/AudiusBackend.ts b/packages/common/src/services/audius-backend/AudiusBackend.ts index 5809d2b558..c65cf85815 100644 --- a/packages/common/src/services/audius-backend/AudiusBackend.ts +++ b/packages/common/src/services/audius-backend/AudiusBackend.ts @@ -2158,11 +2158,23 @@ export const audiusBackend = ({ /** * Sets the artist pick for a user + * @param {User} userMetadata + * @param {number} userId * @param {number?} trackId if null, unsets the artist pick */ - async function setArtistPick(trackId: Nullable = null) { + async function setArtistPick( + userMetadata: User, + userId: ID, + trackId: Nullable = null + ) { await waitForLibsInit() try { + // Dual write to the artist_pick_track_id field in the + // users table in the discovery DB. Part of the migration + // of the artist pick feature from the identity service + // to the entity manager in discovery. + updateCreator(userMetadata, userId) + const { data, signature } = await signData() return await fetch(`${identityServiceUrl}/artist_pick`, { method: 'POST', diff --git a/packages/web/src/common/store/cache/tracks/sagas.js b/packages/web/src/common/store/cache/tracks/sagas.js index 0480da1e1a..6eac02ec98 100644 --- a/packages/web/src/common/store/cache/tracks/sagas.js +++ b/packages/web/src/common/store/cache/tracks/sagas.js @@ -338,15 +338,19 @@ function* deleteTrackAsync(action) { handle ) if (socials.pinnedTrackId === action.trackId) { - yield call(audiusBackendInstance.setArtistPick) yield put( cacheActions.update(Kind.USERS, [ { id: userId, - metadata: { _artist_pick: null } + metadata: { + artist_pick_track_id: null, + _artist_pick: null + } } ]) ) + const user = yield call(waitForValue, getUser, { id: userId }) + yield call(audiusBackendInstance.setArtistPick, user, userId) } const track = yield select(getTrack, { id: action.trackId }) diff --git a/packages/web/src/common/store/cache/users/sagas.js b/packages/web/src/common/store/cache/users/sagas.js index e77cbaa2c7..930f2df9c6 100644 --- a/packages/web/src/common/store/cache/users/sagas.js +++ b/packages/web/src/common/store/cache/users/sagas.js @@ -407,7 +407,8 @@ export function* fetchUserSocials({ handle }) { tiktok_handle: socials.tikTokHandle || null, website: socials.website || null, donation: socials.donation || null, - _artist_pick: socials.pinnedTrackId || null + _artist_pick: socials.pinnedTrackId || null, + artist_pick_track_id: socials.pinnedTrackId || null } } ]) diff --git a/packages/web/src/common/store/social/tracks/sagas.ts b/packages/web/src/common/store/social/tracks/sagas.ts index 183170867c..85f3a96180 100644 --- a/packages/web/src/common/store/social/tracks/sagas.ts +++ b/packages/web/src/common/store/social/tracks/sagas.ts @@ -540,15 +540,25 @@ export function* watchSetArtistPick() { function* (action: ReturnType) { yield* waitForAccount() const userId = yield* select(getUserId) + if (!userId) return yield* put( cacheActions.update(Kind.USERS, [ { id: userId, - metadata: { _artist_pick: action.trackId } + metadata: { + artist_pick_track_id: action.trackId, + _artist_pick: action.trackId + } } ]) ) - yield* call(audiusBackendInstance.setArtistPick, action.trackId) + const user = yield* call(waitForValue, getUser, { id: userId }) + yield* call( + audiusBackendInstance.setArtistPick, + user, + userId, + action.trackId + ) const event = make(Name.ARTIST_PICK_SELECT_TRACK, { id: action.trackId }) yield* put(event) @@ -561,15 +571,20 @@ export function* watchUnsetArtistPick() { yield* takeEvery(socialActions.UNSET_ARTIST_PICK, function* (action) { yield* waitForAccount() const userId = yield* select(getUserId) + if (!userId) return yield* put( cacheActions.update(Kind.USERS, [ { id: userId, - metadata: { _artist_pick: null } + metadata: { + artist_pick_track_id: null, + _artist_pick: null + } } ]) ) - yield* call(audiusBackendInstance.setArtistPick) + const user = yield* call(waitForValue, getUser, { id: userId }) + yield* call(audiusBackendInstance.setArtistPick, user, userId) const event = make(Name.ARTIST_PICK_SELECT_TRACK, { id: 'none' }) yield* put(event)