Skip to content
This repository has been archived by the owner on Oct 4, 2023. It is now read-only.

Offline mode drawer PAY-1713 #4014

Merged
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
4 changes: 3 additions & 1 deletion packages/mobile/src/app/Drawers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ import {
RemoveDownloadedCollectionDrawer,
RemoveDownloadedFavoritesDrawer,
UnfavoriteDownloadedCollectionDrawer,
DeleteTrackConfirmationDrawer
DeleteTrackConfirmationDrawer,
OfflineListeningDrawer
} from '../components/drawers'
import { ShareToStoryProgressDrawer } from '../components/share-drawer/useShareToStory'
import { VipDiscordDrawer } from '../components/vip-discord-drawer'
Expand Down Expand Up @@ -114,6 +115,7 @@ const commonDrawersMap: { [Modal in Modals]?: ComponentType } = {

const nativeDrawersMap: { [DrawerName in Drawer]?: ComponentType } = {
EnablePushNotifications: EnablePushNotificationsDrawer,
OfflineListening: OfflineListeningDrawer,
DownloadTrackProgress: DownloadTrackProgressDrawer,
ForgotPassword: ForgotPasswordDrawer,
DeleteTrackConfirmation: DeleteTrackConfirmationDrawer,
Expand Down
55 changes: 55 additions & 0 deletions packages/mobile/src/components/core/HarmonyModalHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import type { ComponentType } from 'react'

import { View } from 'react-native'
import type { SvgProps } from 'react-native-svg'

import { Text } from 'app/components/core'
import { makeStyles } from 'app/styles'
import { useThemeColors } from 'app/utils/theme'

const useStyles = makeStyles(({ spacing, palette }) => ({
container: {
width: '100%',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
paddingBottom: spacing(4),
borderBottomColor: palette.neutralLight8,
borderBottomWidth: 1
},
titleIcon: {
marginRight: spacing(2)
}
}))

type HarmonyModalHeaderProps = {
icon: ComponentType<SvgProps>
title: string
}

export const HarmonyModalHeader = ({
icon: Icon,
title
}: HarmonyModalHeaderProps) => {
const styles = useStyles()
const { neutralLight2 } = useThemeColors()

return (
<View style={styles.container}>
<Icon
style={styles.titleIcon}
fill={neutralLight2}
height={20}
width={24}
/>
<Text
weight='heavy'
color='neutralLight2'
fontSize='xl'
textTransform='uppercase'
>
{title}
</Text>
</View>
)
}
180 changes: 180 additions & 0 deletions packages/mobile/src/components/drawers/OfflineListeningDrawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import type { ComponentType } from 'react'
import { useCallback, useState } from 'react'

import { View } from 'react-native'
import type { SvgProps } from 'react-native-svg'
import { useDispatch } from 'react-redux'

import IconCart from 'app/assets/images/iconCart.svg'
import IconDownload from 'app/assets/images/iconDownloadQueued.svg'
import IconFavorite from 'app/assets/images/iconFavorite.svg'
import IconRepost from 'app/assets/images/iconRepost.svg'
import { Button, Switch, Text } from 'app/components/core'
import { useDrawer } from 'app/hooks/useDrawer'
import { setVisibility } from 'app/store/drawers/slice'
import { requestDownloadAllFavorites } from 'app/store/offline-downloads/slice'
import { makeStyles } from 'app/styles'
import { useThemeColors } from 'app/utils/theme'

import { HarmonyModalHeader } from '../core/HarmonyModalHeader'
import { NativeDrawer } from '../drawer'

const useDrawerStyles = makeStyles(({ spacing, palette, typography }) => ({
container: {
paddingVertical: spacing(6),
flexDirection: 'column',
paddingHorizontal: spacing(4),
rowGap: spacing(6),
alignItems: 'center'
},
descriptionText: {
textAlign: 'center',
lineHeight: typography.fontSize.large * 1.3
},
titleIcon: {
position: 'relative',
nicoback2 marked this conversation as resolved.
Show resolved Hide resolved
top: 7,
color: palette.neutral,
marginRight: spacing(3)
}
}))

const useToggleStyles = makeStyles(({ spacing, palette }) => ({
toggleContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
width: '100%',
alignItems: 'center'
},
titleContainer: {
columnGap: spacing(2),
flexDirection: 'row'
}
}))

const messages = {
offlineListeningTitle: 'Offline Listening',
offlineListeningDescription:
'Use the toggles to select what you’d like synced for offline streaming.',
comingSoonToggleSuffix: '(coming soon...)',
favorites: 'Favorites',
reposts: 'Reposts',
purchased: 'Purchased',
saveChanges: 'Save Changes'
}

type OfflineListeningOptionToggleProps = {
title: string
icon: ComponentType<SvgProps>
value: boolean
onValueChange?: (value: boolean) => void | Promise<void>
disabled?: boolean
}

const OfflineListeningOptionToggle = ({
nicoback2 marked this conversation as resolved.
Show resolved Hide resolved
title,
icon: Icon,
value,
onValueChange,
disabled
}: OfflineListeningOptionToggleProps) => {
const styles = useToggleStyles()
const { neutral, neutralLight4 } = useThemeColors()

return (
<View style={styles.toggleContainer}>
<View style={styles.titleContainer}>
<Icon
fill={disabled ? neutralLight4 : neutral}
height={20}
width={20}
/>
<Text
weight='demiBold'
fontSize='large'
color={disabled ? 'neutralLight4' : 'neutral'}
>
{title}
</Text>
</View>
<Switch value={value} disabled={disabled} onValueChange={onValueChange} />
</View>
)
}

export const OfflineListeningDrawer = () => {
const styles = useDrawerStyles()
const dispatch = useDispatch()
const { data, onClose } = useDrawer('OfflineListening')
const { isFavoritesMarkedForDownload, onSaveChanges } = data

const [isFavoritesOn, setIsFavoritesOn] = useState(
isFavoritesMarkedForDownload
)

const handleSaveChanges = useCallback(() => {
if (isFavoritesMarkedForDownload && !isFavoritesOn) {
dispatch(
setVisibility({
drawer: 'RemoveDownloadedFavorites',
visible: true
})
)
onSaveChanges(isFavoritesOn)
} else if (!isFavoritesMarkedForDownload && isFavoritesOn) {
dispatch(requestDownloadAllFavorites())
onSaveChanges(isFavoritesOn)
}

onClose()
}, [
dispatch,
isFavoritesMarkedForDownload,
isFavoritesOn,
onClose,
onSaveChanges
])

const handleToggleFavorites = useCallback((value: boolean) => {
setIsFavoritesOn(value)
}, [])

return (
<NativeDrawer drawerName='OfflineListening'>
<View style={styles.container}>
<HarmonyModalHeader
icon={IconDownload}
title={messages.offlineListeningTitle}
/>
<Text weight='medium' fontSize='large' style={styles.descriptionText}>
{messages.offlineListeningDescription}
</Text>
<OfflineListeningOptionToggle
title={messages.favorites}
icon={IconFavorite}
value={isFavoritesOn}
onValueChange={handleToggleFavorites}
/>
<OfflineListeningOptionToggle
title={`${messages.reposts} ${messages.comingSoonToggleSuffix}`}
icon={IconRepost}
value={false}
disabled
/>
<OfflineListeningOptionToggle
title={`${messages.purchased} ${messages.comingSoonToggleSuffix}`}
icon={IconCart}
value={false}
disabled
/>
<Button
title={messages.saveChanges}
fullWidth
size='large'
variant='primary'
onPress={handleSaveChanges}
/>
</View>
</NativeDrawer>
)
}
1 change: 1 addition & 0 deletions packages/mobile/src/components/drawers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export * from './DeleteTrackConfirmationDrawer'
export * from './RemoveAllDownloadsDrawer'
export * from './RemoveDownloadedCollectionDrawer'
export * from './RemoveDownloadedFavoritesDrawer'
export * from './OfflineListeningDrawer'
export * from './UnfavoriteDownloadedCollectionDrawer'
46 changes: 7 additions & 39 deletions packages/mobile/src/components/share-drawer/useShareToStory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ import {
} from 'app/utils/dominantColors'
import { reportToSentry } from 'app/utils/reportToSentry'
import { getTrackRoute } from 'app/utils/routes'
import { useThemeColors } from 'app/utils/theme'

import { HarmonyModalHeader } from '../core/HarmonyModalHeader'
import { NativeDrawer } from '../drawer'
import { DEFAULT_IMAGE_URL, useTrackImage } from '../image/TrackImage'

Expand Down Expand Up @@ -527,39 +527,22 @@ export const useShareToStory = ({
}
}

const useStyles = makeStyles(({ spacing, palette }) => ({
const useStyles = makeStyles(({ spacing }) => ({
container: {
paddingTop: spacing(4),
paddingBottom: spacing(10),
flexDirection: 'column',
paddingHorizontal: spacing(4),
alignItems: 'center'
},
title: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
paddingTop: spacing(2),
paddingBottom: spacing(4)
},
titleText: {
textTransform: 'uppercase',
marginTop: spacing(4)
},
subtitleText: {
marginTop: spacing(4)
},
titleIcon: {
position: 'relative',
top: 7,
color: palette.neutral,
marginRight: spacing(3)
},
button: {
marginTop: spacing(4)
},
progress: {
marginTop: spacing(4),
width: '100%',
height: 24
},
Expand All @@ -580,7 +563,6 @@ export const ShareToStoryProgressDrawer = () => {
}),
[styles.progressBar, styles.progressBarContainer]
)
const { neutralLight2 } = useThemeColors()
const progress = useSelector(getProgressPercentage)
const cancel = useSelector(getCancel)
const platform = useSelector(getPlatform)
Expand All @@ -604,24 +586,10 @@ export const ShareToStoryProgressDrawer = () => {
onClose={handleCancel}
>
<View style={styles.container}>
<View style={styles.title}>
<IconWavform
style={styles.titleIcon}
fill={neutralLight2}
height={20}
width={24}
/>
<View>
<Text
weight='heavy'
color='neutralLight2'
fontSize={'xl'}
style={styles.titleText}
>
{messages.loadingStoryModalTitle}
</Text>
</View>
</View>
<HarmonyModalHeader
icon={IconWavform}
title={messages.loadingStoryModalTitle}
/>
<View style={styles.progress}>
<LinearProgress value={progress} styles={progressBarStyles} />
</View>
Expand Down
Loading