From cf4cb6f300c096444ca741c55fe4c2983f8b4d0d Mon Sep 17 00:00:00 2001 From: Jip Fr <jipfrijlink@gmail.com> Date: Sat, 16 Dec 2023 16:21:50 +0100 Subject: [PATCH] Some RTL fixes Co-authored-by: mrjvs <mistrjvs@gmail.com> --- src/assets/css/index.css | 5 +++ src/components/Icon.tsx | 11 ++++- .../positions/OverlayAnchorPosition.tsx | 2 +- src/components/player/atoms/ProgressBar.tsx | 2 +- src/components/player/internals/Button.tsx | 10 +---- src/components/utils/Lightbar.css | 12 +++--- src/pages/parts/player/PlayerPart.tsx | 2 +- src/pages/parts/player/ScrapingPart.tsx | 29 +++++++------ src/stores/language/index.ts | 42 ------------------- tailwind.config.ts | 23 ++++++---- 10 files changed, 56 insertions(+), 82 deletions(-) delete mode 100644 src/stores/language/index.ts diff --git a/src/assets/css/index.css b/src/assets/css/index.css index 74eb1270..809c5cda 100644 --- a/src/assets/css/index.css +++ b/src/assets/css/index.css @@ -222,3 +222,8 @@ input[type=range].styled-slider.slider-progress::-ms-fill-lower { outline: 2px solid theme('colors.themePreview.primary'); box-shadow: 0 0 10px theme('colors.themePreview.secondary'); } + +[dir="rtl"] .transform { + /* Invert horizontal X offset on transform (Tailwind RTL plugin does the rest) */ + transform: translate(calc(var(--tw-translate-x) * -1), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) !important; +} \ No newline at end of file diff --git a/src/components/Icon.tsx b/src/components/Icon.tsx index 6f5c676e..ef08938e 100644 --- a/src/components/Icon.tsx +++ b/src/components/Icon.tsx @@ -1,3 +1,4 @@ +import classNames from "classnames"; import { memo, useEffect, useRef } from "react"; export enum Icons { @@ -150,10 +151,18 @@ export const Icon = memo((props: IconProps) => { return <ChromeCastButton />; } + const flipClass = + props.icon === Icons.ARROW_LEFT || + props.icon === Icons.ARROW_RIGHT || + props.icon === Icons.CHEVRON_LEFT || + props.icon === Icons.CHEVRON_RIGHT + ? "rtl:-scale-x-100" + : ""; + return ( <span dangerouslySetInnerHTML={{ __html: iconList[props.icon] }} // eslint-disable-line react/no-danger - className={props.className} + className={classNames(props.className, flipClass)} /> ); }); diff --git a/src/components/overlays/positions/OverlayAnchorPosition.tsx b/src/components/overlays/positions/OverlayAnchorPosition.tsx index 028f721d..49cb7d69 100644 --- a/src/components/overlays/positions/OverlayAnchorPosition.tsx +++ b/src/components/overlays/positions/OverlayAnchorPosition.tsx @@ -64,7 +64,7 @@ export function OverlayAnchorPosition(props: AnchorPositionProps) { transform: `translateX(${left}px) translateY(${top}px)`, }} className={classNames([ - "pointer-events-auto z-10 inline-block origin-top-left touch-none", + "[&>*]:pointer-events-auto z-10 flex dir-neutral:items-start justify-start dir-neutral:origin-top-left touch-none", props.className, ])} > diff --git a/src/components/player/atoms/ProgressBar.tsx b/src/components/player/atoms/ProgressBar.tsx index c5deb7ca..887e5ed8 100644 --- a/src/components/player/atoms/ProgressBar.tsx +++ b/src/components/player/atoms/ProgressBar.tsx @@ -119,7 +119,7 @@ export function ProgressBar() { }, [setDraggingTime, duration, dragPercentage]); return ( - <div className="w-full relative"> + <div className="w-full relative" dir="ltr"> <div className="top-0 absolute inset-x-0"> <div className="absolute bottom-0" diff --git a/src/components/player/internals/Button.tsx b/src/components/player/internals/Button.tsx index 16ddda0b..146e34fe 100644 --- a/src/components/player/internals/Button.tsx +++ b/src/components/player/internals/Button.tsx @@ -22,20 +22,14 @@ export const VideoPlayerButton = forwardRef< type="button" onClick={(e) => props.onClick?.(e.currentTarget as HTMLButtonElement)} className={classNames([ - "tabbable p-2 rounded-full hover:bg-video-buttonBackground hover:bg-opacity-50 transition-transform duration-100 flex items-center", + "tabbable p-2 rounded-full hover:bg-video-buttonBackground hover:bg-opacity-50 transition-transform duration-100 flex items-center gap-3", props.activeClass ?? "active:scale-110 active:bg-opacity-75 active:text-white", props.className ?? "", ])} > {props.icon && ( - <Icon - className={classNames( - props.iconSizeClass || "text-2xl", - props.children ? "mr-3" : "" - )} - icon={props.icon} - /> + <Icon className={props.iconSizeClass || "text-2xl"} icon={props.icon} /> )} {props.children} </button> diff --git a/src/components/utils/Lightbar.css b/src/components/utils/Lightbar.css index 06f7ffe8..d5d12310 100644 --- a/src/components/utils/Lightbar.css +++ b/src/components/utils/Lightbar.css @@ -6,7 +6,7 @@ user-select: none; } -.lightbar { +[dir] .lightbar { left: 50vw; transform: translateX(-50%); } @@ -16,13 +16,14 @@ width: 150vw; } - .lightbar { + [dir] .lightbar { left: -25vw; transform: initial; } + } -.lightbar { +[dir] .lightbar { display: flex; justify-content: center; align-items: center; @@ -31,7 +32,7 @@ animation: boot var(--d) var(--animation) forwards; } -.lightbar-visual { +[dir] .lightbar-visual { left: 0; --top: theme('colors.background.main'); --bottom: theme('colors.lightBar.light'); @@ -57,7 +58,6 @@ @keyframes boot { from { - opacity: 0.25; } @@ -74,4 +74,4 @@ 100% { transform: rotate(180deg) translateZ(0px) translateY(400px) scaleX(1); } -} +} \ No newline at end of file diff --git a/src/pages/parts/player/PlayerPart.tsx b/src/pages/parts/player/PlayerPart.tsx index 48a25094..371087e3 100644 --- a/src/pages/parts/player/PlayerPart.tsx +++ b/src/pages/parts/player/PlayerPart.tsx @@ -88,7 +88,7 @@ export function PlayerPart(props: PlayerPartProps) { </> ) : null} </div> - <div className="hidden lg:flex justify-between"> + <div className="hidden lg:flex justify-between" dir="ltr"> <Player.LeftSideControls> {status === playerStatus.PLAYING ? ( <> diff --git a/src/pages/parts/player/ScrapingPart.tsx b/src/pages/parts/player/ScrapingPart.tsx index eee6edcb..de32f711 100644 --- a/src/pages/parts/player/ScrapingPart.tsx +++ b/src/pages/parts/player/ScrapingPart.tsx @@ -60,18 +60,18 @@ export function ScrapingPart(props: ScrapingProps) { (async () => { const output = await startScraping(props.media); if (!isMounted()) return; - props.onResult?.( - resultRef.current.sources, - resultRef.current.sourceOrder - ); - report( - scrapePartsToProviderMetric( - props.media, - resultRef.current.sourceOrder, - resultRef.current.sources - ) - ); - props.onGetStream?.(output); + // props.onResult?.( + // resultRef.current.sources, + // resultRef.current.sourceOrder + // ); + // report( + // scrapePartsToProviderMetric( + // props.media, + // resultRef.current.sourceOrder, + // resultRef.current.sources + // ) + // ); + // props.onGetStream?.(output); })(); }, [startScraping, props, report, isMounted]); @@ -85,7 +85,10 @@ export function ScrapingPart(props: ScrapingProps) { currentProviderIndex = sourceOrder.length - 1; return ( - <div className="h-full w-full relative" ref={containerRef}> + <div + className="h-full w-full relative dir-neutral:origin-top-left flex dir-neutral:flex-row dir-neutral:items-start dir-neutral:justify-start" + ref={containerRef} + > <div className={classNames({ "absolute transition-[transform,opacity] opacity-0": true, diff --git a/src/stores/language/index.ts b/src/stores/language/index.ts deleted file mode 100644 index 1bf632ed..00000000 --- a/src/stores/language/index.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { useEffect } from "react"; -import { create } from "zustand"; -import { persist } from "zustand/middleware"; -import { immer } from "zustand/middleware/immer"; - -import i18n from "@/setup/i18n"; -import { rtlLocales } from "@/assets/languages"; - -export interface LanguageStore { - language: string; - setLanguage(v: string): void; -} - -export const useLanguageStore = create( - persist( - immer<LanguageStore>((set) => ({ - language: "en", - setLanguage(v) { - set((s) => { - s.language = v; - }); - }, - })), - { name: "__MW::locale" } - ) -); - -export function LanguageProvider() { - const language = useLanguageStore((s) => s.language); - - useEffect(() => { - i18n.changeLanguage(language); - }, [language]); - - const isRtl = rtlLocales.includes(language); - - return ( - <Helmet> - <html dir={isRtl ? "rtl" : "ltr"} /> - </Helmet> - ); -} diff --git a/tailwind.config.ts b/tailwind.config.ts index 83da3298..ee5ef13f 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,5 +1,6 @@ import { allThemes, defaultTheme, safeThemeList } from "./themes"; -import type { Config } from "tailwindcss" +import type { Config } from "tailwindcss"; +import plugin from "tailwindcss/plugin"; const themer = require("tailwindcss-themer"); @@ -10,18 +11,18 @@ const config: Config = { extend: { /* fonts */ fontFamily: { - "open-sans": "'Open Sans'" + "open-sans": "'Open Sans'", }, /* animations */ keyframes: { "loading-pin": { "0%, 40%, 100%": { height: "0.5em", "background-color": "#282336" }, - "20%": { height: "1em", "background-color": "white" } - } + "20%": { height: "1em", "background-color": "white" }, + }, }, - animation: { "loading-pin": "loading-pin 1.8s ease-in-out infinite" } - } + animation: { "loading-pin": "loading-pin 1.8s ease-in-out infinite" }, + }, }, plugins: [ require("tailwind-scrollbar"), @@ -33,9 +34,13 @@ const config: Config = { selectors: [".theme-default"], ...defaultTheme, }, - ...allThemes] - }) - ] + ...allThemes, + ], + }), + plugin(({ addVariant }) => { + addVariant("dir-neutral", "[dir] &"); + }), + ], }; export default config;