Skip to content
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
1 change: 1 addition & 0 deletions packages/common/src/store/ui/modals/parentSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const initialState: BasicModalsState = {
TrendingCategory: { isOpen: false },
TrendingTimeRange: { isOpen: false },
TrendingFilter: { isOpen: false },
FeedFilter: { isOpen: false },
TrendingRewardsExplainer: { isOpen: false },
SocialProof: { isOpen: false },
EditTrack: { isOpen: false },
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/store/ui/modals/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export type Modals =
| 'TrendingCategory'
| 'TrendingTimeRange'
| 'TrendingFilter'
| 'FeedFilter'
| 'TrendingRewardsExplainer'
| 'SocialProof'
| 'EditTrack'
Expand Down
2 changes: 2 additions & 0 deletions packages/mobile/src/app/Drawers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import { ReplaceTrackProgressDrawer } from 'app/screens/edit-track-screen/compon
import { EarlyReleaseConfirmationDrawer } from 'app/screens/edit-track-screen/components/EarlyReleaseConfirmationDrawer'
import { PublishConfirmationDrawer } from 'app/screens/edit-track-screen/components/PublishConfirmationDrawer'
import { ConnectNewWalletDrawer } from 'app/screens/external-wallets/components/ConnectNewWalletDrawer'
import { FeedFilterDrawer } from 'app/screens/feed-screen'
import { WelcomeDrawer } from 'app/screens/sign-on-screen/components/WelcomeDrawer'
import { PickWinnersDrawer } from 'app/screens/track-screen/PickWinnersDrawer'
import {
Expand Down Expand Up @@ -115,6 +116,7 @@ const commonDrawersMap: { [Modal in Modals]?: ComponentType } = {
DeactivateAccountConfirmation: DeactivateAccountConfirmationDrawer,
TrendingGenreSelection: TrendingFilterDrawer,
TrendingFilter: TrendingCombinedFilterDrawer,
FeedFilter: FeedFilterDrawer,
Overflow: OverflowMenuDrawer,
SignOutConfirmation: SignOutConfirmationDrawer,
AddToCollection: AddToCollectionDrawer,
Expand Down
37 changes: 37 additions & 0 deletions packages/mobile/src/screens/feed-screen/FeedFilterButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { FeedFilter } from '@audius/common/models'
import { feedPageSelectors, modalsActions } from '@audius/common/store'
import { useDispatch, useSelector } from 'react-redux'

import { Flex, IconLeading, SelectablePill } from '@audius/harmony-native'

import { FEED_FILTER_MODAL } from './FeedFilterDrawer'

export const FeedFilterButton = () => {
const dispatch = useDispatch()
const feedFilter = useSelector(feedPageSelectors.getFeedFilter)

const hasActiveFilters = (feedFilter ?? FeedFilter.ALL) !== FeedFilter.ALL

const handleOpenFilter = () => {
dispatch(
modalsActions.setVisibility({
modal: FEED_FILTER_MODAL,
visible: true
})
)
}

return (
<Flex>
<SelectablePill
type='button'
icon={IconLeading}
size='large'
isSelected={hasActiveFilters}
isControlled
onPress={handleOpenFilter}
accessibilityLabel='Open filter'
/>
</Flex>
)
}
132 changes: 132 additions & 0 deletions packages/mobile/src/screens/feed-screen/FeedFilterDrawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { useCallback } from 'react'

import { FeedFilter } from '@audius/common/models'
import { feedPageActions, feedPageSelectors } from '@audius/common/store'
import { Pressable, View } from 'react-native'
import { useDispatch, useSelector } from 'react-redux'

import { Flex, Text } from '@audius/harmony-native'
import { RadioButton, Text as CoreText } from 'app/components/core'
import { AppDrawer, useDrawerState } from 'app/components/drawer'
import { makeStyles } from 'app/styles'

export const FEED_FILTER_MODAL = 'FeedFilter' as const

const filterLabels: Record<FeedFilter, string> = {
[FeedFilter.ALL]: 'All Posts',
[FeedFilter.ORIGINAL]: 'Original Posts',
[FeedFilter.REPOST]: 'Reposts'
}

const filterOptions: FeedFilter[] = [
FeedFilter.ALL,
FeedFilter.ORIGINAL,
FeedFilter.REPOST
]

const messages = {
title: 'Filter Feed',
sectionTitle: 'Post Type',
selected: 'Selected'
}

const useStyles = makeStyles(({ palette, spacing }) => ({
grabBar: {
width: 36,
height: 4,
borderRadius: 2,
backgroundColor: palette.neutralLight6
},
grabBarContainer: {
paddingTop: spacing(2),
paddingBottom: spacing(1),
alignItems: 'center'
},
content: {
paddingHorizontal: spacing(4),
paddingTop: spacing(4),
paddingBottom: spacing(6)
},
sectionTitle: {
marginBottom: spacing(2)
},
optionRow: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingVertical: spacing(4),
borderBottomWidth: 1,
borderBottomColor: palette.neutralLight8
}
}))

export const FeedFilterDrawer = () => {
const styles = useStyles()
const dispatch = useDispatch()
const currentFilter =
useSelector(feedPageSelectors.getFeedFilter) ?? FeedFilter.ALL

useDrawerState(FEED_FILTER_MODAL)

const handleSelectFilter = useCallback(
(filter: FeedFilter) => {
dispatch(feedPageActions.setFeedFilter(filter))
},
[dispatch]
)

const drawerHeader = useCallback(
(_props: { onClose: () => void }) => (
<Flex>
<View style={[styles.grabBarContainer]}>
<View style={[styles.grabBar]} />
</View>
<Flex ph='l' pb='l' pt='xs' justifyContent='center' alignItems='center'>
<Text variant='title' size='l' textAlign='center'>
{messages.title}
</Text>
</Flex>
</Flex>
),
[styles]
)

return (
<AppDrawer
modalName={FEED_FILTER_MODAL}
drawerHeader={drawerHeader}
isGestureSupported
>
<View style={styles.content}>
<View style={styles.sectionTitle}>
<CoreText fontSize='large' weight='demiBold'>
{messages.sectionTitle}
</CoreText>
</View>
{filterOptions.map((filter) => (
<Pressable
key={filter}
onPress={() => handleSelectFilter(filter)}
style={styles.optionRow}
>
<Flex direction='row' alignItems='center' gap='m'>
<RadioButton checked={currentFilter === filter} />
<Text
variant='body'
size='l'
color={currentFilter === filter ? 'accent' : 'default'}
>
{filterLabels[filter]}
</Text>
</Flex>
{currentFilter === filter ? (
<Text variant='body' size='s' color='accent'>
{messages.selected}
</Text>
) : null}
</Pressable>
))}
</View>
</AppDrawer>
)
}
58 changes: 0 additions & 58 deletions packages/mobile/src/screens/feed-screen/FeedFilters.tsx

This file was deleted.

36 changes: 15 additions & 21 deletions packages/mobile/src/screens/feed-screen/FeedScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
FOR_YOU_INITIAL_PAGE_SIZE,
FOR_YOU_LOAD_MORE_PAGE_SIZE
} from '@audius/common/api'
import { Name, FeedTab, type FeedFilter } from '@audius/common/models'
import { Name, FeedTab } from '@audius/common/models'
import { feedPageActions, feedPageSelectors } from '@audius/common/store'
import { useDispatch, useSelector } from 'react-redux'

Expand All @@ -21,11 +21,11 @@ import { SuggestedFollows } from 'app/components/suggested-follows'
import { MobileRootHeader } from 'app/screens/app-screen/MobileRootHeader'
import { make, track } from 'app/services/analytics'

import { FeedFilters } from './FeedFilters'
import { FeedFilterButton } from './FeedFilterButton'
import { FeedTabs } from './FeedTabs'

const { getFeedTab, getFeedFilter } = feedPageSelectors
const { setFeedTab, setFeedFilter } = feedPageActions
const { setFeedTab } = feedPageActions

const messages = {
header: 'Your Feed',
Expand Down Expand Up @@ -80,12 +80,17 @@ export const FeedScreen = () => {
[dispatch]
)

const handleSelectFilter = useCallback(
(filter: FeedFilter) => {
dispatch(setFeedFilter(filter))
track(make({ eventName: Name.FEED_CHANGE_VIEW, view: filter }))
},
[dispatch]
// Memoized so the header isn't a new function reference on every render —
// otherwise Screen's setOptions runs each parent re-render and React
// Navigation rebuilds the header, remounting AccountPictureHeader and
// re-firing the profile-picture image-fetch path.
const renderHeader = useCallback(
() => (
<MobileRootHeader title={messages.header} showDivider={false}>
{isForYou ? null : <FeedFilterButton />}
</MobileRootHeader>
),
[isForYou]
)

const lineupProps = isForYou
Expand Down Expand Up @@ -115,20 +120,9 @@ export const FeedScreen = () => {
}

return (
<Screen
url='Feed'
header={() => (
<MobileRootHeader title={messages.header} showDivider={false} />
)}
>
<Screen url='Feed' header={renderHeader}>
<ScreenContent>
<FeedTabs currentTab={feedTab} onSelectTab={handleSelectTab} />
{isForYou ? null : (
<FeedFilters
currentFilter={feedFilter}
onSelectFilter={handleSelectFilter}
/>
)}
<TrackLineup
key={`feed-${feedTab}`}
source='DISCOVER_FEED'
Expand Down
1 change: 1 addition & 0 deletions packages/mobile/src/screens/feed-screen/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { FeedScreen } from './FeedScreen'
export { FeedFilterDrawer, FEED_FILTER_MODAL } from './FeedFilterDrawer'
Loading