Skip to content

Commit 131074d

Browse files
nicoback2nicoback
andcommitted
Add purchased + reposted tracks to library PAY-1633 (#3820)
Co-authored-by: Nikki Kang <[email protected]>
1 parent 6259c2a commit 131074d

File tree

3 files changed

+191
-147
lines changed

3 files changed

+191
-147
lines changed

apps/audius-client/packages/web/src/common/store/pages/saved/lineups/sagas.js

-5
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,6 @@ function* getTracks({ offset, limit }) {
6464
trackIds: allSavedTrackIds.filter((id) => id !== null)
6565
})
6666
const tracksMap = tracks.reduce((map, track) => {
67-
// If the track hasn't confirmed save from the backend, pretend it is for the client.
68-
if (!track.has_current_user_saved) {
69-
track.has_current_user_saved = true
70-
track.save_count += 1
71-
}
7267
track.dateSaved = allSavedTrackTimestamps[track.track_id]
7368

7469
map[track.track_id] = track

apps/audius-client/packages/web/src/common/store/pages/saved/sagas.js

-142
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
import {
2+
accountSelectors,
3+
APIActivityV2,
4+
decodeHashId,
5+
encodeHashId,
6+
getContext,
7+
removeNullable,
8+
responseAdapter,
9+
savedPageActions as actions,
10+
savedPageSelectors,
11+
savedPageTracksLineupActions as tracksActions,
12+
User,
13+
UserTrackMetadata,
14+
waitForValue
15+
} from '@audius/common'
16+
import { call, fork, put, select, takeLatest } from 'typed-redux-saga'
17+
18+
import { processAndCacheTracks } from 'common/store/cache/tracks/utils'
19+
import { waitForRead } from 'utils/sagaHelpers'
20+
21+
import tracksSagas from './lineups/sagas'
22+
const { getSaves } = savedPageSelectors
23+
const { getAccountUser } = accountSelectors
24+
25+
function* fetchLineupMetadatas(offset: number, limit: number) {
26+
const isNativeMobile = yield* getContext('isNativeMobile')
27+
28+
// Mobile currently uses infinite scroll instead of a virtualized list
29+
// so we need to apply the offset & limit
30+
if (isNativeMobile) {
31+
yield* put(tracksActions.fetchLineupMetadatas(offset, limit))
32+
} else {
33+
yield* put(tracksActions.fetchLineupMetadatas())
34+
}
35+
}
36+
37+
type LibraryParams = {
38+
userId: number
39+
offset: number
40+
limit: number
41+
query: string
42+
sortMethod: string
43+
sortDirection: string
44+
}
45+
46+
function* sendLibraryRequest({
47+
userId,
48+
offset,
49+
limit,
50+
query,
51+
sortMethod,
52+
sortDirection
53+
}: LibraryParams) {
54+
const audiusBackendInstance = yield* getContext('audiusBackendInstance')
55+
const { data, signature } = yield* call([
56+
audiusBackendInstance,
57+
audiusBackendInstance.signDiscoveryNodeRequest
58+
])
59+
const audiusSdk = yield* getContext('audiusSdk')
60+
const sdk = yield* call(audiusSdk)
61+
62+
const savedTracksResponse = (yield* call(
63+
[sdk.full.users, sdk.full.users.getUserLibraryTracks as any],
64+
{
65+
id: encodeHashId(userId),
66+
userId: encodeHashId(userId),
67+
offset,
68+
limit,
69+
query,
70+
sortMethod,
71+
sortDirection,
72+
type: 'all',
73+
encodedDataMessage: data,
74+
encodedDataSignature: signature
75+
}
76+
)) as any
77+
const savedTracksResponseData = savedTracksResponse.data as APIActivityV2[]
78+
const tracks = savedTracksResponse.data
79+
?.map(responseAdapter.makeActivity)
80+
.filter(removeNullable) as UserTrackMetadata[]
81+
if (!tracks) {
82+
throw new Error('Something went wrong with library tracks request.')
83+
}
84+
85+
const saves = savedTracksResponseData
86+
.filter((save) => Boolean(save.timestamp && save.item))
87+
.map((save) => ({
88+
created_at: save.timestamp,
89+
save_item_id: decodeHashId(save.item.id!)
90+
}))
91+
92+
return {
93+
saves,
94+
tracks
95+
}
96+
}
97+
98+
function prepareParams({
99+
account,
100+
params
101+
}: {
102+
account: User
103+
params: ReturnType<typeof actions.fetchSaves>
104+
}) {
105+
return {
106+
userId: account.user_id,
107+
offset: params.offset ?? 0,
108+
limit: params.limit ?? account.track_save_count,
109+
query: params.query ?? '',
110+
sortMethod: params.sortMethod || 'added_date',
111+
sortDirection: params.sortDirection || 'desc'
112+
}
113+
}
114+
115+
function* watchFetchSaves() {
116+
let currentQuery = ''
117+
let currentSortMethod = ''
118+
let currentSortDirection = ''
119+
120+
yield* takeLatest(
121+
actions.FETCH_SAVES,
122+
function* (rawParams: ReturnType<typeof actions.fetchSaves>) {
123+
yield* waitForRead()
124+
const account: User = yield* call(waitForValue, getAccountUser)
125+
const saves = yield* select(getSaves)
126+
const params = prepareParams({ account, params: rawParams })
127+
const { query, sortDirection, sortMethod, offset, limit } = params
128+
const isSameParams =
129+
query === currentQuery &&
130+
currentSortDirection === sortDirection &&
131+
currentSortMethod === sortMethod
132+
133+
// Don't refetch saves in the same session
134+
if (saves && saves.length && isSameParams) {
135+
yield* fork(fetchLineupMetadatas, offset, limit)
136+
} else {
137+
try {
138+
currentQuery = query
139+
currentSortDirection = sortDirection
140+
currentSortMethod = sortMethod
141+
yield* put(actions.fetchSavesRequested())
142+
const { saves, tracks } = yield* call(sendLibraryRequest, params)
143+
144+
yield* processAndCacheTracks(tracks)
145+
146+
const fullSaves = Array(account.track_save_count)
147+
.fill(0)
148+
.map((_) => ({}))
149+
150+
fullSaves.splice(offset, saves.length, ...saves)
151+
yield* put(actions.fetchSavesSucceeded(fullSaves))
152+
if (limit > 0 && saves.length < limit) {
153+
yield* put(actions.endFetching(offset + saves.length))
154+
}
155+
yield* fork(fetchLineupMetadatas, offset, limit)
156+
} catch (e) {
157+
yield* put(actions.fetchSavesFailed())
158+
}
159+
}
160+
}
161+
)
162+
}
163+
164+
function* watchFetchMoreSaves() {
165+
yield* takeLatest(
166+
actions.FETCH_MORE_SAVES,
167+
function* (rawParams: ReturnType<typeof actions.fetchMoreSaves>) {
168+
yield* waitForRead()
169+
const account = yield* call(waitForValue, getAccountUser)
170+
const params = prepareParams({ account, params: rawParams })
171+
const { limit, offset } = params
172+
173+
try {
174+
const { saves, tracks } = yield* call(sendLibraryRequest, params)
175+
yield* processAndCacheTracks(tracks)
176+
yield* put(actions.fetchMoreSavesSucceeded(saves, offset))
177+
178+
if (limit > 0 && saves.length < limit) {
179+
yield* put(actions.endFetching(offset + saves.length))
180+
}
181+
yield* fork(fetchLineupMetadatas, offset, limit)
182+
} catch (e) {
183+
yield* put(actions.fetchMoreSavesFailed())
184+
}
185+
}
186+
)
187+
}
188+
189+
export default function sagas() {
190+
return [...tracksSagas(), watchFetchSaves, watchFetchMoreSaves]
191+
}

0 commit comments

Comments
 (0)