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 271629c11..dd0ff2b22 100644
--- a/mobile/src/modules/audio/_screens.tsx
+++ b/mobile/src/modules/audio/_screens.tsx
@@ -1,10 +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/equalizer/components/EQGraph.tsx b/mobile/src/modules/audio/equalizer/components/EQGraph.tsx
similarity index 83%
rename from mobile/src/modules/equalizer/components/EQGraph.tsx
rename to mobile/src/modules/audio/equalizer/components/EQGraph.tsx
index 695e6ca14..dd2b2dea8 100644
--- a/mobile/src/modules/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/equalizer/components/FrequencySlider.tsx b/mobile/src/modules/audio/equalizer/components/FrequencySlider.tsx
similarity index 95%
rename from mobile/src/modules/equalizer/components/FrequencySlider.tsx
rename to mobile/src/modules/audio/equalizer/components/FrequencySlider.tsx
index 1b0639db7..a85863bd6 100644
--- a/mobile/src/modules/equalizer/components/FrequencySlider.tsx
+++ b/mobile/src/modules/audio/equalizer/components/FrequencySlider.tsx
@@ -38,13 +38,14 @@ export const FrequencySlider = memo(function FrequencySlider(props: Props) {
disabled={props.disabled}
hitSlop={10}
anchorAt={0}
+ trackColor="surfaceContainer"
roundedEndStop
vertical
_debounceMultiplier={1}
_className="h-48"
/>
- {bandValue > 0 ? "+" : ""}
+ {bandValue >= 0 ? "+" : ""}
{bandValue / 100}
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/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..d848a63d8 100644
--- a/mobile/src/modules/audio/replayGain/components/ReplayGainSettings.tsx
+++ b/mobile/src/modules/audio/replayGain/components/ReplayGainSettings.tsx
@@ -1,24 +1,22 @@
import { View } from "react-native";
import { usePlaybackStore } from "~/stores/Playback/store";
-import * as ReplayGain from "../core/actions";
-import { DB_OFFSET } from "../core/constants";
+import { toggleStatus } from "../core/actions";
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 (
}
/>
@@ -33,56 +31,10 @@ export function ReplayGainSettings() {
/>
-
-
+
+
);
}
-
-function PreAmpSlider(props: {
- variant: "preAmpWTags" | "preAmpWOTags";
- disabled: boolean;
-}) {
- const preAmpValue = usePlaybackStore((s) => s[props.variant]);
-
- return (
-
-
-
-
-
-
- {preAmpValue >= 0 ? "+" : ""}
- {preAmpValue.toFixed(1)} dB
-
-
-
- );
-}
diff --git a/mobile/src/modules/equalizer/screens/View.tsx b/mobile/src/modules/equalizer/screens/View.tsx
deleted file mode 100644
index 81ccdb366..000000000
--- a/mobile/src/modules/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/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";
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,
})}
>
-