mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 04:04:21 -04:00
Make subtitle's menu work on tv
This commit is contained in:
parent
e45c595d6d
commit
1bba1eb02a
@ -21,8 +21,8 @@
|
|||||||
import { Portal } from "@gorhom/portal";
|
import { Portal } from "@gorhom/portal";
|
||||||
import { ScrollView } from "moti";
|
import { ScrollView } from "moti";
|
||||||
import { ComponentType, createContext, ReactNode, useContext, useEffect, useState } from "react";
|
import { ComponentType, createContext, ReactNode, useContext, useEffect, useState } from "react";
|
||||||
import { StyleSheet, Pressable } from "react-native";
|
import { StyleSheet, Pressable, Platform, BackHandler } from "react-native";
|
||||||
import { percent, px, sm, useYoshiki, xl } from "yoshiki/native";
|
import { min, percent, px, sm, Theme, useYoshiki, vh, xl } from "yoshiki/native";
|
||||||
import Close from "@material-symbols/svg-400/rounded/close-fill.svg";
|
import Close from "@material-symbols/svg-400/rounded/close-fill.svg";
|
||||||
import { Icon, IconButton } from "./icons";
|
import { Icon, IconButton } from "./icons";
|
||||||
import { PressableFeedback } from "./links";
|
import { PressableFeedback } from "./links";
|
||||||
@ -52,6 +52,15 @@ const Menu = <AsProps,>({
|
|||||||
else onMenuClose?.call(null);
|
else onMenuClose?.call(null);
|
||||||
}, [isOpen, onMenuClose, onMenuOpen]);
|
}, [isOpen, onMenuClose, onMenuOpen]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handler = BackHandler.addEventListener("hardwareBackPress", () => {
|
||||||
|
if (!isOpen) return false;
|
||||||
|
setOpen(false);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return () => handler.remove();
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* @ts-ignore */}
|
{/* @ts-ignore */}
|
||||||
@ -75,28 +84,26 @@ const Menu = <AsProps,>({
|
|||||||
width: percent(100),
|
width: percent(100),
|
||||||
alignSelf: "center",
|
alignSelf: "center",
|
||||||
borderTopLeftRadius: px(26),
|
borderTopLeftRadius: px(26),
|
||||||
borderTopRightRadius: { xs: px(26), xl: 0 },
|
borderTopRightRadius: px(26),
|
||||||
paddingTop: { xs: px(26), xl: 0 },
|
paddingTop: px(26),
|
||||||
marginTop: { xs: px(72), xl: 0 },
|
marginTop: px(72),
|
||||||
},
|
},
|
||||||
sm({
|
sm({
|
||||||
maxWidth: px(640),
|
maxWidth: px(640),
|
||||||
marginHorizontal: px(56),
|
marginHorizontal: px(56),
|
||||||
}),
|
}),
|
||||||
xl({
|
Platform.isTV && {
|
||||||
top: 0,
|
top: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
marginRight: 0,
|
marginRight: 0,
|
||||||
borderBottomLeftRadius: px(26),
|
borderBottomLeftRadius: px(26),
|
||||||
}),
|
maxWidth: min(px(640), vh(45)),
|
||||||
|
marginHorizontal: px(56),
|
||||||
|
borderTopRightRadius: 0,
|
||||||
|
marginTop: 0,
|
||||||
|
},
|
||||||
])}
|
])}
|
||||||
>
|
>
|
||||||
<IconButton
|
|
||||||
icon={Close}
|
|
||||||
color={theme.colors.black}
|
|
||||||
onPress={() => setOpen(false)}
|
|
||||||
{...css({ alignSelf: "flex-end", display: { xs: "none", xl: "flex" } })}
|
|
||||||
/>
|
|
||||||
{children}
|
{children}
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</MenuContext.Provider>
|
</MenuContext.Provider>
|
||||||
@ -127,6 +134,7 @@ const MenuItem = ({
|
|||||||
setOpen?.call(null, false);
|
setOpen?.call(null, false);
|
||||||
onSelect?.call(null);
|
onSelect?.call(null);
|
||||||
}}
|
}}
|
||||||
|
hasTVPreferredFocus={selected}
|
||||||
{...css(
|
{...css(
|
||||||
{
|
{
|
||||||
paddingHorizontal: ts(2),
|
paddingHorizontal: ts(2),
|
||||||
@ -134,12 +142,20 @@ const MenuItem = ({
|
|||||||
height: ts(5),
|
height: ts(5),
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
|
focus: {
|
||||||
|
self: {
|
||||||
|
bg: (theme: Theme) => theme.alternate.accent,
|
||||||
|
},
|
||||||
|
// text: {
|
||||||
|
// color: (theme: Theme) => theme.alternate.contrast,
|
||||||
|
// },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
props as any,
|
props as any,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{selected && <Icon icon={Check} color={theme.paragraph} size={24} />}
|
{selected && <Icon icon={Check} color={theme.paragraph} size={24} />}
|
||||||
<P {...css({ paddingLeft: ts(2) + +!selected * px(24) })}>{label}</P>
|
<P {...css(["text", { paddingLeft: ts(2) + +!selected * px(24) }])}>{label}</P>
|
||||||
</PressableFeedback>
|
</PressableFeedback>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -27,6 +27,7 @@ import { P } from "./text";
|
|||||||
import { ContrastArea } from "./themes";
|
import { ContrastArea } from "./themes";
|
||||||
import { Icon } from "./icons";
|
import { Icon } from "./icons";
|
||||||
import Dot from "@material-symbols/svg-400/rounded/fiber_manual_record-fill.svg";
|
import Dot from "@material-symbols/svg-400/rounded/fiber_manual_record-fill.svg";
|
||||||
|
import { focusReset } from "./utils";
|
||||||
|
|
||||||
type YoshikiFunc<T> = (props: ReturnType<typeof useYoshiki>) => T;
|
type YoshikiFunc<T> = (props: ReturnType<typeof useYoshiki>) => T;
|
||||||
const YoshikiProvider = ({ children }: { children: YoshikiFunc<ReactNode> }) => {
|
const YoshikiProvider = ({ children }: { children: YoshikiFunc<ReactNode> }) => {
|
||||||
@ -115,18 +116,16 @@ const MenuItem = ({
|
|||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
{...css(
|
{...css(
|
||||||
[
|
{
|
||||||
{
|
display: "flex",
|
||||||
display: "flex",
|
alignItems: "center",
|
||||||
alignItems: "center",
|
padding: "8px",
|
||||||
padding: "8px",
|
height: "32px",
|
||||||
height: "32px",
|
color: (theme) => theme.paragraph,
|
||||||
color: (theme) => theme.paragraph,
|
focus: {
|
||||||
focus: {
|
self: focusReset,
|
||||||
boxShadow: "none",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
],
|
},
|
||||||
props as any,
|
props as any,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Kyoo - A portable and vast media library solution.
|
|
||||||
* Copyright (c) Kyoo.
|
|
||||||
*
|
|
||||||
* See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
*
|
|
||||||
* Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* Kyoo is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import "react-native/tvos-types.d";
|
|
@ -28,11 +28,8 @@ import ClosedCaption from "@material-symbols/svg-400/rounded/closed_caption-fill
|
|||||||
import Fullscreen from "@material-symbols/svg-400/rounded/fullscreen-fill.svg";
|
import Fullscreen from "@material-symbols/svg-400/rounded/fullscreen-fill.svg";
|
||||||
import FullscreenExit from "@material-symbols/svg-400/rounded/fullscreen_exit-fill.svg";
|
import FullscreenExit from "@material-symbols/svg-400/rounded/fullscreen_exit-fill.svg";
|
||||||
import { Stylable, useYoshiki } from "yoshiki/native";
|
import { Stylable, useYoshiki } from "yoshiki/native";
|
||||||
import { createParam } from "solito";
|
|
||||||
import { fullscreenAtom, subtitleAtom } from "../state";
|
import { fullscreenAtom, subtitleAtom } from "../state";
|
||||||
|
|
||||||
const { useParam } = createParam<{ subtitle?: string }>();
|
|
||||||
|
|
||||||
export const RightButtons = ({
|
export const RightButtons = ({
|
||||||
subtitles,
|
subtitles,
|
||||||
fonts,
|
fonts,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user