From 8abdd335f6dd92c4e1dd43b1f136f3fd8682c7f5 Mon Sep 17 00:00:00 2001 From: cyanChill <83375816+cyanChill@users.noreply.github.com> Date: Thu, 4 Jun 2026 21:13:47 -0400 Subject: [PATCH 1/9] chore: Move `PreAmpSlider` to its own file --- .../replayGain/components/PreAmpSlider.tsx | 51 +++++++++++++++++ .../components/ReplayGainSettings.tsx | 56 ++----------------- 2 files changed, 55 insertions(+), 52 deletions(-) create mode 100644 mobile/src/modules/audio/replayGain/components/PreAmpSlider.tsx diff --git a/mobile/src/modules/audio/replayGain/components/PreAmpSlider.tsx b/mobile/src/modules/audio/replayGain/components/PreAmpSlider.tsx new file mode 100644 index 000000000..63bbeed17 --- /dev/null +++ b/mobile/src/modules/audio/replayGain/components/PreAmpSlider.tsx @@ -0,0 +1,51 @@ +import { memo } from "react"; +import { View } from "react-native"; + +import { usePlaybackStore } from "~/stores/Playback/store"; +import * as ReplayGain from "../core/actions"; +import { DB_OFFSET } from "../core/constants"; + +import { CachedSlider } from "~/components/Form/Slider"; +import { Em, TEm } from "~/components/Typography/StyledText"; + +export const PreAmpSlider = memo(function PreAmpSlider(props: { + field: "preAmpWTags" | "preAmpWOTags"; + disabled: boolean; +}) { + const preAmpValue = usePlaybackStore((s) => s[props.field]); + return ( + + + + + + + {preAmpValue >= 0 ? "+" : ""} + {preAmpValue.toFixed(1)} dB + + + + ); +}); diff --git a/mobile/src/modules/audio/replayGain/components/ReplayGainSettings.tsx b/mobile/src/modules/audio/replayGain/components/ReplayGainSettings.tsx index f03a86a1b..fc247b4c5 100644 --- a/mobile/src/modules/audio/replayGain/components/ReplayGainSettings.tsx +++ b/mobile/src/modules/audio/replayGain/components/ReplayGainSettings.tsx @@ -2,18 +2,16 @@ import { View } from "react-native"; import { usePlaybackStore } from "~/stores/Playback/store"; import * as ReplayGain from "../core/actions"; -import { DB_OFFSET } from "../core/constants"; import { cn } from "~/lib/style"; import { Divider } from "~/components/Divider"; -import { CachedSlider } from "~/components/Form/Slider"; import { SegmentedList } from "~/components/List/Segmented"; -import { Em, TEm, TStyledText } from "~/components/Typography/StyledText"; +import { TStyledText } from "~/components/Typography/StyledText"; import { Switch } from "~/components/UI/Switch"; +import { PreAmpSlider } from "./PreAmpSlider"; export function ReplayGainSettings() { const isReplayGainEnabled = usePlaybackStore((s) => s.isReplayGainEnabled); - return ( - - + + ); } - -function PreAmpSlider(props: { - variant: "preAmpWTags" | "preAmpWOTags"; - disabled: boolean; -}) { - const preAmpValue = usePlaybackStore((s) => s[props.variant]); - - return ( - - - - - - - {preAmpValue >= 0 ? "+" : ""} - {preAmpValue.toFixed(1)} dB - - - - ); -} From f15f3b657855cf1705370b0e31a7c3d2d7490182 Mon Sep 17 00:00:00 2001 From: cyanChill <83375816+cyanChill@users.noreply.github.com> Date: Thu, 4 Jun 2026 21:16:10 -0400 Subject: [PATCH 2/9] chore: Show a `+` when frequency slider value is 0 - For consistency as we show the `+` at 0 for the Pre-amp slider --- mobile/src/modules/equalizer/components/FrequencySlider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mobile/src/modules/equalizer/components/FrequencySlider.tsx b/mobile/src/modules/equalizer/components/FrequencySlider.tsx index 1b0639db7..730b38edb 100644 --- a/mobile/src/modules/equalizer/components/FrequencySlider.tsx +++ b/mobile/src/modules/equalizer/components/FrequencySlider.tsx @@ -44,7 +44,7 @@ export const FrequencySlider = memo(function FrequencySlider(props: Props) { _className="h-48" /> - {bandValue > 0 ? "+" : ""} + {bandValue >= 0 ? "+" : ""} {bandValue / 100} From bfef52ba1de98a1227dd3ed2a0d6e7ce18a5ec75 Mon Sep 17 00:00:00 2001 From: cyanChill <83375816+cyanChill@users.noreply.github.com> Date: Thu, 4 Jun 2026 21:26:20 -0400 Subject: [PATCH 3/9] chore: Equalizer settings screen is now accessed from "Audio Effects" screen --- mobile/src/modules/audio/_screens.tsx | 18 ++++++++++++++++++ mobile/src/navigation/routes.tsx | 5 ----- .../settings/ExperimentalSettingsView.tsx | 7 ------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/mobile/src/modules/audio/_screens.tsx b/mobile/src/modules/audio/_screens.tsx index 271629c11..46438e1e4 100644 --- a/mobile/src/modules/audio/_screens.tsx +++ b/mobile/src/modules/audio/_screens.tsx @@ -1,10 +1,23 @@ +import { useNavigation } from "@react-navigation/native"; + +import { Equalizer } from "~/resources/icons/Equalizer"; + import { ListLayout } from "~/navigation/layouts/ListLayout"; +import { SegmentedList } from "~/components/List/Segmented"; +import EqualizerSettings from "../equalizer/screens/View"; import { ReplayGainSettings } from "./replayGain/components/ReplayGainSettings"; function AudioEffectsView() { + const navigation = useNavigation(); return ( + navigation.navigate("EqualizerSettings")} + LeftElement={} + className="gap-4" + /> ); @@ -19,6 +32,11 @@ const AudioEffectScreenGroup = { screen: AudioEffectsView, options: { title: "feat.audioEffects.title" }, }, + + EqualizerSettings: { + screen: EqualizerSettings, + options: { title: "feat.equalizer.title" }, + }, }, } as const; diff --git a/mobile/src/navigation/routes.tsx b/mobile/src/navigation/routes.tsx index 9809c2eae..3d9bc08d7 100644 --- a/mobile/src/navigation/routes.tsx +++ b/mobile/src/navigation/routes.tsx @@ -50,7 +50,6 @@ import { ArtistsSheet } from "./sheets/ArtistsSheet"; import AudioEffectScreenGroup from "~/modules/audio/_screens"; import FontScreenGroup from "~/modules/customization/font/screens"; import ThemeScreenGroup from "~/modules/customization/theme/screens"; -import EqualizerSettings from "~/modules/equalizer/screens/View"; import LyricScreenGroup from "~/modules/lyric/screens"; import Search from "~/modules/search/screens/View"; @@ -317,10 +316,6 @@ export const RootStack = createNativeStackNavigator({ screen: AppearanceSettings, options: { title: "feat.appearance.title" }, }, - EqualizerSettings: { - screen: EqualizerSettings, - options: { title: "feat.equalizer.title" }, - }, Insights: { screen: Insights, options: { title: "feat.insights.title" }, diff --git a/mobile/src/navigation/screens/settings/ExperimentalSettingsView.tsx b/mobile/src/navigation/screens/settings/ExperimentalSettingsView.tsx index 4b849de61..8c2a37304 100644 --- a/mobile/src/navigation/screens/settings/ExperimentalSettingsView.tsx +++ b/mobile/src/navigation/screens/settings/ExperimentalSettingsView.tsx @@ -5,7 +5,6 @@ import { useTranslation } from "react-i18next"; import { db } from "~/db"; import { waveformSamples } from "~/db/schema"; -import { Equalizer } from "~/resources/icons/Equalizer"; import { GraphicEQ } from "~/resources/icons/GraphicEQ"; import { OpenInNew } from "~/resources/icons/OpenInNew"; import { Search } from "~/resources/icons/Search"; @@ -65,12 +64,6 @@ export default function ExperimentalSettings() { LeftElement={} className="gap-4" /> - navigation.navigate("EqualizerSettings")} - LeftElement={} - className="gap-4" - /> Date: Thu, 4 Jun 2026 21:30:51 -0400 Subject: [PATCH 4/9] chore: Show link to "Audio Effects" screen instead of "Equalizer" from "Playback Options" sheet --- .../now-playing/sheets/PlaybackOptionsSheet.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mobile/src/navigation/screens/now-playing/sheets/PlaybackOptionsSheet.tsx b/mobile/src/navigation/screens/now-playing/sheets/PlaybackOptionsSheet.tsx index 031a99353..973d44e4f 100644 --- a/mobile/src/navigation/screens/now-playing/sheets/PlaybackOptionsSheet.tsx +++ b/mobile/src/navigation/screens/now-playing/sheets/PlaybackOptionsSheet.tsx @@ -3,7 +3,7 @@ import { useCallback, useState } from "react"; import AudioBrowser from "react-native-audio-browser"; import { ActivityZone } from "~/resources/icons/ActivityZone"; -import { Equalizer } from "~/resources/icons/Equalizer"; +import { GraphicEQ } from "~/resources/icons/GraphicEQ"; import { SlowMotionVideo } from "~/resources/icons/SlowMotionVideo"; import { VolumeUp } from "~/resources/icons/VolumeUp"; import { usePlaybackStore } from "~/stores/Playback/store"; @@ -58,9 +58,9 @@ export function PlaybackOptionsSheet(props: { navigation.navigate(...getMediaLinkContext(playingSource)); }, [navigation, props.ref, playingSource]); - const navigateToEQSettings = useCallback(async () => { + const navigateToAudioEffectsScree = useCallback(async () => { await props.ref.current?.dismiss(); - navigation.navigate("EqualizerSettings"); + navigation.navigate("AudioEffects"); }, [navigation, props.ref]); //#region Sheet Presenters @@ -147,9 +147,9 @@ export function PlaybackOptionsSheet(props: { className="gap-4" /> } + labelTextKey="feat.audioEffects.title" + onPress={navigateToAudioEffectsScree} + LeftElement={} className="gap-4" /> Date: Thu, 4 Jun 2026 21:33:54 -0400 Subject: [PATCH 5/9] chore: Have equalizer code be under `~/modules/audio` --- mobile/src/modules/audio/_screens.tsx | 2 +- .../modules/{ => audio}/equalizer/components/EQGraph.tsx | 0 .../{ => audio}/equalizer/components/FrequencySlider.tsx | 0 mobile/src/modules/{ => audio}/equalizer/core/actions.ts | 0 mobile/src/modules/{ => audio}/equalizer/core/constants.ts | 0 mobile/src/modules/{ => audio}/equalizer/core/store.ts | 0 mobile/src/modules/{ => audio}/equalizer/screens/View.tsx | 0 mobile/src/modules/scanning/hooks/useSetup.ts | 7 +++++-- 8 files changed, 6 insertions(+), 3 deletions(-) rename mobile/src/modules/{ => audio}/equalizer/components/EQGraph.tsx (100%) rename mobile/src/modules/{ => audio}/equalizer/components/FrequencySlider.tsx (100%) rename mobile/src/modules/{ => audio}/equalizer/core/actions.ts (100%) rename mobile/src/modules/{ => audio}/equalizer/core/constants.ts (100%) rename mobile/src/modules/{ => audio}/equalizer/core/store.ts (100%) rename mobile/src/modules/{ => audio}/equalizer/screens/View.tsx (100%) diff --git a/mobile/src/modules/audio/_screens.tsx b/mobile/src/modules/audio/_screens.tsx index 46438e1e4..4486ff22f 100644 --- a/mobile/src/modules/audio/_screens.tsx +++ b/mobile/src/modules/audio/_screens.tsx @@ -5,7 +5,7 @@ import { Equalizer } from "~/resources/icons/Equalizer"; import { ListLayout } from "~/navigation/layouts/ListLayout"; import { SegmentedList } from "~/components/List/Segmented"; -import EqualizerSettings from "../equalizer/screens/View"; +import EqualizerSettings from "./equalizer/screens/View"; import { ReplayGainSettings } from "./replayGain/components/ReplayGainSettings"; function AudioEffectsView() { diff --git a/mobile/src/modules/equalizer/components/EQGraph.tsx b/mobile/src/modules/audio/equalizer/components/EQGraph.tsx similarity index 100% rename from mobile/src/modules/equalizer/components/EQGraph.tsx rename to mobile/src/modules/audio/equalizer/components/EQGraph.tsx diff --git a/mobile/src/modules/equalizer/components/FrequencySlider.tsx b/mobile/src/modules/audio/equalizer/components/FrequencySlider.tsx similarity index 100% rename from mobile/src/modules/equalizer/components/FrequencySlider.tsx rename to mobile/src/modules/audio/equalizer/components/FrequencySlider.tsx diff --git a/mobile/src/modules/equalizer/core/actions.ts b/mobile/src/modules/audio/equalizer/core/actions.ts similarity index 100% rename from mobile/src/modules/equalizer/core/actions.ts rename to mobile/src/modules/audio/equalizer/core/actions.ts diff --git a/mobile/src/modules/equalizer/core/constants.ts b/mobile/src/modules/audio/equalizer/core/constants.ts similarity index 100% rename from mobile/src/modules/equalizer/core/constants.ts rename to mobile/src/modules/audio/equalizer/core/constants.ts diff --git a/mobile/src/modules/equalizer/core/store.ts b/mobile/src/modules/audio/equalizer/core/store.ts similarity index 100% rename from mobile/src/modules/equalizer/core/store.ts rename to mobile/src/modules/audio/equalizer/core/store.ts diff --git a/mobile/src/modules/equalizer/screens/View.tsx b/mobile/src/modules/audio/equalizer/screens/View.tsx similarity index 100% rename from mobile/src/modules/equalizer/screens/View.tsx rename to mobile/src/modules/audio/equalizer/screens/View.tsx diff --git a/mobile/src/modules/scanning/hooks/useSetup.ts b/mobile/src/modules/scanning/hooks/useSetup.ts index e1c1072a8..09c3f3965 100644 --- a/mobile/src/modules/scanning/hooks/useSetup.ts +++ b/mobile/src/modules/scanning/hooks/useSetup.ts @@ -9,8 +9,11 @@ import { preferenceStore, usePreferenceStore } from "~/stores/Preference/store"; import { equalizerStore, useEqualizerStore, -} from "~/modules/equalizer/core/store"; -import { _initEQStore, setEQPreset } from "~/modules/equalizer/core/actions"; +} from "~/modules/audio/equalizer/core/store"; +import { + _initEQStore, + setEQPreset, +} from "~/modules/audio/equalizer/core/actions"; import { useLyricStore } from "~/modules/lyric/core/store"; import { getAudioBrowserOptions } from "~/lib/react-native-audio-browser"; From 490e2cd19f7d9cd3520b1e6e3f1a8e6b042b5dab Mon Sep 17 00:00:00 2001 From: cyanChill <83375816+cyanChill@users.noreply.github.com> Date: Thu, 4 Jun 2026 22:04:57 -0400 Subject: [PATCH 6/9] chore: Move Equalizer Settings "screen" into a "card" - Follows the same idea as the "ReplayGain Pre-amp" feature. --- mobile/src/modules/audio/_screens.tsx | 20 +---- .../audio/equalizer/components/EQGraph.tsx | 49 +++++----- .../components/EqualizerSettings.tsx | 89 ++++++++++++++++++ .../equalizer/components/FrequencySlider.tsx | 1 + .../modules/audio/equalizer/screens/View.tsx | 90 ------------------- .../components/ReplayGainSettings.tsx | 4 +- mobile/src/resources/icons/Equalizer.tsx | 13 --- 7 files changed, 120 insertions(+), 146 deletions(-) create mode 100644 mobile/src/modules/audio/equalizer/components/EqualizerSettings.tsx delete mode 100644 mobile/src/modules/audio/equalizer/screens/View.tsx delete mode 100644 mobile/src/resources/icons/Equalizer.tsx diff --git a/mobile/src/modules/audio/_screens.tsx b/mobile/src/modules/audio/_screens.tsx index 4486ff22f..585c23fb4 100644 --- a/mobile/src/modules/audio/_screens.tsx +++ b/mobile/src/modules/audio/_screens.tsx @@ -1,23 +1,12 @@ -import { useNavigation } from "@react-navigation/native"; - -import { Equalizer } from "~/resources/icons/Equalizer"; - import { ListLayout } from "~/navigation/layouts/ListLayout"; -import { SegmentedList } from "~/components/List/Segmented"; -import EqualizerSettings from "./equalizer/screens/View"; +import { EqualizerSettings } from "./equalizer/components/EqualizerSettings"; import { ReplayGainSettings } from "./replayGain/components/ReplayGainSettings"; function AudioEffectsView() { - const navigation = useNavigation(); return ( - navigation.navigate("EqualizerSettings")} - LeftElement={} - className="gap-4" - /> + ); @@ -32,11 +21,6 @@ const AudioEffectScreenGroup = { screen: AudioEffectsView, options: { title: "feat.audioEffects.title" }, }, - - EqualizerSettings: { - screen: EqualizerSettings, - options: { title: "feat.equalizer.title" }, - }, }, } as const; diff --git a/mobile/src/modules/audio/equalizer/components/EQGraph.tsx b/mobile/src/modules/audio/equalizer/components/EQGraph.tsx index 695e6ca14..dd2b2dea8 100644 --- a/mobile/src/modules/audio/equalizer/components/EQGraph.tsx +++ b/mobile/src/modules/audio/equalizer/components/EQGraph.tsx @@ -1,5 +1,5 @@ -import { useMemo } from "react"; -import { View, useWindowDimensions } from "react-native"; +import { createContext, use, useMemo, useState } from "react"; +import { View } from "react-native"; import { Circle, Defs, @@ -12,6 +12,7 @@ import { import { useEqualizerStore } from "../core/store"; import { OnRTL } from "~/lib/react"; +import { cn } from "~/lib/style"; import { Em } from "~/components/Typography/StyledText"; import { useTheme } from "~/modules/customization/theme/hooks"; @@ -21,19 +22,29 @@ const ClampedOrdinate = Ordinate - YPadding; const GraphHeight = Ordinate * 2 + 1; const XAxisYPos = Ordinate + 1; +/** Store graph width in a context as we may render it in other content. */ +const GraphWidthContext = createContext(0); + /** Graph displaying Equalizer configuration based on the Nothing X design. */ export function EQGraph(props: EQLineProps) { + const [graphWidth, setGraphWidth] = useState(0); return ( - - - - - - - + + setGraphWidth(e.nativeEvent.layout.width)} + style={{ height: GraphHeight }} + className={cn( + "relative mb-4 w-full rounded-md bg-surfaceContainerLow", + { "opacity-0": graphWidth === 0 }, + )} + > + + + + + + + ); } @@ -45,7 +56,7 @@ interface EQLineProps { function EQLine(props: EQLineProps) { const { scheme, onSurfaceVariant, surfaceContainerHigh } = useTheme(); - const width = useGraphWidth(); + const width = use(GraphWidthContext); const eqBandOrdinate = useEqualizerStore((s) => s.bandOrdinate); const points = useMemo( @@ -130,7 +141,7 @@ const DisplayedFrequencies = [ /** Draws x-axis and tick marks for certain frequencies. */ function GraphAnnotations() { - const width = useGraphWidth(); + const width = use(GraphWidthContext); const { surfaceContainer } = useTheme(); return ( <> @@ -159,7 +170,7 @@ function GraphAnnotations() { * navigating back when in ``. */ function GraphLabels() { - const width = useGraphWidth(); + const width = use(GraphWidthContext); return DisplayedFrequencies.map(({ label, xPosPercent }) => ( s.defaultFrequencies); + const eqPresets = useEqualizerStore((s) => s.defaultPresets); + const activePreset = useEqualizerStore((s) => s.preset); + + const currEQ = useEqualizerSettings(); + const isEQEnabled = Boolean(currEQ?.enabled); + + const eqDataPoints = useMemo( + () => + eqFreqs.map((freq, index) => ({ + x: freq, + y: currEQ?.bandLevels[index] ?? 0, + })), + [eqFreqs, currEQ?.bandLevels], + ); + + return ( + + } + /> + + + + + + {currEQ?.bandLevels.map((level, index) => ( + + ))} + + + + {eqPresets.map((preset) => { + const isActive = activePreset === preset; + return ( + + ); + })} + + + + + ); +} diff --git a/mobile/src/modules/audio/equalizer/components/FrequencySlider.tsx b/mobile/src/modules/audio/equalizer/components/FrequencySlider.tsx index 730b38edb..a85863bd6 100644 --- a/mobile/src/modules/audio/equalizer/components/FrequencySlider.tsx +++ b/mobile/src/modules/audio/equalizer/components/FrequencySlider.tsx @@ -38,6 +38,7 @@ export const FrequencySlider = memo(function FrequencySlider(props: Props) { disabled={props.disabled} hitSlop={10} anchorAt={0} + trackColor="surfaceContainer" roundedEndStop vertical _debounceMultiplier={1} diff --git a/mobile/src/modules/audio/equalizer/screens/View.tsx b/mobile/src/modules/audio/equalizer/screens/View.tsx deleted file mode 100644 index 81ccdb366..000000000 --- a/mobile/src/modules/audio/equalizer/screens/View.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import type { ParseKeys } from "i18next"; -import { useMemo } from "react"; -import { View } from "react-native"; -import { useEqualizerSettings } from "react-native-audio-browser"; - -import { useEqualizerStore } from "../core/store"; -import { toggleEQ, setEQPreset } from "../core/actions"; - -import { ListLayout } from "~/navigation/layouts/ListLayout"; -import { ScreenOptions } from "~/navigation/components/ScreenOptions"; - -import { OnRTL } from "~/lib/react"; -import { cn } from "~/lib/style"; -import { Pressable } from "~/components/Base/Pressable"; -import { Button } from "~/components/Form/Button"; -import { TStyledText } from "~/components/Typography/StyledText"; -import { Switch } from "~/components/UI/Switch"; -import { EQGraph } from "../components/EQGraph"; -import { FrequencySlider } from "../components/FrequencySlider"; - -export default function EqualizerSettings() { - const eqFreqs = useEqualizerStore((s) => s.defaultFrequencies); - const eqPresets = useEqualizerStore((s) => s.defaultPresets); - const activePreset = useEqualizerStore((s) => s.preset); - - const currEQ = useEqualizerSettings(); - - const eqDataPoints = useMemo( - () => - eqFreqs.map((freq, index) => ({ - x: freq, - y: currEQ?.bandLevels[index] ?? 0, - })), - [eqFreqs, currEQ?.bandLevels], - ); - - return ( - <> - ( - - - - )} - /> - - - - - {currEQ?.bandLevels.map((level, index) => ( - - ))} - - - - {eqPresets.map((preset) => { - const isActive = activePreset === preset; - return ( - - ); - })} - - - - ); -} diff --git a/mobile/src/modules/audio/replayGain/components/ReplayGainSettings.tsx b/mobile/src/modules/audio/replayGain/components/ReplayGainSettings.tsx index fc247b4c5..d848a63d8 100644 --- a/mobile/src/modules/audio/replayGain/components/ReplayGainSettings.tsx +++ b/mobile/src/modules/audio/replayGain/components/ReplayGainSettings.tsx @@ -1,7 +1,7 @@ import { View } from "react-native"; import { usePlaybackStore } from "~/stores/Playback/store"; -import * as ReplayGain from "../core/actions"; +import { toggleStatus } from "../core/actions"; import { cn } from "~/lib/style"; import { Divider } from "~/components/Divider"; @@ -16,7 +16,7 @@ export function ReplayGainSettings() { } /> diff --git a/mobile/src/resources/icons/Equalizer.tsx b/mobile/src/resources/icons/Equalizer.tsx deleted file mode 100644 index 6464f9824..000000000 --- a/mobile/src/resources/icons/Equalizer.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import Svg, { Path } from "react-native-svg"; - -import { useColor } from "~/modules/customization/theme/hooks"; -import type { Icon } from "./type"; - -export function Equalizer({ size = 24, color }: Icon) { - const usedColor = useColor(color, "onSurface"); - return ( - - - - ); -} From 8162c2bc41db45a58bf8c3cb3bd8f4201b9ae2a7 Mon Sep 17 00:00:00 2001 From: cyanChill <83375816+cyanChill@users.noreply.github.com> Date: Thu, 4 Jun 2026 22:14:22 -0400 Subject: [PATCH 7/9] fix: Seeing the marquee when pressing on the miniplayer - This bugged me a bit and the cause was due to us changing the background color on press, but not the marquee color. --- mobile/src/navigation/components/MiniPlayer.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mobile/src/navigation/components/MiniPlayer.tsx b/mobile/src/navigation/components/MiniPlayer.tsx index 470a4dcde..ac0d65f56 100644 --- a/mobile/src/navigation/components/MiniPlayer.tsx +++ b/mobile/src/navigation/components/MiniPlayer.tsx @@ -136,10 +136,10 @@ export function MiniPlayer() { "bg-surfaceContainerLow": gestureUI && isPressed, })} > - + {track.name} - + {getArtistsString(track.artists)} From 18b876d2146eb91bbc7142b618972db68bb0bddb Mon Sep 17 00:00:00 2001 From: cyanChill <83375816+cyanChill@users.noreply.github.com> Date: Thu, 4 Jun 2026 22:39:33 -0400 Subject: [PATCH 8/9] chore: Display "Playback Speed" setting in "Audio Effects" screen - It'll only show up in the "Audio Effects" screen if we navigate here via the "Playback Options" sheet. --- .../_components/PlaybackSpeedSetting.tsx} | 20 +++++++++---------- mobile/src/modules/audio/_screens.tsx | 12 ++++++++++- .../components/EqualizerSettings.tsx | 2 +- .../sheets/PlaybackOptionsSheet.tsx | 17 +--------------- .../settings/ExperimentalSettingsView.tsx | 2 +- 5 files changed, 23 insertions(+), 30 deletions(-) rename mobile/src/{navigation/screens/now-playing/sheets/PlaybackSpeedSheet.tsx => modules/audio/_components/PlaybackSpeedSetting.tsx} (79%) diff --git a/mobile/src/navigation/screens/now-playing/sheets/PlaybackSpeedSheet.tsx b/mobile/src/modules/audio/_components/PlaybackSpeedSetting.tsx similarity index 79% rename from mobile/src/navigation/screens/now-playing/sheets/PlaybackSpeedSheet.tsx rename to mobile/src/modules/audio/_components/PlaybackSpeedSetting.tsx index 09f3c45f2..6efac0f8b 100644 --- a/mobile/src/navigation/screens/now-playing/sheets/PlaybackSpeedSheet.tsx +++ b/mobile/src/modules/audio/_components/PlaybackSpeedSetting.tsx @@ -1,4 +1,3 @@ -import { useState } from "react"; import { View } from "react-native"; import AudioBrowser from "react-native-audio-browser"; import type { SharedValue } from "react-native-reanimated"; @@ -9,21 +8,19 @@ import { sessionStore, useSessionStore } from "~/stores/Session/store"; import { Button } from "~/components/Form/Button"; import { CachedSlider } from "~/components/Form/Slider"; -import { DetachedSheet } from "~/components/Sheet"; -import type { TrueSheetRef } from "~/components/Sheet/useSheetRef"; -import { Em } from "~/components/Typography/StyledText"; +import { SegmentedList } from "~/components/List/Segmented"; +import { Em, TStyledText } from "~/components/Typography/StyledText"; -export function PlaybackSpeedSheet(props: { ref: TrueSheetRef }) { - const [stopDrag, setStopDrag] = useState(false); +export function PlaybackSpeedSetting() { const playbackSpeed = useSessionStore((s) => s.playbackSpeed); const cachedPlaybackSpeed = useSharedValue(playbackSpeed); return ( - + + @@ -32,7 +29,7 @@ export function PlaybackSpeedSheet(props: { ref: TrueSheetRef }) { - + ); } @@ -47,7 +44,7 @@ function PlaybackSpeedPreset(props: { setPlaybackSpeed(props.preset); props.value.set(props.preset); }} - className="min-h-8 flex-1 rounded-full py-2 active:bg-surfaceContainer" + className="min-h-8 flex-1 rounded-full bg-surfaceContainerLow py-2 active:bg-surfaceContainer" > {formatValue(props.preset)} @@ -76,10 +73,11 @@ const PlaybackSpeedSliderOptions = { step: 0.05, thickness: 48, onChange: setPlaybackSpeed, + trackColor: "surfaceContainer", overlay: { accessibilityLabelKey: "feat.playback.extra.speed" as const, Icon: SlowMotionVideo, formatValue, }, -}; +} as const; //#endregion diff --git a/mobile/src/modules/audio/_screens.tsx b/mobile/src/modules/audio/_screens.tsx index 585c23fb4..dd0ff2b22 100644 --- a/mobile/src/modules/audio/_screens.tsx +++ b/mobile/src/modules/audio/_screens.tsx @@ -1,12 +1,22 @@ +import type { StaticScreenProps } from "@react-navigation/native"; + import { ListLayout } from "~/navigation/layouts/ListLayout"; +import { PlaybackSpeedSetting } from "./_components/PlaybackSpeedSetting"; import { EqualizerSettings } from "./equalizer/components/EqualizerSettings"; import { ReplayGainSettings } from "./replayGain/components/ReplayGainSettings"; -function AudioEffectsView() { +type Props = StaticScreenProps<{ showHidden?: boolean }>; + +function AudioEffectsView({ + route: { + params: { showHidden }, + }, +}: Props) { return ( + {showHidden ? : null} ); diff --git a/mobile/src/modules/audio/equalizer/components/EqualizerSettings.tsx b/mobile/src/modules/audio/equalizer/components/EqualizerSettings.tsx index 8cac72146..2401cf7d9 100644 --- a/mobile/src/modules/audio/equalizer/components/EqualizerSettings.tsx +++ b/mobile/src/modules/audio/equalizer/components/EqualizerSettings.tsx @@ -70,7 +70,7 @@ export function EqualizerSettings() { onPress={() => setEQPreset(preset)} disabled={!currEQ?.enabled} className={cn( - "min-h-auto rounded-full bg-surfaceContainerLow py-2 disabled:opacity-100", + "min-h-auto rounded-full bg-surfaceContainerLow py-2 active:bg-surfaceContainer disabled:opacity-100", { "bg-primary active:bg-primaryDim": isActive }, )} > diff --git a/mobile/src/navigation/screens/now-playing/sheets/PlaybackOptionsSheet.tsx b/mobile/src/navigation/screens/now-playing/sheets/PlaybackOptionsSheet.tsx index 973d44e4f..f5513ad7a 100644 --- a/mobile/src/navigation/screens/now-playing/sheets/PlaybackOptionsSheet.tsx +++ b/mobile/src/navigation/screens/now-playing/sheets/PlaybackOptionsSheet.tsx @@ -4,7 +4,6 @@ import AudioBrowser from "react-native-audio-browser"; import { ActivityZone } from "~/resources/icons/ActivityZone"; import { GraphicEQ } from "~/resources/icons/GraphicEQ"; -import { SlowMotionVideo } from "~/resources/icons/SlowMotionVideo"; import { VolumeUp } from "~/resources/icons/VolumeUp"; import { usePlaybackStore } from "~/stores/Playback/store"; import { usePreferenceStore } from "~/stores/Preference/store"; @@ -18,7 +17,6 @@ import { toggleLyricVisibility } from "~/modules/lyric/core/actions"; import { getMediaLinkContext } from "~/navigation/utils/router"; import { AppearanceSheet } from "./AppearanceSheet"; -import { PlaybackSpeedSheet } from "./PlaybackSpeedSheet"; import { Pressable } from "~/components/Base/Pressable"; import { ScrollView } from "~/components/Base/ScrollView"; @@ -46,7 +44,6 @@ export function PlaybackOptionsSheet(props: { const waveformSlider = usePreferenceStore((s) => s.waveformSlider); const volume = useSessionStore((s) => s.volume); const appearanceSheetRef = useSheetRef(); - const playbackSpeedRef = useSheetRef(); const sheetListHandlers = useEnableSheetScroll(true); const navigateToList = useCallback(async () => { @@ -60,7 +57,7 @@ export function PlaybackOptionsSheet(props: { const navigateToAudioEffectsScree = useCallback(async () => { await props.ref.current?.dismiss(); - navigation.navigate("AudioEffects"); + navigation.navigate("AudioEffects", { showHidden: true }); }, [navigation, props.ref]); //#region Sheet Presenters @@ -68,17 +65,11 @@ export function PlaybackOptionsSheet(props: { await props.ref.current?.dismiss(); appearanceSheetRef.current?.present(); }, [appearanceSheetRef, props.ref]); - - const presentPlaybackSheet = useCallback(async () => { - await props.ref.current?.dismiss(); - playbackSpeedRef.current?.present(); - }, [playbackSpeedRef, props.ref]); //#endregion return ( <> - } className="gap-4" /> - } - className="gap-4" - /> diff --git a/mobile/src/navigation/screens/settings/ExperimentalSettingsView.tsx b/mobile/src/navigation/screens/settings/ExperimentalSettingsView.tsx index 8c2a37304..b80102cb9 100644 --- a/mobile/src/navigation/screens/settings/ExperimentalSettingsView.tsx +++ b/mobile/src/navigation/screens/settings/ExperimentalSettingsView.tsx @@ -60,7 +60,7 @@ export default function ExperimentalSettings() { /> navigation.navigate("AudioEffects")} + onPress={() => navigation.navigate("AudioEffects", {})} LeftElement={} className="gap-4" /> From 6df987e07dbedd2ded6b3329235bfe37741451ca Mon Sep 17 00:00:00 2001 From: cyanChill <83375816+cyanChill@users.noreply.github.com> Date: Thu, 4 Jun 2026 22:54:56 -0400 Subject: [PATCH 9/9] fix: Lint --- .../screens/now-playing/sheets/PlaybackOptionsSheet.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mobile/src/navigation/screens/now-playing/sheets/PlaybackOptionsSheet.tsx b/mobile/src/navigation/screens/now-playing/sheets/PlaybackOptionsSheet.tsx index f5513ad7a..bd2aff2ca 100644 --- a/mobile/src/navigation/screens/now-playing/sheets/PlaybackOptionsSheet.tsx +++ b/mobile/src/navigation/screens/now-playing/sheets/PlaybackOptionsSheet.tsx @@ -55,7 +55,7 @@ export function PlaybackOptionsSheet(props: { navigation.navigate(...getMediaLinkContext(playingSource)); }, [navigation, props.ref, playingSource]); - const navigateToAudioEffectsScree = useCallback(async () => { + const navigateToAudioEffectsScreen = useCallback(async () => { await props.ref.current?.dismiss(); navigation.navigate("AudioEffects", { showHidden: true }); }, [navigation, props.ref]); @@ -139,7 +139,7 @@ export function PlaybackOptionsSheet(props: { /> } className="gap-4" />