Skip to content

Commit

Permalink
[C-2327] Add playlist updates slice (#3063)
Browse files Browse the repository at this point in the history
  • Loading branch information
dylanjeffers committed Mar 21, 2023
1 parent 59862ad commit 35d1124
Show file tree
Hide file tree
Showing 12 changed files with 167 additions and 2 deletions.
11 changes: 11 additions & 0 deletions packages/common/src/services/audius-api-client/AudiusAPIClient.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { AudiusLibs } from '@audius/sdk/dist/native-libs'

import { PlaylistUpdate } from 'store/playlist-updates'

import {
ID,
TimeRange,
Expand Down Expand Up @@ -77,6 +79,8 @@ const FULL_ENDPOINT_MAP = {
`/playlists/${playlistId}/reposts`,
playlistFavoriteUsers: (playlistId: OpaqueID) =>
`/playlists/${playlistId}/favorites`,
playlistUpdates: (userId: OpaqueID) =>
`/notifications/${userId}/playlist_updates`,
getUser: (userId: OpaqueID) => `/users/${userId}`,
userByHandle: (handle: OpaqueID) => `/users/handle/${handle}`,
userTracksByHandle: (handle: OpaqueID) => `/users/handle/${handle}/tracks`,
Expand Down Expand Up @@ -1726,6 +1730,13 @@ export class AudiusAPIClient {
return response ? response.data : null
}

async getPlaylistUpdates(userId: number) {
const response = await this._getResponse<APIResponse<PlaylistUpdate[]>>(
FULL_ENDPOINT_MAP.playlistUpdates(encodeHashId(userId))
)
return response?.data
}

async init() {
if (this.initializationState.state === 'initialized') return

Expand Down
1 change: 1 addition & 0 deletions packages/common/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ export * from './remix-settings'
export * from './premium-content'
export * from './collectibles'
export * from './solana'
export * from './playlist-updates'
8 changes: 8 additions & 0 deletions packages/common/src/store/playlist-updates/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export {
actions as playlistUpdatesActions,
default as playlistUpdatesReducer
} from './playlistUpdatesSlice'

export * as playlistUpdatesSelectors from './playlistUpdatesSelectors'
export { default as playlistUpdatesSagas } from './playlistUpdatesSagas'
export * from './types'
50 changes: 50 additions & 0 deletions packages/common/src/store/playlist-updates/playlistUpdatesSagas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { call, takeEvery, select, put } from 'typed-redux-saga'

import { getContext } from 'store/effects'

import { getUserId } from '../account/selectors'

import {
fetchPlaylistUpdates,
playlistUpdatesReceived,
updatedPlaylistViewed
} from './playlistUpdatesSlice'
import { UpdatedPlaylistViewedAction } from './types'

function* watchFetchPlaylistUpdates() {
yield* takeEvery(
fetchPlaylistUpdates,
function* fetchPlaylistUpdatesWorker() {
const currentUserId = yield* select(getUserId)
if (!currentUserId) return

const apiClient = yield* getContext('apiClient')

const playlistUpdates = yield* call(
[apiClient, apiClient.getPlaylistUpdates],
currentUserId
)

if (playlistUpdates && playlistUpdates.length > 0) {
yield* put(playlistUpdatesReceived({ playlistUpdates }))
}
}
)
}

function* watchUpdatedPlaylistViewedSaga() {
yield* takeEvery(
updatedPlaylistViewed.type,
function* updatePlaylistLastViewedAt(action: UpdatedPlaylistViewedAction) {
const audiusBackendInstance = yield* getContext('audiusBackendInstance')
yield* call(
audiusBackendInstance.updatePlaylistLastViewedAt,
action.payload.playlistId
)
}
)
}

export default function sagas() {
return [watchFetchPlaylistUpdates, watchUpdatedPlaylistViewedSaga]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { playlistUpdatesEntityAdapter } from './playlistUpdatesSlice'

export const { selectById: selectPlaylistUpdateById } =
playlistUpdatesEntityAdapter.getSelectors()
40 changes: 40 additions & 0 deletions packages/common/src/store/playlist-updates/playlistUpdatesSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { createEntityAdapter, createSlice } from '@reduxjs/toolkit'

import {
PlaylistUpdate,
PlaylistUpdatesReceivedAction,
PlaylistUpdateState,
UpdatedPlaylistViewedAction
} from './types'

export const playlistUpdatesEntityAdapter = createEntityAdapter<PlaylistUpdate>(
{
selectId: (playlistUpdate) => playlistUpdate.playlist_id
}
)

const initialState: PlaylistUpdateState =
playlistUpdatesEntityAdapter.getInitialState()

const slice = createSlice({
name: 'playlist-updates',
initialState,
reducers: {
fetchPlaylistUpdates() {},
playlistUpdatesReceived(state, action: PlaylistUpdatesReceivedAction) {
playlistUpdatesEntityAdapter.setAll(state, action.payload.playlistUpdates)
},
updatedPlaylistViewed(state, action: UpdatedPlaylistViewedAction) {
playlistUpdatesEntityAdapter.removeOne(state, action.payload.playlistId)
}
}
})

export const {
fetchPlaylistUpdates,
playlistUpdatesReceived,
updatedPlaylistViewed
} = slice.actions

export const { actions } = slice
export default slice.reducer
19 changes: 19 additions & 0 deletions packages/common/src/store/playlist-updates/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { EntityState, PayloadAction } from '@reduxjs/toolkit'

import { ID } from 'models/Identifiers'

export type PlaylistUpdate = {
playlist_id: number
updated_at: string
last_seen_at: string
}

export type PlaylistUpdateState = EntityState<PlaylistUpdate>

export type PlaylistUpdatesReceivedAction = PayloadAction<{
playlistUpdates: PlaylistUpdate[]
}>

export type UpdatedPlaylistViewedAction = PayloadAction<{
playlistId: ID
}>
3 changes: 3 additions & 0 deletions packages/common/src/store/reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import {
playlistLibraryReducer,
PlaylistLibraryState
} from './playlist-library'
import { playlistUpdatesReducer, PlaylistUpdateState } from './playlist-updates'
import premiumContentSlice from './premium-content/slice'
import queue from './queue/slice'
import reachability from './reachability/reducer'
Expand Down Expand Up @@ -160,6 +161,7 @@ export const reducers = () => ({

// Playlist Library
playlistLibrary: playlistLibraryReducer,
playlistUpdates: playlistUpdatesReducer,

notificationsLegacy: notificationsReducerLegacy,
notifications: notificationsReducer,
Expand Down Expand Up @@ -274,6 +276,7 @@ export type CommonState = {

// Playlist library
playlistLibrary: PlaylistLibraryState
playlistUpdates: PlaylistUpdateState

notificationsLegacy: NotificationState
notifications: NotificationsState
Expand Down
4 changes: 3 additions & 1 deletion packages/common/src/store/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { premiumContentSagas } from 'store/premium-content'
import remoteConfigSagas from 'store/remote-config/sagas'
import { searchUsersModalSagas } from 'store/ui'

import { playlistUpdatesSagas } from './playlist-updates'
import { CommonStoreContext } from './storeContext'
import {
toastSagas,
Expand Down Expand Up @@ -45,7 +46,8 @@ export const sagas = (_ctx: CommonStoreContext) => ({
mobileOverflowMenuUI: mobileOverflowMenuUISagas,
deletePlaylistConfirmationModalUI: deletePlaylistConfirmationModalUISagas,
player: playerSagas,
playbackPosition: playbackPositionSagas
playbackPosition: playbackPositionSagas,
playlistUpdates: playlistUpdatesSagas

// signOut: signOutSagas
// recoveryEmail: recoveryEmailSagas
Expand Down
5 changes: 5 additions & 0 deletions packages/web/src/common/store/playlist-updates/sagas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { watchUpdatedPlaylistViewedSaga } from './updatedPlaylistViewedSaga'

export default function sagas() {
return [watchUpdatedPlaylistViewedSaga()]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {
getContext,
playlistUpdatesActions,
UpdatedPlaylistViewedAction
} from '@audius/common'
import { call, takeEvery } from 'typed-redux-saga'

const { updatedPlaylistViewed } = playlistUpdatesActions

export function* watchUpdatedPlaylistViewedSaga() {
yield* takeEvery(updatedPlaylistViewed.type, updatePlaylistLastViewedAt)
}

function* updatePlaylistLastViewedAt(action: UpdatedPlaylistViewedAction) {
const audiusBackendInstance = yield* getContext('audiusBackendInstance')
yield* call(
audiusBackendInstance.updatePlaylistLastViewedAt,
action.payload.playlistId
)
}
4 changes: 3 additions & 1 deletion packages/web/src/store/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
vipDiscordModalSagas,
reachabilitySagas as commonReachabilitySagas,
searchUsersModalSagas,
solanaSagas
solanaSagas,
playlistUpdatesSagas
} from '@audius/common'
import { all, fork } from 'redux-saga/effects'

Expand Down Expand Up @@ -104,6 +105,7 @@ export default function* rootSaga() {
// Account
accountSagas(),
playlistLibrarySagas(),
playlistUpdatesSagas(),
recoveryEmailSagas(),
signOutSagas(),

Expand Down

0 comments on commit 35d1124

Please sign in to comment.