Skip to content
This repository was archived by the owner on Oct 4, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/common/src/hooks/useProxySelector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useSelector } from 'react-redux'

import type { CommonState } from '../store/commonStore'

const createProxySelectorHook = <TState extends object = any>() => {
export const createProxySelectorHook = <TState extends object = any>() => {
const useProxySelector = <TReturnType>(
fn: (state: TState) => TReturnType,
deps: DependencyList
Expand Down
3 changes: 2 additions & 1 deletion packages/mobile/src/components/core/Switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const Switch = (props: SwitchProps) => {
defaultValue = false,
value,
onValueChange: onValueChangeProp,
style: styleProp,
...other
} = props
const { neutralLight6, white, secondary } = useThemeColors()
Expand All @@ -38,7 +39,7 @@ export const Switch = (props: SwitchProps) => {

return (
<RNSwitch
style={switchStyle}
style={[switchStyle, styleProp]}
trackColor={{ false: neutralLight6, true: secondary }}
thumbColor={white}
value={isEnabled}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { useCallback } from 'react'

import type { Collection } from '@audius/common'
import { cacheCollectionsSelectors } from '@audius/common'
import { useSelector } from 'react-redux'

import { useDrawer } from 'app/hooks/useDrawer'
import { removeCollectionDownload } from 'app/services/offline-downloader'

import { ConfirmationDrawer } from './ConfirmationDrawer'
const { getCollection } = cacheCollectionsSelectors

const messages = {
header: 'Are You Sure?',
Expand All @@ -20,20 +23,30 @@ const drawerName = 'RemoveDownloadedCollection'

export const RemoveDownloadedCollectionDrawer = () => {
const { data } = useDrawer(drawerName)
const { collectionId, tracksForDownload } = data
const { collectionId } = data

const isAlbum = useSelector(
(state) => state.collections.entries[collectionId]?.metadata.is_album
)
const collection = useSelector((state) =>
getCollection(state, { id: collectionId })
) as Collection

const { is_album, tracks } = collection

const tracksForDownload = tracks?.map(({ track_id }) => ({
trackId: track_id,
downloadReason: {
is_from_favorites: false,
collection_id: collectionId.toString()
}
}))

const handleConfirm = useCallback(() => {
removeCollectionDownload(collectionId, tracksForDownload)
removeCollectionDownload(collectionId.toString(), tracksForDownload ?? [])
}, [collectionId, tracksForDownload])

return (
<ConfirmationDrawer
drawerName={drawerName}
messages={{ ...messages, description: messages.description(isAlbum) }}
messages={{ ...messages, description: messages.description(is_album) }}
onConfirm={handleConfirm}
/>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,59 +1,32 @@
import { useMemo } from 'react'

import { cacheCollectionsSelectors } from '@audius/common'
import { View } from 'react-native'
import { useSelector } from 'react-redux'
import Rive from 'rive-react-native'

import IconDownloadFailed from 'app/assets/images/iconDownloadFailed.svg'
import IconDownloadInactive from 'app/assets/images/iconDownloadInactive.svg'
import IconDownloadQueued from 'app/assets/images/iconDownloadQueued.svg'
import IconDownloaded from 'app/assets/images/iconDownloaded.svg'
import { useIsOfflineModeEnabled } from 'app/hooks/useIsOfflineModeEnabled'
import {
getIsCollectionMarkedForDownload,
getIsAnyDownloadInProgress,
getTrackOfflineDownloadStatus,
getIsAllDownloadsErrored
} from 'app/store/offline-downloads/selectors'
import { OfflineTrackDownloadStatus } from 'app/store/offline-downloads/slice'
import { makeStyles } from 'app/styles'
import { useThemeVariant } from 'app/utils/theme'
import { OfflineDownloadStatus } from 'app/store/offline-downloads/slice'

import { DownloadStatusIndicator as DownloadStatusIndicatorBase } from './DownloadStatusIndicatorBase'

const { getCollection } = cacheCollectionsSelectors

type TrackDownloadIndicatorProps = {
trackId?: number
collectionId?: string
statusOverride?: OfflineTrackDownloadStatus | null
showNotDownloaded?: boolean
size?: number
}

const useStyles = makeStyles(({ palette }) => ({
iconDownloadQueued: {
fill: palette.neutralLight4
},
iconDownloaded: {
fill: palette.secondary
},
iconDownloadFailed: {
fill: palette.secondary
},
iconDownloadInactive: {
fill: palette.neutralLight4
}
}))

export const DownloadStatusIndicator = ({
collectionId,
trackId,
statusOverride,
showNotDownloaded,
size = 24
}: TrackDownloadIndicatorProps) => {
const styles = useStyles()
const themeVariant = useThemeVariant()
const isOfflineModeEnabled = useIsOfflineModeEnabled()
const isMarkedForDownload = useSelector(
getIsCollectionMarkedForDownload(collectionId)
Expand Down Expand Up @@ -86,64 +59,16 @@ export const DownloadStatusIndicator = ({
)

const downloadStatus =
statusOverride ??
trackDownloadStatus ??
(isMarkedForDownload
? isAnyDownloadInProgress
? OfflineTrackDownloadStatus.LOADING
? OfflineDownloadStatus.LOADING
: isAllDownloadsErrored
? OfflineTrackDownloadStatus.ERROR
: OfflineTrackDownloadStatus.SUCCESS
? OfflineDownloadStatus.ERROR
: OfflineDownloadStatus.SUCCESS
: null)

if (!isOfflineModeEnabled) return null

switch (downloadStatus) {
case OfflineTrackDownloadStatus.INIT:
return (
<IconDownloadQueued
fill={styles.iconDownloadQueued.fill}
height={size}
width={size}
/>
)
case OfflineTrackDownloadStatus.LOADING:
return (
<View>
<Rive
style={{
height: size,
width: size
}}
resourceName={`downloading_${themeVariant}`}
autoplay
/>
</View>
)
case OfflineTrackDownloadStatus.SUCCESS:
return (
<IconDownloaded
fill={styles.iconDownloaded.fill}
height={size}
width={size}
/>
)
case OfflineTrackDownloadStatus.ERROR:
// TODO: clickable to retry
return (
<IconDownloadFailed
fill={styles.iconDownloadFailed.fill}
height={size}
width={size}
/>
)
default:
return showNotDownloaded ? (
<IconDownloadInactive
fill={styles.iconDownloadInactive.fill}
height={size}
width={size}
/>
) : null
}
return <DownloadStatusIndicatorBase status={downloadStatus} size={size} />
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import type { Nullable } from '@audius/common'
import type { StyleProp, ViewStyle } from 'react-native'
import { View } from 'react-native'
import Rive from 'rive-react-native'

import IconDownloadFailed from 'app/assets/images/iconDownloadFailed.svg'
import IconDownloadInactive from 'app/assets/images/iconDownloadInactive.svg'
import IconDownloadQueued from 'app/assets/images/iconDownloadQueued.svg'
import IconDownloaded from 'app/assets/images/iconDownloaded.svg'
import { OfflineDownloadStatus } from 'app/store/offline-downloads/slice'
import { makeStyles } from 'app/styles'
import { useThemeVariant } from 'app/utils/theme'

type DownloadStatusIndicatorProps = {
status: Nullable<OfflineDownloadStatus>
size?: number
style?: StyleProp<ViewStyle>
}

const useStyles = makeStyles(({ palette }) => ({
iconDownloadQueued: {
fill: palette.neutralLight4
},
iconDownloaded: {
fill: palette.secondary
},
iconDownloadFailed: {
fill: palette.secondary
},
iconDownloadInactive: {
fill: palette.neutralLight4
}
}))

export const DownloadStatusIndicator = (
props: DownloadStatusIndicatorProps
) => {
const { status, size = 24, style } = props
const styles = useStyles()
const themeVariant = useThemeVariant()

const renderIndicator = () => {
switch (status) {
case OfflineDownloadStatus.INIT:
return (
<IconDownloadQueued
fill={styles.iconDownloadQueued.fill}
height={size}
width={size}
/>
)
case OfflineDownloadStatus.LOADING:
return (
<View>
<Rive
style={{ height: size, width: size }}
resourceName={`downloading_${themeVariant}`}
autoplay
/>
</View>
)
case OfflineDownloadStatus.SUCCESS:
return (
<IconDownloaded
fill={styles.iconDownloaded.fill}
height={size}
width={size}
/>
)
case OfflineDownloadStatus.ERROR:
return (
<IconDownloadFailed
fill={styles.iconDownloadFailed.fill}
height={size}
width={size}
/>
)
case OfflineDownloadStatus.INACTIVE:
return (
<IconDownloadInactive
fill={styles.iconDownloadInactive.fill}
height={size}
width={size}
/>
)
default:
return null
}
}
return <View style={style}>{renderIndicator()}</View>
}
Loading