diff --git a/README.md b/README.md index a606760..6364607 100644 --- a/README.md +++ b/README.md @@ -15,20 +15,19 @@ apps ├─ Expo SDK 50 ├─ React Native using React 18 ├─ Navigation using Expo Router - ├─ Tailwind using Nativewind - └─ Typesafe API calls using tRPC + └─ Styling with Tamagui packages ├─ tmdb | └─ Typesafe API calls to The Movie Database └─ provider-utils └─ Typesafe API calls to the video providers tooling + ├─ color + | └─ shared color palette ├─ eslint | └─ shared, fine-grained, eslint presets ├─ prettier | └─ shared prettier configuration - ├─ tailwind - | └─ shared tailwind configuration └─ typescript └─ shared tsconfig you can extend from ``` diff --git a/apps/expo/babel.config.js b/apps/expo/babel.config.js index 42cdf24..ccd7e7f 100644 --- a/apps/expo/babel.config.js +++ b/apps/expo/babel.config.js @@ -2,10 +2,7 @@ module.exports = function (api) { api.cache(true); return { - presets: [ - ["babel-preset-expo", { jsxImportSource: "nativewind" }], - "nativewind/babel", - ], + presets: ["babel-preset-expo"], plugins: [ "react-native-reanimated/plugin", [ diff --git a/apps/expo/metro.config.js b/apps/expo/metro.config.js index 6a85d2a..259061d 100644 --- a/apps/expo/metro.config.js +++ b/apps/expo/metro.config.js @@ -1,19 +1,19 @@ // Learn more: https://docs.expo.dev/guides/monorepos/ const { getDefaultConfig } = require("expo/metro-config"); const { FileStore } = require("metro-cache"); -const { withNativeWind } = require("nativewind/metro"); +const { withTamagui } = require("@tamagui/metro-plugin"); const path = require("path"); module.exports = withTurborepoManagedCache( withMonorepoPaths( - withNativeWind( + withTamagui( getDefaultConfig(__dirname, { isCSSEnabled: true, }), { - input: "./src/styles/global.css", - configPath: "./tailwind.config.ts", + components: ["tamagui"], + config: "./tamagui.config.ts", }, ), ), diff --git a/apps/expo/package.json b/apps/expo/package.json index 1a16422..135b0a6 100644 --- a/apps/expo/package.json +++ b/apps/expo/package.json @@ -19,38 +19,42 @@ }, "dependencies": { "@expo/metro-config": "^0.17.3", + "@movie-web/colors": "*", "@movie-web/provider-utils": "*", "@movie-web/tmdb": "*", "@react-native-anywhere/polyfill-base64": "0.0.1-alpha.0", "@react-navigation/native": "^6.1.9", + "@tamagui/animations-moti": "^1.91.4", + "@tamagui/babel-plugin": "^1.91.4", + "@tamagui/config": "^1.91.4", + "@tamagui/metro-plugin": "^1.91.4", "@tanstack/react-query": "^5.22.2", "class-variance-authority": "^0.7.0", - "clsx": "^2.1.0", - "expo": "~50.0.5", + "expo": "~50.0.13", "expo-av": "~13.10.5", "expo-brightness": "~11.8.0", "expo-build-properties": "~0.11.1", "expo-constants": "~15.4.5", "expo-haptics": "~12.8.1", + "expo-linear-gradient": "^12.7.2", "expo-linking": "~6.2.2", "expo-navigation-bar": "^2.8.1", - "expo-router": "~3.4.6", + "expo-router": "~3.4.8", "expo-screen-orientation": "~6.4.1", "expo-splash-screen": "~0.26.4", "expo-status-bar": "~1.11.1", + "expo-system-ui": "^2.9.3", "expo-web-browser": "^12.8.2", "immer": "^10.0.3", "iso-639-1": "^3.1.2", - "nativewind": "^4.0.35", "react": "18.2.0", "react-dom": "18.2.0", - "react-native": "0.73.2", + "react-native": "0.73.5", "react-native-context-menu-view": "^1.14.1", - "react-native-css-interop": "^0.0.35", "react-native-gesture-handler": "~2.14.1", + "react-native-ios-modal": "^0.1.8", "react-native-modal": "^13.0.1", "react-native-paper": "^5.12.3", - "react-native-progress": "^5.0.1", "react-native-quick-base64": "^2.0.8", "react-native-quick-crypto": "^0.6.1", "react-native-reanimated": "~3.6.2", @@ -60,7 +64,7 @@ "react-native-url-polyfill": "^2.0.0", "react-native-web": "^0.19.10", "subsrt-ts": "^2.1.2", - "tailwind-merge": "^2.2.1", + "tamagui": "^1.91.4", "zustand": "^4.4.7" }, "devDependencies": { @@ -69,7 +73,6 @@ "@babel/runtime": "^7.23.9", "@movie-web/eslint-config": "workspace:^0.2.0", "@movie-web/prettier-config": "workspace:^0.1.0", - "@movie-web/tailwind-config": "workspace:^0.1.0", "@movie-web/tsconfig": "workspace:^0.1.0", "@tanstack/eslint-plugin-query": "^5.20.1", "@types/babel__core": "^7.20.5", @@ -77,7 +80,6 @@ "babel-plugin-module-resolver": "^5.0.0", "eslint": "^8.56.0", "prettier": "^3.1.1", - "tailwindcss": "^3.4.0", "typescript": "^5.3.3" }, "eslintConfig": { diff --git a/apps/expo/src/app/(tabs)/_layout.tsx b/apps/expo/src/app/(tabs)/_layout.tsx index 5d0ca82..a3e1e7c 100644 --- a/apps/expo/src/app/(tabs)/_layout.tsx +++ b/apps/expo/src/app/(tabs)/_layout.tsx @@ -1,10 +1,9 @@ import { useRef } from "react"; -import { Platform, StyleSheet, View } from "react-native"; +import { Platform } from "react-native"; import * as Haptics from "expo-haptics"; import { Tabs } from "expo-router"; import * as ScreenOrientation from "expo-screen-orientation"; - -import { defaultTheme } from "@movie-web/tailwind-config/themes"; +import { useTheme, View } from "tamagui"; import { MovieWebSvg } from "~/components/Icon"; import SvgTabBarIcon from "~/components/SvgTabBarIcon"; @@ -15,11 +14,13 @@ export default function TabLayout() { // eslint-disable-next-line @typescript-eslint/no-empty-function const focusSearchInputRef = useRef(() => {}); + const theme = useTheme(); + return ( ({ tabPress: () => { @@ -38,9 +39,9 @@ export default function TabLayout() { })} screenOptions={{ headerShown: false, - tabBarActiveTintColor: defaultTheme.extend.colors.tabBar.active, + tabBarActiveTintColor: theme.tabBarIconFocused.val, tabBarStyle: { - backgroundColor: defaultTheme.extend.colors.tabBar.background, + backgroundColor: theme.tabBarBackground.val, borderTopColor: "transparent", borderTopRightRadius: 20, borderTopLeftRadius: 20, @@ -83,10 +84,16 @@ export default function TabLayout() { tabBarLabel: "", tabBarIcon: ({ focused }) => ( @@ -117,22 +124,3 @@ export default function TabLayout() { ); } - -const styles = StyleSheet.create({ - searchTab: { - top: 2, - height: 56, - width: 56, - alignItems: "center", - justifyContent: "center", - overflow: "hidden", - borderRadius: 100, - textAlign: "center", - }, - active: { - backgroundColor: defaultTheme.extend.colors.tabBar.active, - }, - inactive: { - backgroundColor: defaultTheme.extend.colors.tabBar.inactive, - }, -}); diff --git a/apps/expo/src/app/(tabs)/index.tsx b/apps/expo/src/app/(tabs)/index.tsx index 7b55537..83877de 100644 --- a/apps/expo/src/app/(tabs)/index.tsx +++ b/apps/expo/src/app/(tabs)/index.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { View } from "react-native"; +import { Text, View } from "tamagui"; import { bookmarks, @@ -7,15 +7,16 @@ import { watching, } from "~/components/item/ItemListSection"; import ScreenLayout from "~/components/layout/ScreenLayout"; -import { Text } from "~/components/ui/Text"; export default function HomeScreen() { return ( - + - Home + + + Home + } > diff --git a/apps/expo/src/app/(tabs)/movie-web.tsx b/apps/expo/src/app/(tabs)/movie-web.tsx index 8b7e445..b6aecdd 100644 --- a/apps/expo/src/app/(tabs)/movie-web.tsx +++ b/apps/expo/src/app/(tabs)/movie-web.tsx @@ -1,5 +1,6 @@ +import { Text } from "tamagui"; + import ScreenLayout from "~/components/layout/ScreenLayout"; -import { Text } from "~/components/ui/Text"; export default function MovieWebScreen() { return ( diff --git a/apps/expo/src/app/(tabs)/search.tsx b/apps/expo/src/app/(tabs)/search.tsx index 9257e1a..cd44a33 100644 --- a/apps/expo/src/app/(tabs)/search.tsx +++ b/apps/expo/src/app/(tabs)/search.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from "react"; -import { Keyboard, ScrollView, View } from "react-native"; +import { Keyboard, ScrollView } from "react-native"; import Animated, { Easing, useAnimatedStyle, @@ -7,19 +7,14 @@ import Animated, { withTiming, } from "react-native-reanimated"; import { useQuery } from "@tanstack/react-query"; +import { Text, View } from "tamagui"; import { getMediaPoster, searchTitle } from "@movie-web/tmdb"; import type { ItemData } from "~/components/item/item"; import Item from "~/components/item/item"; -import { - bookmarks, - ItemListSection, - watching, -} from "~/components/item/ItemListSection"; import ScreenLayout from "~/components/layout/ScreenLayout"; import { SearchBar } from "~/components/ui/Searchbar"; -import { Text } from "~/components/ui/Text"; export default function HomeScreen() { const [query, setQuery] = useState(""); @@ -113,36 +108,28 @@ export default function HomeScreen() { > - Search + + + Search + } > - {searchResultsLoaded ? ( + {searchResultsLoaded && ( - + {data?.map((item, index) => ( - + ))} - ) : ( - 0 || watching.length > 0 ? true : false - } - > - - - )} diff --git a/apps/expo/src/app/(tabs)/settings.tsx b/apps/expo/src/app/(tabs)/settings.tsx index b94648f..16f2ea8 100644 --- a/apps/expo/src/app/(tabs)/settings.tsx +++ b/apps/expo/src/app/(tabs)/settings.tsx @@ -1,22 +1,142 @@ -import React, { useState } from "react"; -import { Text, View } from "react-native"; -import { Switch } from "react-native-paper"; +import type { SelectProps } from "tamagui"; +import React from "react"; +import { FontAwesome, MaterialIcons } from "@expo/vector-icons"; +import { + Adapt, + Label, + Select, + Separator, + Sheet, + Switch, + Text, + useTheme, + View, + XStack, + YStack, +} from "tamagui"; +import type { ThemeStoreOption } from "~/stores/theme"; import ScreenLayout from "~/components/layout/ScreenLayout"; +import { useThemeStore } from "~/stores/theme"; + +const themeOptions: ThemeStoreOption[] = [ + "main", + "blue", + "gray", + "red", + "teal", +]; export default function SettingsScreen() { - const [isSwitchOn, setIsSwitchOn] = useState(true); - const onToggleSwitch = () => setIsSwitchOn(!isSwitchOn); - return ( - - Player - - Gesture Controls - - + + + Player + + + + + + + + + + + + + + + + ); } + +export function ThemeSelector(props: SelectProps) { + const theme = useTheme(); + const themeStore = useThemeStore((s) => s.theme); + const setTheme = useThemeStore((s) => s.setTheme); + + return ( + + ); +} diff --git a/apps/expo/src/app/[...missing].tsx b/apps/expo/src/app/[...missing].tsx index 1844311..ec64eb6 100644 --- a/apps/expo/src/app/[...missing].tsx +++ b/apps/expo/src/app/[...missing].tsx @@ -1,19 +1,21 @@ -import { View } from "react-native"; import { Link, Stack } from "expo-router"; - -import { Text } from "~/components/ui/Text"; +import { Text, View } from "tamagui"; export default function NotFoundScreen() { return ( <> - - - This screen doesn't exist. - + + This screen doesn't exist. - - Go to home screen! + + Go to home screen! diff --git a/apps/expo/src/app/_layout.tsx b/apps/expo/src/app/_layout.tsx index dfbba6c..7c22070 100644 --- a/apps/expo/src/app/_layout.tsx +++ b/apps/expo/src/app/_layout.tsx @@ -1,26 +1,28 @@ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { useEffect } from "react"; -import { useColorScheme } from "react-native"; import { GestureHandlerRootView } from "react-native-gesture-handler"; +// @ts-expect-error - No exported types +import { ModalView } from "react-native-ios-modal"; import { useFonts } from "expo-font"; import { SplashScreen, Stack } from "expo-router"; import FontAwesome from "@expo/vector-icons/FontAwesome"; -import { - DarkTheme, - DefaultTheme, - ThemeProvider, -} from "@react-navigation/native"; +import { DarkTheme, ThemeProvider } from "@react-navigation/native"; +import { setupNativeSheet } from "@tamagui/sheet"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { TamaguiProvider, Theme, useTheme } from "tamagui"; +import tamaguiConfig from "tamagui.config"; -import "../styles/global.css"; - -import { defaultTheme } from "@movie-web/tailwind-config/themes"; +import { useThemeStore } from "~/stores/theme"; +// @ts-expect-error - Without named import it causes an infinite loop +import _styles from "../../tamagui-web.css"; export { // Catch any errors thrown by the Layout component. ErrorBoundary, } from "expo-router"; +setupNativeSheet("ios", ModalView); + export const unstable_settings = { // Ensure that reloading on `/modal` keeps a back button present. initialRouteName: "(tabs)", @@ -68,38 +70,50 @@ export default function RootLayout() { ); } +function ScreenStacks() { + const theme = useTheme(); + + return ( + + + + ); +} + function RootLayoutNav() { - const colorScheme = useColorScheme(); + const themeStore = useThemeStore((s) => s.theme); return ( - - - - - + + + + + + + ); } diff --git a/apps/expo/src/components/DownloadItem.tsx b/apps/expo/src/components/DownloadItem.tsx index a3432de..95583e6 100644 --- a/apps/expo/src/components/DownloadItem.tsx +++ b/apps/expo/src/components/DownloadItem.tsx @@ -1,8 +1,5 @@ import React from "react"; -import { Text, View } from "react-native"; -import { Bar as ProgressBar } from "react-native-progress"; - -import { defaultTheme } from "@movie-web/tailwind-config/themes"; +import { Progress, Text, View } from "tamagui"; export interface DownloadItemProps { filename: string; @@ -33,22 +30,28 @@ export const DownloadItem: React.FC = ({ const formattedDownloaded = formatBytes(downloaded); return ( - - {filename} - - - + + + {filename} + + + + + + {percentage}% - {formattedDownloaded} of {formattedFileSize} - {speed} MB/s + + {speed} MB/s + ); diff --git a/apps/expo/src/components/FlagIcon.tsx b/apps/expo/src/components/FlagIcon.tsx new file mode 100644 index 0000000..466685c --- /dev/null +++ b/apps/expo/src/components/FlagIcon.tsx @@ -0,0 +1,15 @@ +import { Image } from "tamagui"; + +// TODO: Improve flag icons. This is incomplete. +export function FlagIcon({ languageCode }: { languageCode: string }) { + return ( + + ); +} diff --git a/apps/expo/src/components/HomeScreenContent.tsx b/apps/expo/src/components/HomeScreenContent.tsx index f03f0e8..54c52ea 100644 --- a/apps/expo/src/components/HomeScreenContent.tsx +++ b/apps/expo/src/components/HomeScreenContent.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from "react"; -import { Keyboard, ScrollView, View } from "react-native"; +import { Keyboard } from "react-native"; import Animated, { Easing, useAnimatedStyle, @@ -7,6 +7,7 @@ import Animated, { withTiming, } from "react-native-reanimated"; import { useQuery } from "@tanstack/react-query"; +import { ScrollView, Text, View } from "tamagui"; import { getMediaPoster, searchTitle } from "@movie-web/tmdb"; @@ -19,7 +20,6 @@ import { } from "~/components/item/ItemListSection"; import ScreenLayout from "~/components/layout/ScreenLayout"; import { SearchBar } from "~/components/ui/Searchbar"; -import { Text } from "~/components/ui/Text"; export default function HomeScreenContent() { const [query, setQuery] = useState(""); @@ -103,7 +103,7 @@ export default function HomeScreenContent() { }; return ( - + - Home + + + Home + } > {searchResultsLoaded ? ( - + {data?.map((item, index) => ( - + ))} diff --git a/apps/expo/src/components/Icon.tsx b/apps/expo/src/components/Icon.tsx index 97568b1..dd942f5 100644 --- a/apps/expo/src/components/Icon.tsx +++ b/apps/expo/src/components/Icon.tsx @@ -1,11 +1,7 @@ import React from "react"; import Svg, { G, Path } from "react-native-svg"; -export const MovieWebSvg = ({ - fillColor = "currentColor", -}: { - fillColor?: string; -}) => { +export const MovieWebSvg = ({ fillColor }: { fillColor?: string }) => { const svgPath = "M18.186,4.5V6.241H16.445V4.5H9.482V6.241H7.741V4.5H6V20.168H7.741V18.427H9.482v1.741h6.964V18.427h1.741v1.741h1.741V4.5Zm-8.7,12.186H7.741V14.945H9.482Zm0-3.482H7.741V11.464H9.482Zm0-3.482H7.741V7.982H9.482Zm8.7,6.964H16.445V14.945h1.741Zm0-3.482H16.445V11.464h1.741Zm0-3.482H16.445V7.982h1.741Z"; diff --git a/apps/expo/src/components/SvgTabBarIcon.tsx b/apps/expo/src/components/SvgTabBarIcon.tsx index 70a8a14..62de2f9 100644 --- a/apps/expo/src/components/SvgTabBarIcon.tsx +++ b/apps/expo/src/components/SvgTabBarIcon.tsx @@ -1,6 +1,6 @@ import React from "react"; -import { defaultTheme } from "@movie-web/tailwind-config/themes"; +import { useTheme } from "tamagui"; interface SvgTabBarIconProps { focused?: boolean; @@ -11,9 +11,8 @@ export default function SvgTabBarIcon({ focused, children, }: SvgTabBarIconProps) { - const fillColor = focused - ? defaultTheme.extend.colors.tabBar.active - : defaultTheme.extend.colors.tabBar.inactive; + const theme = useTheme(); + const fillColor = focused ? theme.tabBarIconFocused.val : theme.tabBarIcon.val; if (React.isValidElement(children)) { return React.cloneElement(children, { fillColor } as React.Attributes); diff --git a/apps/expo/src/components/TabBarIcon.tsx b/apps/expo/src/components/TabBarIcon.tsx index cd3f4cd..ad508dd 100644 --- a/apps/expo/src/components/TabBarIcon.tsx +++ b/apps/expo/src/components/TabBarIcon.tsx @@ -1,14 +1,13 @@ import { FontAwesome } from "@expo/vector-icons"; -import { defaultTheme } from "@movie-web/tailwind-config/themes"; +import { useTheme } from "tamagui"; type Props = { focused?: boolean; } & React.ComponentProps; export default function TabBarIcon({ focused, ...rest }: Props) { - const color = focused - ? defaultTheme.extend.colors.tabBar.active - : defaultTheme.extend.colors.tabBar.inactive; + const theme = useTheme(); + const color = focused ? theme.tabBarIconFocused.val : theme.tabBarIcon.val return ; } diff --git a/apps/expo/src/components/item/ItemListSection.tsx b/apps/expo/src/components/item/ItemListSection.tsx index 9142778..ccde37b 100644 --- a/apps/expo/src/components/item/ItemListSection.tsx +++ b/apps/expo/src/components/item/ItemListSection.tsx @@ -1,5 +1,6 @@ import React from "react"; -import { Dimensions, ScrollView, Text, View } from "react-native"; +import { Dimensions } from "react-native"; +import { ScrollView, Text, View } from "tamagui"; import type { ItemData } from "~/components/item/item"; import Item from "~/components/item/item"; @@ -55,7 +56,7 @@ export const ItemListSection = ({ }) => { return ( - + {title} ( diff --git a/apps/expo/src/components/item/item.tsx b/apps/expo/src/components/item/item.tsx index dc38906..427c3ad 100644 --- a/apps/expo/src/components/item/item.tsx +++ b/apps/expo/src/components/item/item.tsx @@ -1,10 +1,10 @@ import type { NativeSyntheticEvent } from "react-native"; import type { ContextMenuOnPressNativeEvent } from "react-native-context-menu-view"; -import { Image, Keyboard, TouchableOpacity, View } from "react-native"; +import { Keyboard, TouchableOpacity } from "react-native"; import ContextMenu from "react-native-context-menu-view"; import { useRouter } from "expo-router"; +import { Image, Text, View } from "tamagui"; -import { Text } from "~/components/ui/Text"; import { usePlayerStore } from "~/stores/player/store"; export interface ItemData { @@ -47,19 +47,29 @@ export default function Item({ data }: { data: ItemData }) { onLongPress={() => {}} style={{ width: "100%" }} > - + - - + + - {title} - - + + {title} + + + {type === "tv" ? "Show" : "Movie"} - - {year} + + + {year} + diff --git a/apps/expo/src/components/layout/ScreenLayout.tsx b/apps/expo/src/components/layout/ScreenLayout.tsx index 339626d..d9745e3 100644 --- a/apps/expo/src/components/layout/ScreenLayout.tsx +++ b/apps/expo/src/components/layout/ScreenLayout.tsx @@ -1,6 +1,4 @@ -import { View } from "react-native"; - -import { Text } from "~/components/ui/Text"; +import { Text, View } from "tamagui"; interface Props { title?: React.ReactNode | string; @@ -10,13 +8,17 @@ interface Props { export default function ScreenLayout({ title, subtitle, children }: Props) { return ( - + {typeof title === "string" && ( - {title} + + {title} + )} {typeof title !== "string" && title} - {subtitle} - {children} + + {subtitle} + + {children} ); } diff --git a/apps/expo/src/components/player/AudioTrackSelector.tsx b/apps/expo/src/components/player/AudioTrackSelector.tsx index 8f4c44c..7097d39 100644 --- a/apps/expo/src/components/player/AudioTrackSelector.tsx +++ b/apps/expo/src/components/player/AudioTrackSelector.tsx @@ -1,17 +1,13 @@ -import { useEffect } from "react"; -import { Pressable, ScrollView, View } from "react-native"; -import Modal from "react-native-modal"; +import { useEffect, useState } from "react"; import { MaterialCommunityIcons } from "@expo/vector-icons"; - -import { defaultTheme } from "@movie-web/tailwind-config/themes"; +import { useTheme } from "tamagui"; import { useAudioTrack } from "~/hooks/player/useAudioTrack"; -import { useBoolean } from "~/hooks/useBoolean"; import { useAudioTrackStore } from "~/stores/audio"; import { usePlayerStore } from "~/stores/player/store"; -import { Button } from "../ui/Button"; -import { Text } from "../ui/Text"; +import { MWButton } from "../ui/Button"; import { Controls } from "./Controls"; +import { Settings } from "./settings/Sheet"; export interface AudioTrack { uri: string; @@ -21,6 +17,9 @@ export interface AudioTrack { } export const AudioTrackSelector = () => { + const theme = useTheme(); + const [open, setOpen] = useState(false); + const tracks = usePlayerStore((state) => state.interface.audioTracks); const setAudioTracks = usePlayerStore((state) => state.setAudioTracks); const stream = usePlayerStore((state) => state.interface.currentStream); @@ -30,7 +29,6 @@ export const AudioTrackSelector = () => { (state) => state.setSelectedAudioTrack, ); - const { isTrue, on, off } = useBoolean(); const { synchronizePlayback } = useAudioTrack(); useEffect(() => { @@ -52,58 +50,67 @@ export const AudioTrackSelector = () => { if (!tracks?.length) return null; return ( - + <> - + + + + + + + {props.children} + + + + + ); +} diff --git a/apps/expo/src/components/player/PlaybackSpeedSelector.tsx b/apps/expo/src/components/player/PlaybackSpeedSelector.tsx index 7068b95..2553474 100644 --- a/apps/expo/src/components/player/PlaybackSpeedSelector.tsx +++ b/apps/expo/src/components/player/PlaybackSpeedSelector.tsx @@ -1,71 +1,82 @@ -import { Pressable, ScrollView, View } from "react-native"; -import Modal from "react-native-modal"; +import { useState } from "react"; import { MaterialCommunityIcons } from "@expo/vector-icons"; - -import { defaultTheme } from "@movie-web/tailwind-config/themes"; +import { useTheme } from "tamagui"; import { usePlaybackSpeed } from "~/hooks/player/usePlaybackSpeed"; -import { useBoolean } from "~/hooks/useBoolean"; -import { Button } from "../ui/Button"; -import { Text } from "../ui/Text"; +import { MWButton } from "../ui/Button"; import { Controls } from "./Controls"; +import { Settings } from "./settings/Sheet"; export const PlaybackSpeedSelector = () => { + const theme = useTheme(); + const [open, setOpen] = useState(false); const { currentSpeed, changePlaybackSpeed } = usePlaybackSpeed(); - const { isTrue, on, off } = useBoolean(); const speeds = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2]; return ( - + <> -