mirror of
https://github.com/movie-web/native-app.git
synced 2025-09-13 16:23:25 +00:00
fix theme selector not working, add input styling
This commit is contained in:
@@ -1,8 +1,3 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
||||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
||||||
const withEntitlementsPlist =
|
const withEntitlementsPlist =
|
||||||
require("@expo/config-plugins").withEntitlementsPlist;
|
require("@expo/config-plugins").withEntitlementsPlist;
|
||||||
|
|
||||||
|
@@ -20,6 +20,7 @@ import {
|
|||||||
|
|
||||||
import type { ThemeStoreOption } from "~/stores/theme";
|
import type { ThemeStoreOption } from "~/stores/theme";
|
||||||
import ScreenLayout from "~/components/layout/ScreenLayout";
|
import ScreenLayout from "~/components/layout/ScreenLayout";
|
||||||
|
import { MWSelect } from "~/components/ui/Select";
|
||||||
import { MWSwitch } from "~/components/ui/Switch";
|
import { MWSwitch } from "~/components/ui/Switch";
|
||||||
import { checkForUpdate } from "~/lib/update";
|
import { checkForUpdate } from "~/lib/update";
|
||||||
import { getGestureControls, saveGestureControls } from "~/settings";
|
import { getGestureControls, saveGestureControls } from "~/settings";
|
||||||
@@ -102,19 +103,20 @@ export function ThemeSelector(props: SelectProps) {
|
|||||||
const setTheme = useThemeStore((s) => s.setTheme);
|
const setTheme = useThemeStore((s) => s.setTheme);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Select
|
<MWSelect
|
||||||
value={themeStore}
|
value={themeStore}
|
||||||
onValueChange={setTheme}
|
onValueChange={setTheme}
|
||||||
disablePreventBodyScroll
|
disablePreventBodyScroll
|
||||||
native
|
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<Select.Trigger
|
<MWSelect.Trigger
|
||||||
maxWidth="$12"
|
maxWidth="$12"
|
||||||
iconAfter={<FontAwesome name="chevron-down" />}
|
iconAfter={
|
||||||
|
<FontAwesome name="chevron-down" color={theme.inputIconColor.val} />
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Select.Value />
|
<Select.Value />
|
||||||
</Select.Trigger>
|
</MWSelect.Trigger>
|
||||||
|
|
||||||
<Adapt platform="native">
|
<Adapt platform="native">
|
||||||
<Sheet
|
<Sheet
|
||||||
@@ -130,7 +132,12 @@ export function ThemeSelector(props: SelectProps) {
|
|||||||
snapPoints={[35]}
|
snapPoints={[35]}
|
||||||
>
|
>
|
||||||
<Sheet.Handle backgroundColor="$sheetHandle" />
|
<Sheet.Handle backgroundColor="$sheetHandle" />
|
||||||
<Sheet.Frame backgroundColor="$sheetBackground" padding="$5">
|
<Sheet.Frame
|
||||||
|
backgroundColor="$sheetBackground"
|
||||||
|
padding="$4"
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="center"
|
||||||
|
>
|
||||||
<Adapt.Contents />
|
<Adapt.Contents />
|
||||||
</Sheet.Frame>
|
</Sheet.Frame>
|
||||||
<Sheet.Overlay
|
<Sheet.Overlay
|
||||||
@@ -178,6 +185,6 @@ export function ThemeSelector(props: SelectProps) {
|
|||||||
})}
|
})}
|
||||||
</Select.Viewport>
|
</Select.Viewport>
|
||||||
</Select.Content>
|
</Select.Content>
|
||||||
</Select>
|
</MWSelect>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
25
apps/expo/src/components/ui/Input.tsx
Normal file
25
apps/expo/src/components/ui/Input.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { Input, styled } from "tamagui";
|
||||||
|
|
||||||
|
export const MWInput = styled(Input, {
|
||||||
|
variants: {
|
||||||
|
type: {
|
||||||
|
default: {
|
||||||
|
backgroundColor: "$inputBackground",
|
||||||
|
color: "$inputText",
|
||||||
|
placeholderTextColor: "$placeHolderText",
|
||||||
|
borderColor: "$inputBorder",
|
||||||
|
outlineStyle: "none",
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
backgroundColor: "$searchBackground",
|
||||||
|
borderColor: "$colorTransparent",
|
||||||
|
placeholderTextColor: "$searchPlaceholder",
|
||||||
|
outlineStyle: "none",
|
||||||
|
focusStyle: {
|
||||||
|
borderColor: "$colorTransparent",
|
||||||
|
backgroundColor: "$searchFocused",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
@@ -1,19 +1,11 @@
|
|||||||
|
import type { Input } from "tamagui";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { Keyboard } from "react-native";
|
import { Keyboard } from "react-native";
|
||||||
import { FontAwesome5 } from "@expo/vector-icons";
|
import { FontAwesome5 } from "@expo/vector-icons";
|
||||||
import { useIsFocused } from "@react-navigation/native";
|
import { useIsFocused } from "@react-navigation/native";
|
||||||
import { Input, styled, useTheme, View } from "tamagui";
|
import { useTheme, View } from "tamagui";
|
||||||
|
|
||||||
const SearchInput = styled(Input, {
|
import { MWInput } from "./Input";
|
||||||
backgroundColor: "$searchBackground",
|
|
||||||
borderColor: "$colorTransparent",
|
|
||||||
placeholderTextColor: "$searchPlaceholder",
|
|
||||||
outlineStyle: "none",
|
|
||||||
focusStyle: {
|
|
||||||
borderColor: "$colorTransparent",
|
|
||||||
backgroundColor: "$searchFocused",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export function SearchBar({
|
export function SearchBar({
|
||||||
onSearchChange,
|
onSearchChange,
|
||||||
@@ -69,7 +61,8 @@ export function SearchBar({
|
|||||||
<View width={48} alignItems="center" justifyContent="center">
|
<View width={48} alignItems="center" justifyContent="center">
|
||||||
<FontAwesome5 name="search" size={18} color={theme.searchIcon.val} />
|
<FontAwesome5 name="search" size={18} color={theme.searchIcon.val} />
|
||||||
</View>
|
</View>
|
||||||
<SearchInput
|
<MWInput
|
||||||
|
type="search"
|
||||||
value={keyword}
|
value={keyword}
|
||||||
onChangeText={handleChange}
|
onChangeText={handleChange}
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
|
38
apps/expo/src/components/ui/Select.tsx
Normal file
38
apps/expo/src/components/ui/Select.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { Select, styled, withStaticProperties } from "tamagui";
|
||||||
|
|
||||||
|
const MWSelectFrame = styled(Select, {
|
||||||
|
variants: {
|
||||||
|
type: {
|
||||||
|
default: {
|
||||||
|
backgroundColor: "$inputBackground",
|
||||||
|
color: "$inputText",
|
||||||
|
borderColor: "$inputBorder",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
type: "default",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const MWSelectTrigger = styled(Select.Trigger, {
|
||||||
|
variants: {
|
||||||
|
type: {
|
||||||
|
default: {
|
||||||
|
backgroundColor: "$inputBackground",
|
||||||
|
color: "$inputText",
|
||||||
|
placeholderTextColor: "$inputPlaceholderText",
|
||||||
|
borderColor: "$inputBorder",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
type: "default",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const MWSelect = withStaticProperties(MWSelectFrame, {
|
||||||
|
Trigger: MWSelectTrigger,
|
||||||
|
});
|
||||||
|
|
||||||
|
export { MWSelect };
|
@@ -1,4 +1,4 @@
|
|||||||
import type { SwitchProps } from "tamagui";
|
import type { SwitchProps, SwitchThumbProps } from "tamagui";
|
||||||
import { Switch, useTheme } from "tamagui";
|
import { Switch, useTheme } from "tamagui";
|
||||||
|
|
||||||
const MWSwitch = (props: SwitchProps) => {
|
const MWSwitch = (props: SwitchProps) => {
|
||||||
@@ -18,7 +18,7 @@ const MWSwitch = (props: SwitchProps) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const MWSwitchThumb = (props: any) => {
|
const MWSwitchThumb = (props: SwitchThumbProps) => {
|
||||||
return <Switch.Thumb animation="quicker" {...props} />;
|
return <Switch.Thumb animation="quicker" {...props} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -232,19 +232,12 @@ export const useSourceScrape = (sourceId: string | null) => {
|
|||||||
const query = useQuery({
|
const query = useQuery({
|
||||||
queryKey: ["sourceScrape", meta, sourceId],
|
queryKey: ["sourceScrape", meta, sourceId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
console.log("useSourceScrape", meta, sourceId);
|
|
||||||
if (!meta || !sourceId) return;
|
if (!meta || !sourceId) return;
|
||||||
const scrapeMedia = convertMetaToScrapeMedia(meta);
|
const scrapeMedia = convertMetaToScrapeMedia(meta);
|
||||||
const result = await getVideoStreamFromSource({
|
const result = await getVideoStreamFromSource({
|
||||||
sourceId,
|
sourceId,
|
||||||
media: scrapeMedia,
|
media: scrapeMedia,
|
||||||
events: {
|
|
||||||
update(evt) {
|
|
||||||
console.log("update useSourceScrape", evt);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
console.log("useSourceScrape result", result);
|
|
||||||
|
|
||||||
if (result?.stream) {
|
if (result?.stream) {
|
||||||
setCurrentStream(result.stream[0]!);
|
setCurrentStream(result.stream[0]!);
|
||||||
|
@@ -12,8 +12,8 @@ interface PlayerSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface Settings {
|
interface Settings {
|
||||||
themes: ThemeSettings;
|
themes?: ThemeSettings;
|
||||||
player: PlayerSettings;
|
player?: PlayerSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingsKey = "settings";
|
const settingsKey = "settings";
|
||||||
@@ -35,8 +35,12 @@ export const getTheme = async (): Promise<ThemeStoreOption> => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const saveTheme = async (newTheme: ThemeStoreOption) => {
|
export const saveTheme = async (newTheme: ThemeStoreOption) => {
|
||||||
const settings = (await loadSettings()) ?? { themes: { theme: newTheme } };
|
const existingSettings = await loadSettings();
|
||||||
settings.themes.theme = newTheme;
|
const settings: Settings = existingSettings?.themes?.theme
|
||||||
|
? {
|
||||||
|
themes: { theme: newTheme },
|
||||||
|
}
|
||||||
|
: { themes: { theme: "main" } };
|
||||||
await saveSettings(settings);
|
await saveSettings(settings);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -69,7 +73,7 @@ export const getGestureControls = async (): Promise<boolean> => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const saveGestureControls = async (gestureControls: boolean) => {
|
export const saveGestureControls = async (gestureControls: boolean) => {
|
||||||
const settings = (await loadSettings()) ?? ({} as Settings);
|
const settings = (await loadSettings()) ?? {};
|
||||||
|
|
||||||
if (!settings.player) {
|
if (!settings.player) {
|
||||||
settings.player = { gestureControls: true };
|
settings.player = { gestureControls: true };
|
||||||
|
@@ -20,12 +20,6 @@ type Tokens =
|
|||||||
const createThemeConfig = (tokens: Tokens) => ({
|
const createThemeConfig = (tokens: Tokens) => ({
|
||||||
screenBackground: tokens.shade.c900,
|
screenBackground: tokens.shade.c900,
|
||||||
|
|
||||||
searchIcon: tokens.shade.c100,
|
|
||||||
searchBackground: tokens.shade.c600,
|
|
||||||
searchHoverBackground: tokens.shade.c600,
|
|
||||||
searchFocused: tokens.shade.c400,
|
|
||||||
searchPlaceholder: tokens.shade.c100,
|
|
||||||
|
|
||||||
tabBarBackground: tokens.shade.c700,
|
tabBarBackground: tokens.shade.c700,
|
||||||
tabBarIcon: tokens.shade.c300,
|
tabBarIcon: tokens.shade.c300,
|
||||||
tabBarIconFocused: tokens.purple.c200,
|
tabBarIconFocused: tokens.purple.c200,
|
||||||
@@ -77,6 +71,18 @@ const createThemeConfig = (tokens: Tokens) => ({
|
|||||||
switchActiveTrackColor: tokens.purple.c300,
|
switchActiveTrackColor: tokens.purple.c300,
|
||||||
switchInactiveTrackColor: tokens.ash.c500,
|
switchInactiveTrackColor: tokens.ash.c500,
|
||||||
switchThumbColor: tokens.white,
|
switchThumbColor: tokens.white,
|
||||||
|
|
||||||
|
searchIcon: tokens.shade.c100,
|
||||||
|
searchBackground: tokens.shade.c600,
|
||||||
|
searchHoverBackground: tokens.shade.c600,
|
||||||
|
searchFocused: tokens.shade.c400,
|
||||||
|
searchPlaceholder: tokens.shade.c100,
|
||||||
|
|
||||||
|
inputBackground: tokens.shade.c600,
|
||||||
|
inputBorder: tokens.shade.c600,
|
||||||
|
inputPlaceholderText: tokens.shade.c300,
|
||||||
|
inputText: tokens.white,
|
||||||
|
inputIconColor: tokens.shade.c50,
|
||||||
});
|
});
|
||||||
|
|
||||||
const openSansFace = {
|
const openSansFace = {
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
"extends": ["@movie-web/tsconfig/base.json"],
|
"extends": ["@movie-web/tsconfig/base.json"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"incremental": true,
|
"incremental": true,
|
||||||
|
"allowJs": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"~/*": ["./src/*"],
|
"~/*": ["./src/*"],
|
||||||
@@ -10,6 +11,6 @@
|
|||||||
"jsx": "react-native",
|
"jsx": "react-native",
|
||||||
"tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json",
|
"tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json",
|
||||||
},
|
},
|
||||||
"include": ["src", "*.ts", "*.js", ".expo/types/**/*.ts", "expo-env.d.ts"],
|
"include": ["src", "*.ts", "*.js", ".expo/types/**/*.ts", "expo-env.d.ts", "config-plugins/*"],
|
||||||
"exclude": ["node_modules"],
|
"exclude": ["node_modules"],
|
||||||
}
|
}
|
||||||
|
@@ -41,6 +41,23 @@ const config = {
|
|||||||
"tamagui-web.css",
|
"tamagui-web.css",
|
||||||
],
|
],
|
||||||
reportUnusedDisableDirectives: true,
|
reportUnusedDisableDirectives: true,
|
||||||
|
// disable all typescript rules for js files
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: ["*.js", "*.cjs", "*.mjs"],
|
||||||
|
rules: {
|
||||||
|
"@typescript-eslint/no-var-requires": "off",
|
||||||
|
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-assignment": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-member-access": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-call": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-return": "off",
|
||||||
|
"@typescript-eslint/no-floating-promises": "off",
|
||||||
|
"@typescript-eslint/require-await": "off",
|
||||||
|
"@typescript-eslint/no-misused-promises": "off",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = config;
|
module.exports = config;
|
||||||
|
Reference in New Issue
Block a user