mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-30 19:54:16 -04:00
Fix bottom scrubber on android
This commit is contained in:
parent
085d337fb7
commit
0cc6274894
@ -27,7 +27,7 @@ import { ContrastArea } from "../themes";
|
|||||||
import { percent } from "yoshiki/native";
|
import { percent } from "yoshiki/native";
|
||||||
import { imageBorderRadius } from "../constants";
|
import { imageBorderRadius } from "../constants";
|
||||||
|
|
||||||
export { FastImage } from "./fast-image";
|
export { Sprite } from "./sprite";
|
||||||
export { BlurhashContainer } from "./blurhash";
|
export { BlurhashContainer } from "./blurhash";
|
||||||
export { type Props as ImageProps, Image };
|
export { type Props as ImageProps, Image };
|
||||||
|
|
||||||
|
@ -18,10 +18,9 @@
|
|||||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { View } from "react-native";
|
import { Image, View } from "react-native";
|
||||||
import FImage from "react-native-fast-image";
|
|
||||||
|
|
||||||
export const FastImage = ({
|
export const Sprite = ({
|
||||||
src,
|
src,
|
||||||
alt,
|
alt,
|
||||||
width,
|
width,
|
||||||
@ -45,21 +44,12 @@ export const FastImage = ({
|
|||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<View style={{ width, height, overflow: "hidden", flexGrow: 0, flexShrink: 0 }}>
|
<View style={{ width, height, overflow: "hidden", flexGrow: 0, flexShrink: 0 }}>
|
||||||
<FImage
|
<Image
|
||||||
source={{
|
source={{ uri: src }}
|
||||||
uri: src,
|
alt={alt}
|
||||||
priority: FImage.priority.low,
|
width={width * columns}
|
||||||
}}
|
height={height * rows}
|
||||||
accessibilityLabel={alt}
|
style={{ transform: [{ translateX: -x }, { translateY: -y }] }}
|
||||||
resizeMode={FImage.resizeMode.cover}
|
|
||||||
style={[
|
|
||||||
{
|
|
||||||
width: width * columns,
|
|
||||||
height: height * rows,
|
|
||||||
transform: `translate(${-x}px, ${-y}px)`,
|
|
||||||
},
|
|
||||||
style,
|
|
||||||
]}
|
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
import NextImage from "next/image";
|
import NextImage from "next/image";
|
||||||
|
|
||||||
export const FastImage = ({
|
export const Sprite = ({
|
||||||
src,
|
src,
|
||||||
alt,
|
alt,
|
||||||
style,
|
style,
|
||||||
@ -31,8 +31,8 @@ export const FastImage = ({
|
|||||||
src: string;
|
src: string;
|
||||||
alt: string;
|
alt: string;
|
||||||
style?: object;
|
style?: object;
|
||||||
width: number | string;
|
width: number;
|
||||||
height: number | string;
|
height: number;
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
}) => {
|
}) => {
|
||||||
@ -43,7 +43,13 @@ export const FastImage = ({
|
|||||||
alt={alt!}
|
alt={alt!}
|
||||||
// Don't use next's server to reprocess images, they are already optimized by kyoo.
|
// Don't use next's server to reprocess images, they are already optimized by kyoo.
|
||||||
unoptimized={true}
|
unoptimized={true}
|
||||||
style={{ objectFit: "none", objectPosition: `${-x}px ${-y}px`, ...style }}
|
style={{
|
||||||
|
objectFit: "none",
|
||||||
|
objectPosition: `${-x}px ${-y}px`,
|
||||||
|
flexGrow: 0,
|
||||||
|
flexShrink: 0,
|
||||||
|
...style,
|
||||||
|
}}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
@ -19,11 +19,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { useFetch, QueryIdentifier, imageFn, Chapter } from "@kyoo/models";
|
import { useFetch, QueryIdentifier, imageFn, Chapter } from "@kyoo/models";
|
||||||
import { FastImage, P, imageBorderRadius, ts } from "@kyoo/primitives";
|
import { Sprite, P, imageBorderRadius, ts } from "@kyoo/primitives";
|
||||||
import { View } from "react-native";
|
import { View, Platform } from "react-native";
|
||||||
import { percent, useYoshiki, px, Theme } from "yoshiki/native";
|
import { percent, useYoshiki, px, Theme, useForceRerender } from "yoshiki/native";
|
||||||
import { ErrorView } from "../../fetch";
|
import { ErrorView } from "../../fetch";
|
||||||
import { useMemo } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { useAtomValue } from "jotai";
|
import { useAtomValue } from "jotai";
|
||||||
import { durationAtom, progressAtom } from "../state";
|
import { durationAtom, progressAtom } from "../state";
|
||||||
import { toTimerString } from "./left-buttons";
|
import { toTimerString } from "./left-buttons";
|
||||||
@ -128,7 +128,7 @@ export const ScrubberTooltip = ({
|
|||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{current && (
|
{current && (
|
||||||
<FastImage
|
<Sprite
|
||||||
src={current.url}
|
src={current.url}
|
||||||
alt={""}
|
alt={""}
|
||||||
width={current.width}
|
width={current.width}
|
||||||
@ -145,10 +145,12 @@ export const ScrubberTooltip = ({
|
|||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
let scrubberWidth = 0;
|
||||||
|
|
||||||
export const BottomScrubber = ({ url }: { url: string }) => {
|
export const BottomScrubber = ({ url }: { url: string }) => {
|
||||||
const { css } = useYoshiki();
|
const { css } = useYoshiki();
|
||||||
const { info, error, stats } = useScrubber(url);
|
const { info, error, stats } = useScrubber(url);
|
||||||
|
const rerender = useForceRerender();
|
||||||
|
|
||||||
const progress = useAtomValue(progressAtom);
|
const progress = useAtomValue(progressAtom);
|
||||||
const duration = useAtomValue(durationAtom) ?? 1;
|
const duration = useAtomValue(durationAtom) ?? 1;
|
||||||
@ -159,30 +161,44 @@ export const BottomScrubber = ({ url }: { url: string }) => {
|
|||||||
return (
|
return (
|
||||||
<View {...css({ overflow: "hidden" })}>
|
<View {...css({ overflow: "hidden" })}>
|
||||||
<View
|
<View
|
||||||
{...css(
|
{...(Platform.OS === "web"
|
||||||
{ flexDirection: "row" },
|
? css({ transform: `translateX(50%)` })
|
||||||
{
|
: {
|
||||||
style: {
|
// react-native does not support translateX by percentage so we simulate it
|
||||||
transform: `translateX(calc(${
|
style: { transform: [{ translateX: scrubberWidth / 2 }] },
|
||||||
(progress / duration) * -width * info.length - width / 2
|
onLayout: (e) => {
|
||||||
}px + 50%))`,
|
if (!e.nativeEvent.layout.width) return;
|
||||||
},
|
scrubberWidth = e.nativeEvent.layout.width;
|
||||||
},
|
rerender();
|
||||||
)}
|
},
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
{info.map((thumb) => (
|
<View
|
||||||
<FastImage
|
{...css(
|
||||||
key={thumb.to}
|
{ flexDirection: "row" },
|
||||||
src={thumb.url}
|
{
|
||||||
alt=""
|
style: {
|
||||||
width={thumb.width}
|
transform: `translateX(${
|
||||||
height={thumb.height}
|
(progress / duration) * -width * info.length - width / 2
|
||||||
x={thumb.x}
|
}px)`,
|
||||||
y={thumb.y}
|
},
|
||||||
columns={stats!.columns}
|
},
|
||||||
rows={stats!.rows}
|
)}
|
||||||
/>
|
>
|
||||||
))}
|
{info.map((thumb) => (
|
||||||
|
<Sprite
|
||||||
|
key={thumb.to}
|
||||||
|
src={thumb.url}
|
||||||
|
alt=""
|
||||||
|
width={thumb.width}
|
||||||
|
height={thumb.height}
|
||||||
|
x={thumb.x}
|
||||||
|
y={thumb.y}
|
||||||
|
columns={stats!.columns}
|
||||||
|
rows={stats!.rows}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View
|
<View
|
||||||
{...css({
|
{...css({
|
||||||
|
Loading…
x
Reference in New Issue
Block a user