Skip to content

Commit 8632a7b

Browse files
authored
Drop theme flag (#13890)
1 parent 7127ed2 commit 8632a7b

13 files changed

Lines changed: 106 additions & 271 deletions

File tree

packages/common/src/adapters/collection.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {
1414
type UpdateAlbumRequestBody,
1515
type UpdatePlaylistRequestBody
1616
} from '@audius/sdk'
17-
import dayjs from '~/utils/dayjs'
1817
import { omit } from 'lodash'
1918
import snakecaseKeys from 'snakecase-keys'
2019

@@ -27,6 +26,7 @@ import {
2726
} from '~/models/Collection'
2827
import { Copyright, isContentUSDCPurchaseGated } from '~/models/Track'
2928
import type { AlbumValues, PlaylistValues } from '~/schemas'
29+
import dayjs from '~/utils/dayjs'
3030

3131
import { accessConditionsFromSDK } from './accessConditionsFromSDK'
3232
import { usdcPurchaseConditionsToSDK } from './accessConditionsToSDK'

packages/common/src/adapters/notification.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
instanceOfPlaylistMilestoneNotificationActionData,
1111
instanceOfTrackMilestoneNotificationActionData
1212
} from '@audius/sdk'
13-
import dayjs from '~/utils/dayjs'
1413

1514
import { BadgeTier, type ID } from '~/models'
1615
import type { ChallengeRewardID } from '~/models/AudioRewards'
@@ -21,6 +20,7 @@ import {
2120
NotificationType,
2221
type Notification
2322
} from '~/store/notifications/types'
23+
import dayjs from '~/utils/dayjs'
2424
import { removeNullable } from '~/utils/typeUtils'
2525

