improved settings design

This commit is contained in:
Jorrin
2024-04-02 17:25:24 +02:00
parent 9dc973dd38
commit 925b28019f
5 changed files with 173 additions and 33 deletions

View File

@@ -11,12 +11,13 @@ import {
MaterialIcons, MaterialIcons,
} from "@expo/vector-icons"; } from "@expo/vector-icons";
import { useToastController } from "@tamagui/toast"; import { useToastController } from "@tamagui/toast";
import { useMutation } from "@tanstack/react-query";
import { import {
Adapt, Adapt,
ScrollView, ScrollView,
Select, Select,
Separator,
Sheet, Sheet,
Spinner,
Text, Text,
useTheme, useTheme,
View, View,
@@ -28,6 +29,7 @@ import type { ThemeStoreOption } from "~/stores/theme";
import ScreenLayout from "~/components/layout/ScreenLayout"; import ScreenLayout from "~/components/layout/ScreenLayout";
import { MWButton } from "~/components/ui/Button"; import { MWButton } from "~/components/ui/Button";
import { MWSelect } from "~/components/ui/Select"; import { MWSelect } from "~/components/ui/Select";
import { MWSeparator } from "~/components/ui/Separator";
import { MWSwitch } from "~/components/ui/Switch"; import { MWSwitch } from "~/components/ui/Switch";
import { checkForUpdate } from "~/lib/update"; import { checkForUpdate } from "~/lib/update";
import { usePlayerSettingsStore } from "~/stores/settings"; import { usePlayerSettingsStore } from "~/stores/settings";
@@ -50,6 +52,30 @@ export default function SettingsScreen() {
const [updateMarkdownContent, setUpdateMarkdownContent] = useState(""); const [updateMarkdownContent, setUpdateMarkdownContent] = useState("");
const [downloadUrl, setDownloadUrl] = useState(""); const [downloadUrl, setDownloadUrl] = useState("");
const mutation = useMutation({
mutationKey: ["checkForUpdate"],
mutationFn: checkForUpdate,
onSuccess: (res) => {
if (res) {
setUpdateMarkdownContent(res.data.body!);
setDownloadUrl(
res.data.assets.find(
(asset) =>
asset.name ===
`movie-web.${Platform.select({ ios: "ipa", android: "apk" })}`,
)?.browser_download_url ?? "",
);
setShowUpdateSheet(true);
} else {
toastController.show("No updates available", {
burntOptions: { preset: "none" },
native: true,
duration: 500,
});
}
},
});
const handleGestureControlsToggle = async (isEnabled: boolean) => { const handleGestureControlsToggle = async (isEnabled: boolean) => {
if (isEnabled) { if (isEnabled) {
const { status } = await Brightness.requestPermissionsAsync(); const { status } = await Brightness.requestPermissionsAsync();
@@ -61,32 +87,90 @@ export default function SettingsScreen() {
} }
}; };
const handleVersionPress = async () => {
const res = await checkForUpdate();
if (res) {
setUpdateMarkdownContent(res.data.body!);
setDownloadUrl(
res.data.assets.find(
(asset) =>
asset.name ===
`movie-web.${Platform.select({ ios: "ipa", android: "apk" })}`,
)?.browser_download_url ?? "",
);
setShowUpdateSheet(true);
} else {
toastController.show("No updates available", {
burntOptions: { preset: "none" },
native: true,
duration: 500,
});
}
};
return ( return (
<ScreenLayout> <ScreenLayout>
<View padding={4}> <View padding={4}>
<YStack gap={4}> <YStack gap="$8">
<XStack width={200} alignItems="center" gap="$4"> <YStack gap="$4">
<Text fontSize="$9" fontWeight="$semibold">
Appearance
</Text>
<MWSeparator />
<YStack gap="$2">
<XStack gap="$4" alignItems="center">
<Text fontWeight="$semibold" flexGrow={1}>
Theme
</Text>
<ThemeSelector />
</XStack>
</YStack>
</YStack>
<YStack gap="$4">
<Text fontSize="$9" fontWeight="$semibold">
Player
</Text>
<MWSeparator />
<YStack gap="$2">
<XStack gap="$4" alignItems="center">
<Text fontWeight="$semibold" flexGrow={1}>
Gesture controls
</Text>
<MWSwitch
checked={gestureControls}
onCheckedChange={handleGestureControlsToggle}
>
<MWSwitch.Thumb animation="quicker" />
</MWSwitch>
</XStack>
<XStack gap="$4" alignItems="center">
<Text fontWeight="$semibold" flexGrow={1}>
Autoplay
</Text>
<MWSwitch checked={autoPlay} onCheckedChange={setAutoPlay}>
<MWSwitch.Thumb animation="quicker" />
</MWSwitch>
</XStack>
</YStack>
</YStack>
<YStack gap="$4">
<Text fontSize="$9" fontWeight="$semibold">
App
</Text>
<MWSeparator />
<YStack gap="$2">
<XStack gap="$4" alignItems="center">
<Text fontWeight="$semibold" flexGrow={1}>
Version v{Application.nativeApplicationVersion}
</Text>
<MWButton
type="secondary"
backgroundColor="$sheetItemBackground"
icon={
<MaterialCommunityIcons
name={Platform.select({
ios: "apple",
android: "android",
})}
size={24}
color={theme.buttonSecondaryText.val}
/>
}
iconAfter={
<>{mutation.isPending && <Spinner color="$purple200" />}</>
}
disabled={mutation.isPending}
onPress={() => mutation.mutate()}
animation="quicker"
>
Update
</MWButton>
</XStack>
</YStack>
</YStack>
{/* <XStack width={200} alignItems="center" gap="$4">
<Text minWidth={110}>Theme</Text> <Text minWidth={110}>Theme</Text>
<Separator minHeight={20} vertical /> <Separator minHeight={20} vertical />
<ThemeSelector /> <ThemeSelector />
@@ -125,7 +209,7 @@ export default function SettingsScreen() {
> >
Update Update
</MWButton> </MWButton>
</XStack> </XStack> */}
</YStack> </YStack>
</View> </View>
<UpdateSheet <UpdateSheet

View File

@@ -2,6 +2,7 @@ import type { LanguageCode } from "iso-639-1";
import type { ContentCaption } from "subsrt-ts/dist/types/handler"; import type { ContentCaption } from "subsrt-ts/dist/types/handler";
import { useState } from "react"; import { useState } from "react";
import { MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons"; import { MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons";
import { useToastController } from "@tamagui/toast";
import { useMutation } from "@tanstack/react-query"; import { useMutation } from "@tanstack/react-query";
import { parse } from "subsrt-ts"; import { parse } from "subsrt-ts";
import { Spinner, useTheme, View } from "tamagui"; import { Spinner, useTheme, View } from "tamagui";
@@ -34,6 +35,7 @@ const parseCaption = async (
}; };
export const CaptionsSelector = () => { export const CaptionsSelector = () => {
const toast = useToastController();
const theme = useTheme(); const theme = useTheme();
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const captions = usePlayerStore( const captions = usePlayerStore(
@@ -94,6 +96,13 @@ export const CaptionsSelector = () => {
color="$playerSettingsUnactiveText" color="$playerSettingsUnactiveText"
fontWeight="bold" fontWeight="bold"
chromeless chromeless
onPress={() => {
toast.show("Work in progress", {
burntOptions: { preset: "none" },
native: true,
duration: 500,
});
}}
> >
Customize Customize
</MWButton> </MWButton>

View File

@@ -0,0 +1,14 @@
import { Separator, styled } from "tamagui";
export const MWSeparator = styled(Separator, {
variants: {
type: {
settings: {
borderColor: "$shade300",
},
},
},
defaultVariants: {
type: "settings",
},
});

View File

@@ -29,7 +29,7 @@
}, },
"prettier": "@movie-web/prettier-config", "prettier": "@movie-web/prettier-config",
"dependencies": { "dependencies": {
"@movie-web/providers": "^2.2.4", "@movie-web/providers": "^2.2.7",
"parse-hls": "^1.0.7", "parse-hls": "^1.0.7",
"srt-webvtt": "^2.0.0", "srt-webvtt": "^2.0.0",
"tmdb-ts": "^1.6.1" "tmdb-ts": "^1.6.1"

47
pnpm-lock.yaml generated
View File

@@ -265,8 +265,8 @@ importers:
packages/provider-utils: packages/provider-utils:
dependencies: dependencies:
'@movie-web/providers': '@movie-web/providers':
specifier: ^2.2.4 specifier: ^2.2.7
version: 2.2.4 version: 2.2.7
parse-hls: parse-hls:
specifier: ^1.0.7 specifier: ^1.0.7
version: 1.0.7 version: 1.0.7
@@ -2894,8 +2894,9 @@ packages:
tslib: 2.6.2 tslib: 2.6.2
dev: false dev: false
/@movie-web/providers@2.2.4: /@movie-web/providers@2.2.7:
resolution: {integrity: sha512-c10ffR7/oPMbVwpD+Lw0/k5jvx51NbywGJtogzRjeXqDr01o5+pitPeN1qSGaqTg5FBlipn7NSesrd+cczDDQw==} resolution: {integrity: sha512-XwU1IkXrF7e99JtC5Tna00/yuRECqEyBo8bhTtVE6ZFLYj3YQXVm2sdHjcyerjbyAsXvKGeikWEkrvHofTUjDA==}
requiresBuild: true
dependencies: dependencies:
cheerio: 1.0.0-rc.12 cheerio: 1.0.0-rc.12
cookie: 0.6.0 cookie: 0.6.0
@@ -2903,11 +2904,9 @@ packages:
form-data: 4.0.0 form-data: 4.0.0
iso-639-1: 3.1.2 iso-639-1: 3.1.2
nanoid: 3.3.7 nanoid: 3.3.7
node-fetch: 2.7.0 node-fetch: 3.3.2
set-cookie-parser: 2.6.0 set-cookie-parser: 2.6.0
unpacker: 1.0.1 unpacker: 1.0.1
transitivePeerDependencies:
- encoding
dev: false dev: false
/@nodelib/fs.scandir@2.1.5: /@nodelib/fs.scandir@2.1.5:
@@ -6890,6 +6889,11 @@ packages:
engines: {node: '>= 6'} engines: {node: '>= 6'}
dev: false dev: false
/data-uri-to-buffer@4.0.1:
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
engines: {node: '>= 12'}
dev: false
/data-uri-to-buffer@6.0.1: /data-uri-to-buffer@6.0.1:
resolution: {integrity: sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==} resolution: {integrity: sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==}
engines: {node: '>= 14'} engines: {node: '>= 14'}
@@ -8118,6 +8122,14 @@ packages:
- encoding - encoding
dev: false dev: false
/fetch-blob@3.2.0:
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
engines: {node: ^12.20 || >= 14.13}
dependencies:
node-domexception: 1.0.0
web-streams-polyfill: 3.3.2
dev: false
/fetch-retry@4.1.1: /fetch-retry@4.1.1:
resolution: {integrity: sha512-e6eB7zN6UBSwGVwrbWVH+gdLnkW9WwHhmq2YDK1Sh30pzx1onRVGBvogTlUeWxwTa+L86NYdo4hFkh7O8ZjSnA==} resolution: {integrity: sha512-e6eB7zN6UBSwGVwrbWVH+gdLnkW9WwHhmq2YDK1Sh30pzx1onRVGBvogTlUeWxwTa+L86NYdo4hFkh7O8ZjSnA==}
dev: false dev: false
@@ -8288,6 +8300,13 @@ packages:
mime-types: 2.1.35 mime-types: 2.1.35
dev: false dev: false
/formdata-polyfill@4.0.10:
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
engines: {node: '>=12.20.0'}
dependencies:
fetch-blob: 3.2.0
dev: false
/framer-motion@6.5.1(react-dom@18.2.0)(react@18.2.0): /framer-motion@6.5.1(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw==} resolution: {integrity: sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw==}
peerDependencies: peerDependencies:
@@ -10465,6 +10484,11 @@ packages:
minimatch: 3.1.2 minimatch: 3.1.2
dev: false dev: false
/node-domexception@1.0.0:
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
engines: {node: '>=10.5.0'}
dev: false
/node-fetch@2.7.0: /node-fetch@2.7.0:
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
engines: {node: 4.x || >=6.0.0} engines: {node: 4.x || >=6.0.0}
@@ -10477,6 +10501,15 @@ packages:
whatwg-url: 5.0.0 whatwg-url: 5.0.0
dev: false dev: false
/node-fetch@3.3.2:
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
data-uri-to-buffer: 4.0.1
fetch-blob: 3.2.0
formdata-polyfill: 4.0.10
dev: false
/node-forge@1.3.1: /node-forge@1.3.1:
resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==}
engines: {node: '>= 6.13.0'} engines: {node: '>= 6.13.0'}