From bf6010b3c7d6870ed892c5ab7939bc30b7a982d5 Mon Sep 17 00:00:00 2001 From: Gauvain Date: Thu, 4 Jun 2026 12:16:13 +0200 Subject: [PATCH] refactor(settings): rebuild Playback & Controls interior with typed rows + translate Chromecast --- components/settings/ChromecastSettings.tsx | 23 +-- components/settings/GestureControls.tsx | 83 ++++----- components/settings/MediaToggles.tsx | 43 ++--- components/settings/MpvBufferSettings.tsx | 87 ++++----- components/settings/MpvVoSettings.tsx | 27 +-- .../settings/PlaybackControlsSettings.tsx | 167 ++++++------------ translations/en.json | 4 + 7 files changed, 157 insertions(+), 277 deletions(-) diff --git a/components/settings/ChromecastSettings.tsx b/components/settings/ChromecastSettings.tsx index 4da06332f..e54926efe 100644 --- a/components/settings/ChromecastSettings.tsx +++ b/components/settings/ChromecastSettings.tsx @@ -1,21 +1,22 @@ -import { Switch, View } from "react-native"; +import { useTranslation } from "react-i18next"; +import { View } from "react-native"; +import { SettingsSwitchRow } from "@/components/settings/index/SettingsSwitchRow"; import { useSettings } from "@/utils/atoms/settings"; import { ListGroup } from "../list/ListGroup"; -import { ListItem } from "../list/ListItem"; export const ChromecastSettings: React.FC = ({ ...props }) => { const { settings, updateSettings } = useSettings(); + const { t } = useTranslation(); return ( - - - - updateSettings({ enableH265ForChromecast }) - } - /> - + + + updateSettings({ enableH265ForChromecast }) + } + /> ); diff --git a/components/settings/GestureControls.tsx b/components/settings/GestureControls.tsx index b9c39ef47..777dfd31a 100644 --- a/components/settings/GestureControls.tsx +++ b/components/settings/GestureControls.tsx @@ -2,11 +2,10 @@ import type React from "react"; import { useMemo } from "react"; import { useTranslation } from "react-i18next"; import type { ViewProps } from "react-native"; -import { Switch } from "react-native"; import DisabledSetting from "@/components/settings/DisabledSetting"; +import { SettingsSwitchRow } from "@/components/settings/index/SettingsSwitchRow"; import { useSettings } from "@/utils/atoms/settings"; import { ListGroup } from "../list/ListGroup"; -import { ListItem } from "../list/ListItem"; interface Props extends ViewProps {} @@ -32,85 +31,65 @@ export const GestureControls: React.FC = ({ ...props }) => { - - - updateSettings({ enableHorizontalSwipeSkip }) - } - /> - + value={settings.enableHorizontalSwipeSkip} + onValueChange={(enableHorizontalSwipeSkip) => + updateSettings({ enableHorizontalSwipeSkip }) + } + /> - - - updateSettings({ enableLeftSideBrightnessSwipe }) - } - /> - + value={settings.enableLeftSideBrightnessSwipe} + onValueChange={(enableLeftSideBrightnessSwipe) => + updateSettings({ enableLeftSideBrightnessSwipe }) + } + /> - - - updateSettings({ enableRightSideVolumeSwipe }) - } - /> - + value={settings.enableRightSideVolumeSwipe} + onValueChange={(enableRightSideVolumeSwipe) => + updateSettings({ enableRightSideVolumeSwipe }) + } + /> - - - updateSettings({ hideVolumeSlider }) - } - /> - + value={settings.hideVolumeSlider} + onValueChange={(hideVolumeSlider) => + updateSettings({ hideVolumeSlider }) + } + /> - - - updateSettings({ hideBrightnessSlider }) - } - /> - + value={settings.hideBrightnessSlider} + onValueChange={(hideBrightnessSlider) => + updateSettings({ hideBrightnessSlider }) + } + /> ); diff --git a/components/settings/MediaToggles.tsx b/components/settings/MediaToggles.tsx index c01a6d136..52c631610 100644 --- a/components/settings/MediaToggles.tsx +++ b/components/settings/MediaToggles.tsx @@ -2,11 +2,10 @@ import type React from "react"; import { useMemo } from "react"; import { useTranslation } from "react-i18next"; import type { ViewProps } from "react-native"; -import { Stepper } from "@/components/inputs/Stepper"; import DisabledSetting from "@/components/settings/DisabledSetting"; +import { SettingsStepperRow } from "@/components/settings/index/SettingsStepperRow"; import { useSettings } from "@/utils/atoms/settings"; import { ListGroup } from "../list/ListGroup"; -import { ListItem } from "../list/ListItem"; interface Props extends ViewProps {} @@ -27,35 +26,27 @@ export const MediaToggles: React.FC = ({ ...props }) => { return ( - - updateSettings({ forwardSkipTime })} - /> - + value={settings.forwardSkipTime} + step={5} + appendValue={t("home.settings.media_controls.seconds_unit")} + min={0} + max={60} + onUpdate={(forwardSkipTime) => updateSettings({ forwardSkipTime })} + /> - - updateSettings({ rewindSkipTime })} - /> - + value={settings.rewindSkipTime} + step={5} + appendValue={t("home.settings.media_controls.seconds_unit")} + min={0} + max={60} + onUpdate={(rewindSkipTime) => updateSettings({ rewindSkipTime })} + /> ); diff --git a/components/settings/MpvBufferSettings.tsx b/components/settings/MpvBufferSettings.tsx index 6df374123..aad861af1 100644 --- a/components/settings/MpvBufferSettings.tsx +++ b/components/settings/MpvBufferSettings.tsx @@ -1,14 +1,10 @@ -import { Ionicons } from "@expo/vector-icons"; import type React from "react"; import { useMemo } from "react"; import { useTranslation } from "react-i18next"; -import { View } from "react-native"; -import { Stepper } from "@/components/inputs/Stepper"; -import { PlatformDropdown } from "@/components/PlatformDropdown"; +import { SettingsSelectRow } from "@/components/settings/index/SettingsSelectRow"; +import { SettingsStepperRow } from "@/components/settings/index/SettingsStepperRow"; import { type MpvCacheMode, useSettings } from "@/utils/atoms/settings"; -import { Text } from "../common/Text"; import { ListGroup } from "../list/ListGroup"; -import { ListItem } from "../list/ListItem"; const CACHE_MODE_OPTIONS: { key: string; value: MpvCacheMode }[] = [ { key: "home.settings.buffer.cache_auto", value: "auto" }, @@ -46,55 +42,42 @@ export const MpvBufferSettings: React.FC = () => { return ( - - - - {currentCacheModeLabel} - - - - } - title={t("home.settings.buffer.cache_mode")} - /> - + - - updateSettings({ mpvCacheSeconds: value })} - appendValue='s' - /> - + updateSettings({ mpvCacheSeconds: value })} + appendValue='s' + /> - - updateSettings({ mpvDemuxerMaxBytes: value })} - appendValue=' MB' - /> - + updateSettings({ mpvDemuxerMaxBytes: value })} + appendValue=' MB' + /> - - - updateSettings({ mpvDemuxerMaxBackBytes: value }) - } - appendValue=' MB' - /> - + updateSettings({ mpvDemuxerMaxBackBytes: value })} + appendValue=' MB' + /> ); }; diff --git a/components/settings/MpvVoSettings.tsx b/components/settings/MpvVoSettings.tsx index 164829c41..7d56c8375 100644 --- a/components/settings/MpvVoSettings.tsx +++ b/components/settings/MpvVoSettings.tsx @@ -1,13 +1,10 @@ -import { Ionicons } from "@expo/vector-icons"; import type React from "react"; import { useMemo } from "react"; import { useTranslation } from "react-i18next"; -import { Platform, View } from "react-native"; -import { PlatformDropdown } from "@/components/PlatformDropdown"; +import { Platform } from "react-native"; +import { SettingsSelectRow } from "@/components/settings/index/SettingsSelectRow"; import { type MpvVoDriver, useSettings } from "@/utils/atoms/settings"; -import { Text } from "../common/Text"; import { ListGroup } from "../list/ListGroup"; -import { ListItem } from "../list/ListItem"; const VO_DRIVER_OPTIONS: { key: string; value: MpvVoDriver }[] = [ { key: "home.settings.vo_driver.gpu_next", value: "gpu-next" }, @@ -47,20 +44,12 @@ export const MpvVoSettings: React.FC = () => { return ( - - - - {currentVoDriverLabel} - - - - } - title={t("home.settings.vo_driver.vo_mode")} - /> - + ); }; diff --git a/components/settings/PlaybackControlsSettings.tsx b/components/settings/PlaybackControlsSettings.tsx index 17ee53679..1110a0880 100644 --- a/components/settings/PlaybackControlsSettings.tsx +++ b/components/settings/PlaybackControlsSettings.tsx @@ -1,18 +1,15 @@ -import { Ionicons } from "@expo/vector-icons"; import { TFunction } from "i18next"; import type React from "react"; import { useMemo } from "react"; import { useTranslation } from "react-i18next"; -import { Switch, View } from "react-native"; import { BITRATES } from "@/components/BitrateSelector"; -import { PlatformDropdown } from "@/components/PlatformDropdown"; import { PLAYBACK_SPEEDS } from "@/components/PlaybackSpeedSelector"; import DisabledSetting from "@/components/settings/DisabledSetting"; +import { SettingsSelectRow } from "@/components/settings/index/SettingsSelectRow"; +import { SettingsSwitchRow } from "@/components/settings/index/SettingsSwitchRow"; import * as ScreenOrientation from "@/packages/expo-screen-orientation"; import { ScreenOrientationEnum, useSettings } from "@/utils/atoms/settings"; -import { Text } from "../common/Text"; import { ListGroup } from "../list/ListGroup"; -import { ListItem } from "../list/ListItem"; export const PlaybackControlsSettings: React.FC = () => { const { settings, updateSettings, pluginSettings } = useSettings(); @@ -116,141 +113,77 @@ export const PlaybackControlsSettings: React.FC = () => { return ( - - - - {t( - orientationTranslations[ - settings.defaultVideoOrientation as keyof typeof orientationTranslations - ], - ) || "Unknown Orientation"} - - - - } - title={t("home.settings.other.orientation")} - /> - + valueLabel={ + t( + orientationTranslations[ + settings.defaultVideoOrientation as keyof typeof orientationTranslations + ], + ) || "Unknown Orientation" + } + groups={orientationOptions} + dropdownTitle={t("home.settings.other.orientation")} + /> - - - updateSettings({ safeAreaInControlsEnabled: value }) - } - /> - + value={settings.safeAreaInControlsEnabled} + onValueChange={(value) => + updateSettings({ safeAreaInControlsEnabled: value }) + } + /> - - - - {settings.defaultBitrate?.key} - - - - } - title={t("home.settings.other.default_quality")} - /> - + valueLabel={settings.defaultBitrate?.key} + groups={bitrateOptions} + dropdownTitle={t("home.settings.other.default_quality")} + /> - - - - {PLAYBACK_SPEEDS.find( - (s) => s.value === settings.defaultPlaybackSpeed, - )?.label ?? "1x"} - - - - } - title={t("home.settings.other.default_playback_speed")} - /> - + valueLabel={ + PLAYBACK_SPEEDS.find( + (s) => s.value === settings.defaultPlaybackSpeed, + )?.label ?? "1x" + } + groups={playbackSpeedOptions} + dropdownTitle={t("home.settings.other.default_playback_speed")} + /> - - - updateSettings({ disableHapticFeedback }) - } - /> - + value={settings.disableHapticFeedback} + onValueChange={(disableHapticFeedback) => + updateSettings({ disableHapticFeedback }) + } + /> - - - updateSettings({ autoPlayNextEpisode }) - } - /> - + value={settings.autoPlayNextEpisode} + onValueChange={(autoPlayNextEpisode) => + updateSettings({ autoPlayNextEpisode }) + } + /> - - - - {t(settings?.maxAutoPlayEpisodeCount.key)} - - - - } - title={t("home.settings.other.max_auto_play_episode_count")} - /> - + valueLabel={t(settings?.maxAutoPlayEpisodeCount.key)} + groups={autoPlayEpisodeOptions} + dropdownTitle={t("home.settings.other.max_auto_play_episode_count")} + /> ); diff --git a/translations/en.json b/translations/en.json index 0e0691f6b..af4375fdc 100644 --- a/translations/en.json +++ b/translations/en.json @@ -220,6 +220,10 @@ "rewind_length": "Rewind Length", "seconds_unit": "s" }, + "chromecast": { + "title": "Chromecast", + "enable_h265": "Enable H265 for Chromecast" + }, "buffer": { "title": "Buffer Settings", "cache_mode": "Cache Mode",