2626
const getTimeAgo = (date: number) => {

packages/common/src/adapters/track.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {
1414
OptionalId
1515
} from '@audius/sdk'
1616
import camelcaseKeys from 'camelcase-keys'
17-
import dayjs from '~/utils/dayjs'
1817
import { omit, pick, mapValues } from 'lodash'
1918
import snakecaseKeys from 'snakecase-keys'
2019

@@ -27,6 +26,7 @@ import {
2726
import { StemTrackMetadata, UserTrackMetadata } from '~/models/Track'
2827
import type { TrackMetadataForUpload } from '~/store/upload/types'
2928
import { formatMusicalKey, License, Maybe, squashNewLines } from '~/utils'
29+
import dayjs from '~/utils/dayjs'
3030

3131
import { accessConditionsFromSDK } from './accessConditionsFromSDK'
3232
import { accessConditionsToSDK } from './accessConditionsToSDK'

packages/common/src/services/remote-config/feature-flags.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ export enum FeatureFlags {
1414
FAST_REFERRAL = 'fast_referral',
1515
REACT_QUERY_SYNC = 'react_query_sync',
1616
COLLAPSED_EXPLORE_HEADER = 'collapsed_explore_header',
17-
LAUNCHPAD_VERIFICATION = 'launchpad_verification',
18-
NEW_THEME_MODEL = 'new_theme_model'
17+
LAUNCHPAD_VERIFICATION = 'launchpad_verification'
1918
}
2019

2120
type FlagDefaults = Record<FeatureFlags, boolean>
@@ -44,6 +43,5 @@ export const flagDefaults: FlagDefaults = {
4443
[FeatureFlags.FAST_REFERRAL]: false,
4544
[FeatureFlags.REACT_QUERY_SYNC]: false,
4645
[FeatureFlags.COLLAPSED_EXPLORE_HEADER]: false,
47-
[FeatureFlags.LAUNCHPAD_VERIFICATION]: true,
48-
[FeatureFlags.NEW_THEME_MODEL]: false
46+
[FeatureFlags.LAUNCHPAD_VERIFICATION]: true
4947
}

packages/common/src/store/ui/theme/slice.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ const themeSlice = createSlice({
5757
: action.payload.theme === Theme.DARK
5858
? ThemeMode.DARK
5959
: ThemeMode.AUTO
60-
// Preserve palette when updating mode; default to classic for legacy
60+
// Preserve palette when updating mode; default to default (Neue) for all users
6161
if (state.themePalette === null) {
62-
state.themePalette = ThemePalette.CLASSIC
62+
state.themePalette = ThemePalette.DEFAULT
6363
}
6464
}
6565
},

packages/mobile/android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ android {
128128
// versionCode is automatically incremented in CI
129129
versionCode 1
130130
// Make sure this is above the currently released Android version in the play store if your changes touch native code:
131-
versionName "1.1.521"
131+
versionName "1.1.522"
132132
resValue "string", "build_config_package", "co.audius.app"
133133
resConfigs "en"
134134
}

packages/mobile/src/app/ThemeProvider.tsx

Lines changed: 38 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import type { ReactNode } from 'react'
2-
import { useEffect, useMemo } from 'react'
2+
import { useEffect } from 'react'
33

4-
import { useFeatureFlag } from '@audius/common/hooks'
54
import {
65
Theme,
76
ThemeMode,
87
ThemePalette,
98
SystemAppearance,
109
LEGACY_THEME_DEFAULT
1110
} from '@audius/common/models'
12-
import { FeatureFlags } from '@audius/common/services'
1311
import { themeActions, themeSelectors } from '@audius/common/store'
1412
import type { Nullable } from '@audius/common/utils'
1513
import AsyncStorage from '@react-native-async-storage/async-storage'
@@ -107,38 +105,12 @@ const selectHarmonyTheme = (state: AppState): HarmonyThemeName => {
107105
}
108106
}
109107

110-
/**
111-
* When new theme flag is on: classic-* → default-* (upgrade).
112-
* When new theme flag is off: default-* → classic-* (downgrade).
113-
* Matrix is unchanged.
114-
*/
115-
const applyThemeFlag = (
116-
themeName: HarmonyThemeName,
117-
isNewThemeModelEnabled: boolean
118-
): HarmonyThemeName => {
119-
if (isNewThemeModelEnabled) {
120-
if (themeName === 'classic-light') return 'default-light'
121-
if (themeName === 'classic-dark') return 'default-dark'
122-
} else {
123-
if (themeName === 'default-light') return 'classic-light'
124-
if (themeName === 'default-dark') return 'classic-dark'
125-
}
126-
return themeName
127-
}
128-
129108
export const ThemeProvider = (props: ThemeProviderProps) => {
130109
const { children } = props
131110
const isDarkMode = useDarkMode()
132111
const dispatch = useDispatch()
133112
const appState = useAppState()
134-
const themeFromState = useSelector(selectHarmonyTheme)
135-
const { isEnabled: isNewThemeModelEnabled } = useFeatureFlag(
136-
FeatureFlags.NEW_THEME_MODEL
137-
)
138-
const theme = useMemo(
139-
() => applyThemeFlag(themeFromState, isNewThemeModelEnabled),
140-
[themeFromState, isNewThemeModelEnabled]
141-
)
113+
const theme = useSelector(selectHarmonyTheme)
142114

143115
useAsync(async () => {
144116
const [savedTheme, savedPalette, savedMode] = await Promise.all([
@@ -147,25 +119,42 @@ export const ThemeProvider = (props: ThemeProviderProps) => {
147119
AsyncStorage.getItem(THEME_MODE_KEY)
148120
])
149121

150-
// Handle legacy "default" value - treat as AUTO
151-
const theme =
152-
savedTheme === LEGACY_THEME_DEFAULT
153-
? Theme.AUTO
154-
: ((savedTheme as Nullable<Theme>) ?? Theme.AUTO)
155-
156-
dispatch(setTheme({ theme }))
157-
158-
if (
159-
savedPalette &&
160-
Object.values(ThemePalette).includes(savedPalette as ThemePalette)
161-
) {
162-
dispatch(setThemePalette({ themePalette: savedPalette as ThemePalette }))
163-
}
164-
if (
165-
savedMode &&
166-
Object.values(ThemeMode).includes(savedMode as ThemeMode)
167-
) {
168-
dispatch(setThemeMode({ themeMode: savedMode as ThemeMode }))
122+
const isLegacyTheme =
123+
savedTheme === LEGACY_THEME_DEFAULT ||
124+
savedTheme == null ||
125+
savedPalette == null ||
126+
savedPalette === ThemePalette.CLASSIC
127+
128+
if (isLegacyTheme) {
129+
// Migrate: wipe legacy/classic and set everyone to default palette + auto
130+
await Promise.all([
131+
AsyncStorage.setItem(THEME_STORAGE_KEY, Theme.AUTO),
132+
AsyncStorage.setItem(THEME_PALETTE_KEY, ThemePalette.DEFAULT),
133+
AsyncStorage.setItem(THEME_MODE_KEY, ThemeMode.AUTO)
134+
])
135+
dispatch(setTheme({ theme: Theme.AUTO }))
136+
dispatch(setThemePalette({ themePalette: ThemePalette.DEFAULT }))
137+
dispatch(setThemeMode({ themeMode: ThemeMode.AUTO }))
138+
} else {
139+
const theme =
140+
savedTheme === LEGACY_THEME_DEFAULT
141+
? Theme.AUTO
142+
: ((savedTheme as Nullable<Theme>) ?? Theme.AUTO)
143+
dispatch(setTheme({ theme }))
144+
if (
145+
savedPalette &&
146+
Object.values(ThemePalette).includes(savedPalette as ThemePalette)
147+
) {
148+
dispatch(
149+
setThemePalette({ themePalette: savedPalette as ThemePalette })
150+
)
151+
}
152+
if (
153+
savedMode &&
154+
Object.values(ThemeMode).includes(savedMode as ThemeMode)
155+
) {
156+
dispatch(setThemeMode({ themeMode: savedMode as ThemeMode }))
157+
}
169158
}
170159
}, [dispatch])
171160

packages/mobile/src/screens/settings-screen/AppearanceSettingsRow.tsx

Lines changed: 18 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import { useCallback } from 'react'
22

33
import { useCurrentUserId } from '@audius/common/api'
4-
import { useFeatureFlag } from '@audius/common/hooks'
54
import { settingsMessages as messages } from '@audius/common/messages'
65
import { Name, Theme, ThemeMode, ThemePalette } from '@audius/common/models'
7-
import { FeatureFlags } from '@audius/common/services'
86
import {
97
useTierAndVerifiedForUser,
108
themeActions,
@@ -33,9 +31,6 @@ export const AppearanceSettingsRow = () => {
3331
const { data: accountId } = useCurrentUserId()
3432
const dispatch = useDispatch()
3533
const { tier } = useTierAndVerifiedForUser(accountId)
36-
const { isEnabled: isNewThemeModelEnabled } = useFeatureFlag(
37-
FeatureFlags.NEW_THEME_MODEL
38-
)
3934

4035
const showMatrix =
4136
tier === 'gold' ||
@@ -44,7 +39,7 @@ export const AppearanceSettingsRow = () => {
4439

4540
const effectivePalette =
4641
themePalette ??
47-
(theme === Theme.MATRIX ? ThemePalette.MATRIX : ThemePalette.CLASSIC)
42+
(theme === Theme.MATRIX ? ThemePalette.MATRIX : ThemePalette.DEFAULT)
4843
const effectiveMode =
4944
themeMode ??
5045
(theme === Theme.LIGHT
@@ -53,20 +48,12 @@ export const AppearanceSettingsRow = () => {
5348
? ThemeMode.DARK
5449
: ThemeMode.AUTO)
5550

56-
const appearanceOptions = [
57-
{ key: Theme.AUTO, text: messages.autoMode },
58-
{ key: Theme.LIGHT, text: messages.lightMode },
59-
{ key: Theme.DARK, text: messages.darkMode }
60-
]
61-
62-
if (showMatrix) {
63-
appearanceOptions.push({ key: Theme.MATRIX, text: messages.matrixMode })
64-
}
65-
6651
const paletteOptions = [
6752
{ key: ThemePalette.DEFAULT, text: messages.defaultPalette },
6853
{ key: ThemePalette.CLASSIC, text: messages.classicPalette },
69-
{ key: ThemePalette.MATRIX, text: messages.matrixMode }
54+
...(showMatrix
55+
? [{ key: ThemePalette.MATRIX, text: messages.matrixMode }]
56+
: [])
7057
]
7158

7259
const modeOptions = [
@@ -75,23 +62,6 @@ export const AppearanceSettingsRow = () => {
7562
{ key: ThemeMode.DARK, text: messages.darkMode }
7663
]
7764

78-
const handleSetTheme = useCallback(
79-
(selectedTheme: Theme) => {
80-
dispatch(setTheme({ theme: selectedTheme }))
81-
track(
82-
make({
83-
eventName: Name.SETTINGS_CHANGE_THEME,
84-
mode: selectedTheme.toLowerCase() as
85-
| 'dark'
86-
| 'light'
87-
| 'matrix'
88-
| 'auto'
89-
})
90-
)
91-
},
92-
[dispatch]
93-
)
94-
9565
const handlePaletteChange = useCallback(
9666
(value: ThemePalette) => {
9767
dispatch(setThemePalette({ themePalette: value }))
@@ -140,32 +110,23 @@ export const AppearanceSettingsRow = () => {
140110
{messages.appearanceDescription}
141111
</SettingsRowDescription>
142112
<SettingsRowContent>
143-
{isNewThemeModelEnabled ? (
144-
<Flex direction='column' gap='l'>
145-
<SegmentedControl
146-
fullWidth
147-
options={paletteOptions}
148-
selected={effectivePalette}
149-
onSelectOption={handlePaletteChange}
150-
/>
151-
{effectivePalette !== ThemePalette.MATRIX ? (
152-
<SegmentedControl
153-
fullWidth
154-
options={modeOptions}
155-
selected={effectiveMode}
156-
onSelectOption={handleModeChange}
157-
key={`mode-${effectivePalette}`}
158-
/>
159-
) : null}
160-
</Flex>
161-
) : (
113+
<Flex direction='column' gap='l'>
162114
<SegmentedControl
163115
fullWidth
164-
options={appearanceOptions}
165-
selected={theme ?? Theme.AUTO}
166-
onSelectOption={handleSetTheme}
116+
options={paletteOptions}
117+
selected={effectivePalette}
118+
onSelectOption={handlePaletteChange}
167119
/>
168-
)}
120+
{effectivePalette !== ThemePalette.MATRIX ? (
121+
<SegmentedControl
122+
fullWidth
123+
options={modeOptions}
124+
selected={effectiveMode}
125+
onSelectOption={handleModeChange}
126+
key={`mode-${effectivePalette}`}
127+
/>
128+
) : null}
129+
</Flex>
169130
</SettingsRowContent>
170131
</SettingsRow>
171132
)

packages/web/src/app/ThemeProvider.tsx

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
import { ReactNode, useEffect, useMemo } from 'react'
1+
import { ReactNode, useEffect } from 'react'
22

3-
import { useFeatureFlag } from '@audius/common/hooks'
43
import {
54
SystemAppearance,
65
Theme as LegacyTheme,
76
ThemeMode,
87
ThemePalette
98
} from '@audius/common/models'
10-
import { FeatureFlags } from '@audius/common/services'
119
import { themeActions, themeSelectors } from '@audius/common/store'
1210
import {
1311
resolveTheme,
@@ -68,35 +66,9 @@ type ThemeProviderProps = {
6866
children: ReactNode
6967
}
7068

71-
/**
72-
* When new theme flag is on: classic-* → default-* (upgrade).
73-
* When new theme flag is off: default-* → classic-* (downgrade).
74-
* Matrix is unchanged.
75-
*/
76-
const applyThemeFlag = (
77-
theme: Theme,
78-
isNewThemeModelEnabled: boolean
79-
): Theme => {
80-
if (isNewThemeModelEnabled) {
81-
if (theme === 'classic-light') return 'default-light'
82-
if (theme === 'classic-dark') return 'default-dark'
83-
} else {
84-
if (theme === 'default-light') return 'classic-light'
85-
if (theme === 'default-dark') return 'classic-dark'
86-
}
87-
return theme
88-
}
89-
9069
export const ThemeProvider = (props: ThemeProviderProps) => {
9170
const { children } = props
92-
const harmonyThemeFromState = useSelector(selectHarmonyTheme)
93-
const { isEnabled: isNewThemeModelEnabled } = useFeatureFlag(
94-
FeatureFlags.NEW_THEME_MODEL
95-
)
96-
const harmonyTheme = useMemo(
97-
() => applyThemeFlag(harmonyThemeFromState, isNewThemeModelEnabled),
98-
[harmonyThemeFromState, isNewThemeModelEnabled]
99-
)
71+
const harmonyTheme = useSelector(selectHarmonyTheme)
10072
const dispatch = useDispatch()
10173

10274
useEffect(() => {

packages/web/src/pages/oauth-login-page/hooks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const collapseScopes = (
4747
? raw.filter((t): t is string => typeof t === 'string')
4848
: [raw]
4949
const tokens = strings
50-
.flatMap((s) => s.split(/\s+/))
50+
.flatMap((s) => (s != null ? s.split(/\s+/) : []))
5151
.filter((t) => t.length > 0)
5252
if (tokens.includes('write')) return 'write'
5353
if (tokens.includes('write_once')) return 'write_once'

0 commit comments

Comments
 (0)