mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-20 14:37:43 +01:00
Some shoepolish for movie-web
Co-authored-by: Jip Frijlink <JipFr@users.noreply.github.com>
This commit is contained in:
parent
b1b604d322
commit
4dc3a3216a
18 changed files with 186 additions and 83 deletions
|
@ -46,6 +46,7 @@
|
|||
"errors": {
|
||||
"details": "Error details",
|
||||
"reloadPage": "Reload the page",
|
||||
"showError": "Show error details",
|
||||
"badge": "It broke",
|
||||
"title": "That's an error boss"
|
||||
},
|
||||
|
|
|
@ -81,20 +81,10 @@ export function UserAvatar(props: {
|
|||
);
|
||||
}
|
||||
|
||||
export function NoUserAvatar(props: {
|
||||
sizeClass?: string;
|
||||
iconClass?: string;
|
||||
}) {
|
||||
export function NoUserAvatar(props: { iconClass?: string }) {
|
||||
return (
|
||||
<div className="relative inline-block">
|
||||
<div
|
||||
className={classNames(
|
||||
props.sizeClass ?? "w-[2rem] h-[2rem]",
|
||||
"rounded-full overflow-hidden flex items-center justify-center text-type-dimmed hover:text-type-secondary bg-pill-background bg-opacity-50 hover:bg-opacity-100 transition-colors duration-100"
|
||||
)}
|
||||
>
|
||||
<div className="relative inline-block p-1 text-type-dimmed">
|
||||
<Icon className={props.iconClass ?? "text-xl"} icon={Icons.MENU} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ export function LinksDropdown(props: { children: React.ReactNode }) {
|
|||
return (
|
||||
<div className="relative is-dropdown">
|
||||
<div
|
||||
className="cursor-pointer tabbable rounded-full flex gap-2 text-white items-center py-2 px-3 bg-pill-background bg-opacity-50"
|
||||
className="cursor-pointer tabbable rounded-full flex gap-2 text-white items-center py-2 px-3 bg-pill-background bg-opacity-50 hover:bg-pill-backgroundHover transition-[background,transform] duration-100 hover:scale-105"
|
||||
tabIndex={0}
|
||||
onClick={toggleOpen}
|
||||
onKeyUp={(evt) => evt.key === "Enter" && toggleOpen()}
|
||||
|
|
|
@ -99,6 +99,8 @@ export function Button(props: Props) {
|
|||
);
|
||||
}
|
||||
|
||||
// Sometimes you can't use normal button, due to not having access to a useHistory context
|
||||
// When that happens, use this!
|
||||
interface ButtonPlainProps {
|
||||
onClick?: () => void;
|
||||
children?: ReactNode;
|
||||
|
|
|
@ -21,7 +21,7 @@ export function Dropdown(props: DropdownProps) {
|
|||
<Listbox value={props.selectedItem} onChange={props.setSelectedItem}>
|
||||
{() => (
|
||||
<>
|
||||
<Listbox.Button className="relative w-full cursor-default rounded-lg bg-dropdown-background py-3 pl-3 pr-10 text-left text-white shadow-md focus:outline-none tabbable">
|
||||
<Listbox.Button className="relative w-full rounded-lg bg-dropdown-background py-3 pl-3 pr-10 text-left text-white shadow-md focus:outline-none tabbable cursor-pointer">
|
||||
<span className="flex gap-4 items-center truncate">
|
||||
{props.selectedItem.leftIcon
|
||||
? props.selectedItem.leftIcon
|
||||
|
@ -45,7 +45,7 @@ export function Dropdown(props: DropdownProps) {
|
|||
{props.options.map((opt) => (
|
||||
<Listbox.Option
|
||||
className={({ active }) =>
|
||||
`flex gap-4 items-center relative cursor-default select-none py-3 pl-4 pr-4 ${
|
||||
`cursor-pointer flex gap-4 items-center relative select-none py-3 pl-4 pr-4 ${
|
||||
active
|
||||
? "bg-background-secondaryHover text-type-link"
|
||||
: "text-white"
|
||||
|
|
|
@ -24,7 +24,7 @@ export const SearchBarInput = forwardRef<HTMLInputElement, SearchBarProps>(
|
|||
return (
|
||||
<Flare.Base
|
||||
className={c({
|
||||
"hover:flare-enabled group relative flex flex-col rounded-[28px] transition-colors sm:flex-row sm:items-center":
|
||||
"hover:flare-enabled group flex flex-col rounded-[28px] transition-colors sm:flex-row sm:items-center relative":
|
||||
true,
|
||||
"bg-search-background": !focused,
|
||||
"bg-search-focused": focused,
|
||||
|
@ -40,7 +40,6 @@ export const SearchBarInput = forwardRef<HTMLInputElement, SearchBarProps>(
|
|||
"bg-search-focused": focused,
|
||||
})}
|
||||
/>
|
||||
|
||||
<Flare.Child className="flex flex-1 flex-col">
|
||||
<div className="pointer-events-none absolute bottom-0 left-5 top-0 flex max-h-14 items-center text-search-icon">
|
||||
<Icon icon={Icons.SEARCH} />
|
||||
|
|
|
@ -55,7 +55,7 @@ export function Footer() {
|
|||
</h3>
|
||||
<p className="mt-3">{t("footer.legal.disclaimerText")}</p>
|
||||
</div>
|
||||
<div className="space-x-[0.5rem] -ml-3">
|
||||
<div className="flex flex-wrap gap-[0.5rem] -ml-3">
|
||||
<FooterLink icon={Icons.GITHUB} href={conf().GITHUB_LINK}>
|
||||
{t("footer.links.github")}
|
||||
</FooterLink>
|
||||
|
|
|
@ -59,6 +59,7 @@ export function Navigation(props: NavigationProps) {
|
|||
<BlurEllipsis positionClass="absolute" />
|
||||
</div>
|
||||
) : null}
|
||||
<div className="opacity-0 absolute inset-0 block h-20 pointer-events-auto" />
|
||||
<div
|
||||
className={`${
|
||||
props.bg ? "opacity-100" : "opacity-0"
|
||||
|
@ -77,8 +78,8 @@ export function Navigation(props: NavigationProps) {
|
|||
}}
|
||||
>
|
||||
<div className={classNames("fixed left-0 right-0 flex items-center")}>
|
||||
<div className="pointer-events-auto px-7 py-5 relative z-[60] flex flex-1 items-center">
|
||||
<div className="flex items-center flex-1 space-x-3">
|
||||
<div className="px-7 py-5 relative z-[60] flex flex-1 items-center justify-between">
|
||||
<div className="flex items-center space-x-3 pointer-events-auto">
|
||||
<Link className="block tabbable rounded-full" to="/">
|
||||
<BrandPill clickable />
|
||||
</Link>
|
||||
|
@ -99,7 +100,7 @@ export function Navigation(props: NavigationProps) {
|
|||
<IconPatch icon={Icons.GITHUB} clickable downsized />
|
||||
</a>
|
||||
</div>
|
||||
<div className="relative">
|
||||
<div className="relative pointer-events-auto">
|
||||
<LinksDropdown>
|
||||
{loggedIn ? <UserAvatar withName /> : <NoUserAvatar />}
|
||||
</LinksDropdown>
|
||||
|
|
|
@ -23,7 +23,7 @@ export function AutoPlayStart() {
|
|||
return (
|
||||
<div
|
||||
onClick={handleClick}
|
||||
className="group pointer-events-auto flex h-16 w-16 cursor-pointer items-center justify-center rounded-full text-white transition-[background-color,transform] hover:scale-125 active:scale-100"
|
||||
className="group pointer-events-auto flex h-16 w-16 cursor-pointer items-center justify-center bg-video-autoPlay-background hover:bg-video-autoPlay-hover rounded-full text-white transition-[background-color,transform] hover:scale-125 active:scale-100"
|
||||
>
|
||||
<Icon
|
||||
icon={Icons.PLAY}
|
||||
|
|
|
@ -230,7 +230,7 @@ export function CaptionSettingsView({ id }: { id: string }) {
|
|||
</Menu.BackLink>
|
||||
<Menu.Section className="space-y-6">
|
||||
<CaptionSetting
|
||||
label={t("player.menus.captions.settings.fixCapitals")}
|
||||
label={t("player.menus.captions.settings.delay")}
|
||||
max={10}
|
||||
min={-10}
|
||||
onChange={(v) => setDelay(v)}
|
||||
|
@ -241,7 +241,7 @@ export function CaptionSettingsView({ id }: { id: string }) {
|
|||
/>
|
||||
<div className="flex justify-between items-center">
|
||||
<Menu.FieldTitle>
|
||||
{t("player.menus.captions.settings.delay")}
|
||||
{t("player.menus.captions.settings.fixCapitals")}
|
||||
</Menu.FieldTitle>
|
||||
<div className="flex justify-center items-center">
|
||||
<Toggle
|
||||
|
|
|
@ -3,10 +3,13 @@ import { useTranslation } from "react-i18next";
|
|||
|
||||
import { Button } from "@/components/buttons/Button";
|
||||
import { Icon, Icons } from "@/components/Icon";
|
||||
import { Modal } from "@/components/overlays/Modal";
|
||||
import { DisplayError } from "@/components/player/display/displayInterface";
|
||||
|
||||
export function ErrorCard(props: { error: DisplayError | string }) {
|
||||
const [showErrorCard, setShowErrorCard] = useState(true);
|
||||
export function ErrorCard(props: {
|
||||
error: DisplayError | string;
|
||||
onClose: () => void;
|
||||
}) {
|
||||
const [hasCopied, setHasCopied] = useState(false);
|
||||
const hasCopiedUnsetDebounce = useRef<ReturnType<typeof setTimeout> | null>(
|
||||
null
|
||||
|
@ -32,8 +35,6 @@ export function ErrorCard(props: { error: DisplayError | string }) {
|
|||
hasCopiedUnsetDebounce.current = setTimeout(() => setHasCopied(false), 2e3);
|
||||
}
|
||||
|
||||
if (!showErrorCard) return null;
|
||||
|
||||
return (
|
||||
// I didn't put a <Transition> here because it'd fade out, then jump height weirdly
|
||||
<div className="w-full bg-errors-card p-6 rounded-lg">
|
||||
|
@ -60,7 +61,7 @@ export function ErrorCard(props: { error: DisplayError | string }) {
|
|||
<Button
|
||||
theme="secondary"
|
||||
padding="p-2 md:px-2"
|
||||
onClick={() => setShowErrorCard(false)}
|
||||
onClick={props.onClose}
|
||||
>
|
||||
<Icon icon={Icons.X} className="text-2xl" />
|
||||
</Button>
|
||||
|
@ -72,3 +73,35 @@ export function ErrorCard(props: { error: DisplayError | string }) {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// use plain modal version if there is no access to history api (like in error boundary)
|
||||
export function ErrorCardInPlainModal(props: {
|
||||
error?: DisplayError | string;
|
||||
onClose: () => void;
|
||||
show?: boolean;
|
||||
}) {
|
||||
if (!props.show || !props.error) return null;
|
||||
return (
|
||||
<div className="fixed inset-0 w-full h-full bg-black bg-opacity-30 flex justify-center items-center p-12">
|
||||
<div className="max-w-2xl">
|
||||
<ErrorCard error={props.error} onClose={props.onClose} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function ErrorCardInModal(props: {
|
||||
error?: DisplayError | string;
|
||||
id: string;
|
||||
onClose: () => void;
|
||||
}) {
|
||||
if (!props.error) return null;
|
||||
|
||||
return (
|
||||
<Modal id={props.id}>
|
||||
<div className="max-w-2xl pointer-events-auto">
|
||||
<ErrorCard error={props.error} onClose={props.onClose} />
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { ButtonPlain } from "@/components/buttons/Button";
|
||||
|
@ -7,10 +8,11 @@ import { DisplayError } from "@/components/player/display/displayInterface";
|
|||
import { Title } from "@/components/text/Title";
|
||||
import { Paragraph } from "@/components/utils/Text";
|
||||
import { ErrorContainer, ErrorLayout } from "@/pages/layouts/ErrorLayout";
|
||||
import { ErrorCard } from "@/pages/parts/errors/ErrorCard";
|
||||
import { ErrorCardInPlainModal } from "@/pages/parts/errors/ErrorCard";
|
||||
|
||||
export function ErrorPart(props: { error: any; errorInfo: any }) {
|
||||
const { t } = useTranslation();
|
||||
const [showErrorCard, setShowErrorCard] = useState(false);
|
||||
|
||||
const maxLineCount = 5;
|
||||
const errorLines = (props.errorInfo.componentStack || "")
|
||||
|
@ -30,15 +32,30 @@ export function ErrorPart(props: { error: any; errorInfo: any }) {
|
|||
<ErrorContainer maxWidth="max-w-2xl">
|
||||
<IconPill icon={Icons.EYE_SLASH}>{t("errors.badge")}</IconPill>
|
||||
<Title>{t("errors.title")}</Title>
|
||||
|
||||
<Paragraph>{props.error.toString()}</Paragraph>
|
||||
<ErrorCard error={error} />
|
||||
<ErrorCardInPlainModal
|
||||
show={showErrorCard}
|
||||
onClose={() => setShowErrorCard(false)}
|
||||
error={error}
|
||||
/>
|
||||
|
||||
<div className="flex gap-3">
|
||||
<ButtonPlain
|
||||
theme="purple"
|
||||
theme="secondary"
|
||||
className="mt-6 md:px-12 p-2.5"
|
||||
onClick={() => window.location.reload()}
|
||||
>
|
||||
{t("errors.reloadPage")}
|
||||
</ButtonPlain>
|
||||
<ButtonPlain
|
||||
theme="purple"
|
||||
className="mt-6 md:px-12 p-2.5"
|
||||
onClick={() => setShowErrorCard(true)}
|
||||
>
|
||||
{t("errors.showError")}
|
||||
</ButtonPlain>
|
||||
</div>
|
||||
</ErrorContainer>
|
||||
</ErrorLayout>
|
||||
</div>
|
||||
|
|
|
@ -3,16 +3,18 @@ import { useTranslation } from "react-i18next";
|
|||
import { Button } from "@/components/buttons/Button";
|
||||
import { Icons } from "@/components/Icon";
|
||||
import { IconPill } from "@/components/layout/IconPill";
|
||||
import { useModal } from "@/components/overlays/Modal";
|
||||
import { Paragraph } from "@/components/text/Paragraph";
|
||||
import { Title } from "@/components/text/Title";
|
||||
import { ErrorContainer, ErrorLayout } from "@/pages/layouts/ErrorLayout";
|
||||
import { usePlayerStore } from "@/stores/player/store";
|
||||
|
||||
import { ErrorCard } from "../errors/ErrorCard";
|
||||
import { ErrorCardInModal } from "../errors/ErrorCard";
|
||||
|
||||
export function PlaybackErrorPart() {
|
||||
const { t } = useTranslation();
|
||||
const playbackError = usePlayerStore((s) => s.interface.error);
|
||||
const modal = useModal("error");
|
||||
|
||||
return (
|
||||
<ErrorLayout>
|
||||
|
@ -20,19 +22,31 @@ export function PlaybackErrorPart() {
|
|||
<IconPill icon={Icons.WAND}>{t("player.playbackError.badge")}</IconPill>
|
||||
<Title>{t("player.playbackError.title")}</Title>
|
||||
<Paragraph>{t("player.playbackError.text")}</Paragraph>
|
||||
<div className="flex gap-3">
|
||||
<Button
|
||||
href="/"
|
||||
theme="purple"
|
||||
theme="secondary"
|
||||
padding="md:px-12 p-2.5"
|
||||
className="mt-6"
|
||||
>
|
||||
{t("player.playbackError.homeButton")}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => modal.show()}
|
||||
theme="purple"
|
||||
padding="md:px-12 p-2.5"
|
||||
className="mt-6"
|
||||
>
|
||||
{t("errors.showError")}
|
||||
</Button>
|
||||
</div>
|
||||
</ErrorContainer>
|
||||
<ErrorContainer maxWidth="max-w-[45rem]">
|
||||
{/* Error */}
|
||||
{playbackError ? <ErrorCard error={playbackError} /> : null}
|
||||
</ErrorContainer>
|
||||
<ErrorCardInModal
|
||||
onClose={() => modal.hide()}
|
||||
error={playbackError}
|
||||
id={modal.id}
|
||||
/>
|
||||
</ErrorLayout>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -64,38 +64,54 @@ export function PlayerPart(props: PlayerPartProps) {
|
|||
<BrandPill />
|
||||
</div>
|
||||
<div className="flex sm:hidden items-center justify-end">
|
||||
{status === playerStatus.PLAYING ? (
|
||||
<>
|
||||
<Player.Airplay />
|
||||
<Player.Chromecast />
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</Player.TopControls>
|
||||
|
||||
<Player.BottomControls show={showTargets}>
|
||||
<div className="flex items-center space-x-3">
|
||||
{status === playerStatus.PLAYING ? (
|
||||
<>
|
||||
{isMobile ? <Player.Time short /> : null}
|
||||
<Player.ProgressBar />
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="hidden lg:flex justify-between">
|
||||
<Player.LeftSideControls>
|
||||
{status === playerStatus.PLAYING ? (
|
||||
<>
|
||||
<Player.Pause />
|
||||
<Player.SkipBackward />
|
||||
<Player.SkipForward />
|
||||
<Player.Volume />
|
||||
<Player.Time />
|
||||
</>
|
||||
) : null}
|
||||
</Player.LeftSideControls>
|
||||
<div className="flex items-center space-x-3">
|
||||
<Player.Episodes />
|
||||
{status === playerStatus.PLAYING ? (
|
||||
<>
|
||||
<Player.Pip />
|
||||
<Player.Airplay />
|
||||
<Player.Chromecast />
|
||||
<Player.Settings />
|
||||
</>
|
||||
) : null}
|
||||
<Player.Fullscreen />
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-[2.5rem,1fr,2.5rem] gap-3 lg:hidden">
|
||||
<div />
|
||||
<div className="flex justify-center space-x-3">
|
||||
<Player.Pip />
|
||||
{status === playerStatus.PLAYING ? <Player.Pip /> : null}
|
||||
<Player.Episodes />
|
||||
<Player.Settings />
|
||||
</div>
|
||||
|
|
|
@ -4,12 +4,13 @@ import { useTranslation } from "react-i18next";
|
|||
import { Button } from "@/components/buttons/Button";
|
||||
import { Icons } from "@/components/Icon";
|
||||
import { IconPill } from "@/components/layout/IconPill";
|
||||
import { useModal } from "@/components/overlays/Modal";
|
||||
import { Paragraph } from "@/components/text/Paragraph";
|
||||
import { Title } from "@/components/text/Title";
|
||||
import { ScrapingItems, ScrapingSegment } from "@/hooks/useProviderScrape";
|
||||
import { ErrorContainer, ErrorLayout } from "@/pages/layouts/ErrorLayout";
|
||||
|
||||
import { ErrorCard } from "../errors/ErrorCard";
|
||||
import { ErrorCardInModal } from "../errors/ErrorCard";
|
||||
|
||||
export interface ScrapeErrorPartProps {
|
||||
data: {
|
||||
|
@ -20,6 +21,8 @@ export interface ScrapeErrorPartProps {
|
|||
|
||||
export function ScrapeErrorPart(props: ScrapeErrorPartProps) {
|
||||
const { t } = useTranslation();
|
||||
const modal = useModal("error");
|
||||
|
||||
const error = useMemo(() => {
|
||||
const data = props.data;
|
||||
const amountError = Object.values(data.sources).filter(
|
||||
|
@ -43,18 +46,33 @@ export function ScrapeErrorPart(props: ScrapeErrorPartProps) {
|
|||
</IconPill>
|
||||
<Title>{t("player.scraping.notFound.title")}</Title>
|
||||
<Paragraph>{t("player.scraping.notFound.text")}</Paragraph>
|
||||
<div className="flex gap-3">
|
||||
<Button
|
||||
href="/"
|
||||
theme="purple"
|
||||
theme="secondary"
|
||||
padding="md:px-12 p-2.5"
|
||||
className="mt-6"
|
||||
>
|
||||
{t("player.scraping.notFound.homeButton")}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => modal.show()}
|
||||
theme="purple"
|
||||
padding="md:px-12 p-2.5"
|
||||
className="mt-6"
|
||||
>
|
||||
{t("errors.showError")}
|
||||
</Button>
|
||||
</div>
|
||||
</ErrorContainer>
|
||||
<ErrorContainer maxWidth="max-w-[45rem]">
|
||||
{/* Error */}
|
||||
{error ? <ErrorCard error={error} /> : null}
|
||||
{error ? (
|
||||
<ErrorCardInModal
|
||||
id={modal.id}
|
||||
onClose={() => modal.hide()}
|
||||
error={error}
|
||||
/>
|
||||
) : null}
|
||||
</ErrorContainer>
|
||||
</ErrorLayout>
|
||||
);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import classNames from "classnames";
|
||||
import { useState } from "react";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { Icon, Icons } from "@/components/Icon";
|
||||
|
@ -29,6 +30,11 @@ export function CaptionPreview(props: {
|
|||
"fixed inset-0 z-[60]": props.fullscreen,
|
||||
})}
|
||||
>
|
||||
{props.fullscreen && props.show ? (
|
||||
<Helmet>
|
||||
<html data-no-scroll />
|
||||
</Helmet>
|
||||
) : null}
|
||||
<Transition animation="fade" show={props.show}>
|
||||
<div
|
||||
className="absolute inset-0 pointer-events-auto"
|
||||
|
|
|
@ -115,10 +115,10 @@ function BackendEdit({ backendUrl, setBackendUrl }: BackendEditProps) {
|
|||
<div className="flex justify-between items-center gap-4">
|
||||
<div className="my-3">
|
||||
<p className="text-white font-bold mb-3">
|
||||
{t("settings.connections.workers.label")}
|
||||
{t("settings.connections.server.label")}
|
||||
</p>
|
||||
<p className="max-w-[20rem] font-medium">
|
||||
{t("settings.connections.workers.description")}
|
||||
{t("settings.connections.server.description")}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -132,7 +132,7 @@ function BackendEdit({ backendUrl, setBackendUrl }: BackendEditProps) {
|
|||
<>
|
||||
<Divider marginClass="my-6 px-8 box-content -mx-8" />
|
||||
<p className="text-white font-bold mb-3">
|
||||
{t("settings.connections.workers.urlLabel")}
|
||||
{t("settings.connections.server.urlLabel")}
|
||||
</p>
|
||||
<AuthInputBox onChange={setBackendUrl} value={backendUrl ?? ""} />
|
||||
</>
|
||||
|
|
|
@ -9,8 +9,8 @@ export const defaultTheme = {
|
|||
|
||||
// Branding
|
||||
pill: {
|
||||
background: "#1C1C36",
|
||||
backgroundHover: "#1C1C36",
|
||||
background: "#2e2e4d",
|
||||
backgroundHover: "#3d3d61",
|
||||
highlight: "#714C97",
|
||||
},
|
||||
|
||||
|
@ -97,7 +97,7 @@ export const defaultTheme = {
|
|||
dropdown: {
|
||||
background: "#171728",
|
||||
altBackground: "#151525",
|
||||
highlight: "#FCEC61",
|
||||
highlight: "#afa349",
|
||||
highlightHover: "#FCEC61",
|
||||
text: "#846D95",
|
||||
secondary: "#73739D",
|
||||
|
@ -179,6 +179,11 @@ export const defaultTheme = {
|
|||
video: {
|
||||
buttonBackground: "#444B5C",
|
||||
|
||||
autoPlay: {
|
||||
background: "#161C26",
|
||||
hover: "#252533"
|
||||
},
|
||||
|
||||
scraping: {
|
||||
card: "#161620",
|
||||
error: "#E44F4F",
|
||||
|
@ -211,6 +216,7 @@ export const defaultTheme = {
|
|||
active: "#0D1317",
|
||||
},
|
||||
|
||||
|
||||
type: {
|
||||
main: "#617A8A",
|
||||
secondary: "#374A56",
|
||||
|
|
Loading…
Reference in a new issue