Allow subtitles menu to be scrolled on android

This commit is contained in:
Zoe Roux 2023-08-02 00:48:37 +09:00
parent 45b18eb8e6
commit 9591350c3e
6 changed files with 100 additions and 31 deletions

View File

@ -40,6 +40,10 @@ import { useTheme } from "yoshiki/native";
import { CircularProgress } from "@kyoo/primitives"; import { CircularProgress } from "@kyoo/primitives";
import { useRouter } from "solito/router"; import { useRouter } from "solito/router";
import "intl-pluralrules"; import "intl-pluralrules";
import '@formatjs/intl-locale/polyfill'
import '@formatjs/intl-displaynames/polyfill'
import '@formatjs/intl-displaynames/locale-data/en'
import '@formatjs/intl-displaynames/locale-data/fr'
// TODO: use a backend to load jsons. // TODO: use a backend to load jsons.
import en from "../../../translations/en.json"; import en from "../../../translations/en.json";

View File

@ -13,6 +13,8 @@
}, },
"dependencies": { "dependencies": {
"@expo-google-fonts/poppins": "^0.2.3", "@expo-google-fonts/poppins": "^0.2.3",
"@formatjs/intl-displaynames": "^6.5.0",
"@formatjs/intl-locale": "^3.3.2",
"@gorhom/portal": "^1.0.14", "@gorhom/portal": "^1.0.14",
"@kyoo/ui": "workspace:^", "@kyoo/ui": "workspace:^",
"@material-symbols/svg-400": "^0.5.0", "@material-symbols/svg-400": "^0.5.0",

View File

@ -29,8 +29,8 @@ import {
useEffect, useEffect,
useState, useState,
} from "react"; } from "react";
import { StyleSheet, Pressable } from "react-native"; import { StyleSheet, Pressable, View } from "react-native";
import { percent, px, sm, useYoshiki, xl } from "yoshiki/native"; import { percent, px, sm, 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";
@ -76,13 +76,14 @@ const Menu = <AsProps,>({
focusable={false} focusable={false}
{...css({ ...StyleSheet.absoluteFillObject, flexGrow: 1, bg: "transparent" })} {...css({ ...StyleSheet.absoluteFillObject, flexGrow: 1, bg: "transparent" })}
/> />
<ScrollView <View
{...css([ {...css([
{ {
bg: (theme) => theme.background, bg: (theme) => theme.background,
position: "absolute", position: "absolute",
bottom: 0, bottom: 0,
width: percent(100), width: percent(100),
maxHeight: vh(80),
alignSelf: "center", alignSelf: "center",
borderTopLeftRadius: px(26), borderTopLeftRadius: px(26),
borderTopRightRadius: { xs: px(26), xl: 0 }, borderTopRightRadius: { xs: px(26), xl: 0 },
@ -101,14 +102,16 @@ const Menu = <AsProps,>({
}), }),
])} ])}
> >
<IconButton <ScrollView {...css([])}>
icon={Close} <IconButton
color={theme.colors.black} icon={Close}
onPress={() => setOpen(false)} color={theme.colors.black}
{...css({ alignSelf: "flex-end", display: { xs: "none", xl: "flex" } })} onPress={() => setOpen(false)}
/> {...css({ alignSelf: "flex-end", display: { xs: "none", xl: "flex" } })}
{children} />
</ScrollView> {children}
</ScrollView>
</View>
</MenuContext.Provider> </MenuContext.Provider>
)} )}
</SwitchVariant> </SwitchVariant>
@ -142,7 +145,7 @@ const MenuItem = ({
const icn = (icon || selected) && ( const icn = (icon || selected) && (
<Icon <Icon
icon={icon ?? Check} icon={icon ?? Check}
color={theme.paragraph} color={disabled ? theme.overlay0 : theme.paragraph}
size={24} size={24}
{...css({ paddingLeft: icon ? ts(2) : 0 })} {...css({ paddingLeft: icon ? ts(2) : 0 })}
/> />
@ -157,16 +160,13 @@ const MenuItem = ({
}} }}
disabled={disabled} disabled={disabled}
{...css( {...css(
[ {
{ paddingHorizontal: ts(2),
paddingHorizontal: ts(2), width: percent(100),
width: percent(100), height: ts(5),
height: ts(5), alignItems: "center",
alignItems: "center", flexDirection: "row",
flexDirection: "row", },
},
disabled && {},
],
props as any, props as any,
)} )}
> >

View File

@ -77,12 +77,13 @@ const Menu = <AsProps extends { onPress: PressableProps["onPress"] }>({
onFocusOutside={(e) => e.stopImmediatePropagation()} onFocusOutside={(e) => e.stopImmediatePropagation()}
{...css({ {...css({
bg: (theme) => theme.background, bg: (theme) => theme.background,
overflow: "hidden", overflow: "auto",
minWidth: "220px", minWidth: "220px",
borderRadius: "8px", borderRadius: "8px",
boxShadow: boxShadow:
"0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2)", "0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2)",
zIndex: 2, zIndex: 2,
maxHeight: "calc(var(--radix-dropdown-menu-content-available-height) * 0.8)",
})} })}
> >
{children} {children}
@ -138,7 +139,7 @@ const MenuItem = ({
const icn = (icon || selected) && ( const icn = (icon || selected) && (
<Icon <Icon
icon={icon ?? Dot} icon={icon ?? Dot}
color={theme.paragraph} color={disabled ? theme.overlay0 : theme.paragraph}
size={ts(icon ? 2 : 1)} size={ts(icon ? 2 : 1)}
{...nCss({ paddingRight: ts(1) })} {...nCss({ paddingRight: ts(1) })}
/> />

View File

@ -2043,6 +2043,66 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@formatjs/ecma402-abstract@npm:1.17.0":
version: 1.17.0
resolution: "@formatjs/ecma402-abstract@npm:1.17.0"
dependencies:
"@formatjs/intl-localematcher": 0.4.0
tslib: ^2.4.0
checksum: cc45d238e541076cb27b9cf02d8b97f789d1744b60218da6d31793204850c159e85f5b2557de3905a365eefd52a1c2e7f1febb9e1f009bad23d5eca17b3de6c8
languageName: node
linkType: hard
"@formatjs/intl-displaynames@npm:^6.5.0":
version: 6.5.0
resolution: "@formatjs/intl-displaynames@npm:6.5.0"
dependencies:
"@formatjs/ecma402-abstract": 1.17.0
"@formatjs/intl-localematcher": 0.4.0
tslib: ^2.4.0
checksum: d071f8459796240575e9911052b7116a6e2e43687607b0a5d1ac8ceddbaa85324af78694226c37c8172c0f3e7d6b793f506c5758b6bc50b2110516902b532e12
languageName: node
linkType: hard
"@formatjs/intl-enumerator@npm:1.3.2":
version: 1.3.2
resolution: "@formatjs/intl-enumerator@npm:1.3.2"
dependencies:
tslib: ^2.4.0
checksum: 37435354fcab9f69390402b1bcc917e83d0e35869cd5a06b584ca84ef62b179a4b94b9ee94febb59ab503a9d1587babcdcbebc2d4ece146fbc02bef41f722314
languageName: node
linkType: hard
"@formatjs/intl-getcanonicallocales@npm:2.2.1":
version: 2.2.1
resolution: "@formatjs/intl-getcanonicallocales@npm:2.2.1"
dependencies:
tslib: ^2.4.0
checksum: 9842f21308ee7cc46bf5a7f54c3ae66ebcaf107226ea43c11571eab0d8b36fdfa81521bf3210a4f385e2ca3302d9a61378e375946a930687278432bc482c9f8e
languageName: node
linkType: hard
"@formatjs/intl-locale@npm:^3.3.2":
version: 3.3.2
resolution: "@formatjs/intl-locale@npm:3.3.2"
dependencies:
"@formatjs/ecma402-abstract": 1.17.0
"@formatjs/intl-enumerator": 1.3.2
"@formatjs/intl-getcanonicallocales": 2.2.1
tslib: ^2.4.0
checksum: 41d2ab272ba759671cfa1720b2c43f8e261694f68d114ff976f2b9749ac3afad2181aa1b16799740082aa05bedd6f23b0ab67c65f48bfa0097b42582789e9a4d
languageName: node
linkType: hard
"@formatjs/intl-localematcher@npm:0.4.0":
version: 0.4.0
resolution: "@formatjs/intl-localematcher@npm:0.4.0"
dependencies:
tslib: ^2.4.0
checksum: c65108e9a81c3733d2b6240ceedc846d0ae59c3606041cb5cc71c13453cdabe295b0dc8559dc4a8acaafdc45876807bd5e9ef37a3ec1cb864e78db655d434b66
languageName: node
linkType: hard
"@gar/promisify@npm:^1.0.1, @gar/promisify@npm:^1.1.3": "@gar/promisify@npm:^1.0.1, @gar/promisify@npm:^1.1.3":
version: 1.1.3 version: 1.1.3
resolution: "@gar/promisify@npm:1.1.3" resolution: "@gar/promisify@npm:1.1.3"
@ -10312,6 +10372,8 @@ __metadata:
dependencies: dependencies:
"@babel/core": ^7.21.3 "@babel/core": ^7.21.3
"@expo-google-fonts/poppins": ^0.2.3 "@expo-google-fonts/poppins": ^0.2.3
"@formatjs/intl-displaynames": ^6.5.0
"@formatjs/intl-locale": ^3.3.2
"@gorhom/portal": ^1.0.14 "@gorhom/portal": ^1.0.14
"@kyoo/ui": "workspace:^" "@kyoo/ui": "workspace:^"
"@material-symbols/svg-400": ^0.5.0 "@material-symbols/svg-400": ^0.5.0

View File

@ -149,9 +149,9 @@ pub async fn identify(path: String) -> Result<MediaInfo, std::io::Error> {
let subs: Vec<Subtitle> = output["media"]["track"] let subs: Vec<Subtitle> = output["media"]["track"]
.members() .members()
.filter(|x| x["@type"] == "Text") .filter(|x| x["@type"] == "Text")
.map(|a| { .map(|x| {
let index = parse::<u32>(&a["@typeorder"]).unwrap() - 1; let index = parse::<u32>(&x["@typeorder"]).unwrap_or(1) - 1;
let mut codec = a["Format"].as_str().unwrap().to_string().to_lowercase(); let mut codec = x["Format"].as_str().unwrap().to_string().to_lowercase();
if codec == "utf-8" { if codec == "utf-8" {
codec = "subrip".to_string(); codec = "subrip".to_string();
} }
@ -159,12 +159,12 @@ pub async fn identify(path: String) -> Result<MediaInfo, std::io::Error> {
Subtitle { Subtitle {
link: extension.as_ref().map(|ext| format!("/video/{sha}/subtitle/{index}.{ext}")), link: extension.as_ref().map(|ext| format!("/video/{sha}/subtitle/{index}.{ext}")),
index, index,
title: a["Title"].as_str().map(|x| x.to_string()), title: x["Title"].as_str().map(|x| x.to_string()),
language: a["Language"].as_str().map(|x| x.to_string()), language: x["Language"].as_str().map(|x| x.to_string()),
codec, codec,
extension, extension,
is_default: a["Default"] == "Yes", is_default: x["Default"] == "Yes",
is_forced: a["Forced"] == "No", is_forced: x["Forced"] == "No",
} }
}) })
.collect(); .collect();