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

Commit

Permalink
Offline mode drawer PAY-1713 (#4014)
Browse files Browse the repository at this point in the history
Co-authored-by: Nikki Kang <kangaroo233@gmail.com>
  • Loading branch information
nicoback2 and nicoback authored Sep 5, 2023
1 parent f81b5d8 commit 73eddce
Show file tree
Hide file tree
Showing 8 changed files with 287 additions and 47 deletions.
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',
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 = ({
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

0 comments on commit 73eddce

Please sign in to comment.