From e46ca235165859baf4ce0f80fc00c48db0eddf76 Mon Sep 17 00:00:00 2001 From: qtchaos <72168435+qtchaos@users.noreply.github.com> Date: Fri, 12 Apr 2024 00:01:57 +0300 Subject: [PATCH] chore: clean up code and remove intervals --- .../player/atoms/NextEpisodeButton.tsx | 28 +++++--------- src/pages/parts/settings/PreferencesPart.tsx | 38 +++++-------------- src/utils/autoplay.ts | 11 ++++++ 3 files changed, 30 insertions(+), 47 deletions(-) create mode 100644 src/utils/autoplay.ts diff --git a/src/components/player/atoms/NextEpisodeButton.tsx b/src/components/player/atoms/NextEpisodeButton.tsx index 07d89068..75ef65b0 100644 --- a/src/components/player/atoms/NextEpisodeButton.tsx +++ b/src/components/player/atoms/NextEpisodeButton.tsx @@ -1,17 +1,15 @@ import classNames from "classnames"; -import { useCallback, useEffect } from "react"; +import { useCallback, useEffect, useRef } from "react"; import { useTranslation } from "react-i18next"; -import { isExtensionActiveCached } from "@/backend/extension/messaging"; import { Icon, Icons } from "@/components/Icon"; import { usePlayerMeta } from "@/components/player/hooks/usePlayerMeta"; import { Transition } from "@/components/utils/Transition"; -import { conf } from "@/setup/config"; -import { useAuthStore } from "@/stores/auth"; import { PlayerMeta } from "@/stores/player/slices/source"; import { usePlayerStore } from "@/stores/player/store"; import { usePreferencesStore } from "@/stores/preferences"; import { useProgressStore } from "@/stores/progress"; +import { isAutoplayAllowed } from "@/utils/autoplay"; function shouldShowNextEpisodeButton( time: number, @@ -64,6 +62,7 @@ export function NextEpisodeButton(props: { const enableAutoplay = usePreferencesStore((s) => s.enableAutoplay); let show = false; + const hasAutoplayed = useRef(false); if (showingState === "always") show = true; else if (showingState === "hover" && props.controlsShowing) show = true; if (isHidden || status !== "playing" || duration === 0) show = false; @@ -102,21 +101,14 @@ export function NextEpisodeButton(props: { useEffect(() => { if (!enableAutoplay || metaType !== "show") return; + const onePercent = duration / 100; + const isEnding = time >= duration - onePercent && duration !== 0; - const interval = setInterval(() => { - const onePercent = duration / 100; - const isEnding = time >= duration - onePercent && duration !== 0; - - const allowAutoplay = Boolean( - conf().ALLOW_AUTOPLAY || - isExtensionActiveCached() || - useAuthStore.getState().proxySet, - ); - - if (isEnding && allowAutoplay) loadNextEpisode(); - }, 250); - - return () => clearInterval(interval); + if (duration === 0) hasAutoplayed.current = false; + if (isEnding && isAutoplayAllowed() && !hasAutoplayed.current) { + hasAutoplayed.current = true; + loadNextEpisode(); + } }, [duration, enableAutoplay, loadNextEpisode, metaType, time]); if (!meta?.episode || !nextEp) return null; diff --git a/src/pages/parts/settings/PreferencesPart.tsx b/src/pages/parts/settings/PreferencesPart.tsx index f81e0c9e..efead293 100644 --- a/src/pages/parts/settings/PreferencesPart.tsx +++ b/src/pages/parts/settings/PreferencesPart.tsx @@ -1,28 +1,14 @@ +import classNames from "classnames"; import { useTranslation } from "react-i18next"; -import { useAsync } from "react-use"; -import { isExtensionActive } from "@/backend/extension/messaging"; import { Toggle } from "@/components/buttons/Toggle"; import { FlagIcon } from "@/components/FlagIcon"; import { Dropdown } from "@/components/form/Dropdown"; import { Heading1 } from "@/components/utils/Text"; -import { conf } from "@/setup/config"; import { appLanguageOptions } from "@/setup/i18n"; -import { useAuthStore } from "@/stores/auth"; +import { isAutoplayAllowed } from "@/utils/autoplay"; import { getLocaleInfo, sortLangCodes } from "@/utils/language"; -function useIsExtensionActive() { - const { loading, value } = useAsync(async () => { - const extensionStatus = (await isExtensionActive()) ? "success" : "unset"; - return extensionStatus === "success"; - }, []); - - return { - loading, - active: value, - }; -} - export function PreferencesPart(props: { language: string; setLanguage: (l: string) => void; @@ -33,14 +19,8 @@ export function PreferencesPart(props: { }) { const { t } = useTranslation(); const sorted = sortLangCodes(appLanguageOptions.map((item) => item.code)); - const { loading, active } = useIsExtensionActive(); - const extensionActive = active && !loading; - const allowAutoplay = Boolean( - conf().ALLOW_AUTOPLAY || - extensionActive || - useAuthStore.getState().proxySet, - ); + const allowAutoplay = isAutoplayAllowed(); const options = appLanguageOptions .sort((a, b) => sorted.indexOf(a.code) - sorted.indexOf(b.code)) @@ -101,12 +81,12 @@ export function PreferencesPart(props: { ? props.setEnableAutoplay(!props.enableAutoplay) : null } - className="bg-dropdown-background hover:bg-dropdown-hoverBackground select-none my-4 cursor-pointer space-x-3 flex items-center max-w-[25rem] py-3 px-4 rounded-lg" - style={{ - pointerEvents: allowAutoplay ? "auto" : "none", - opacity: allowAutoplay ? 1 : 0.5, - cursor: allowAutoplay ? "pointer" : "not-allowed", - }} + className={classNames( + "bg-dropdown-background hover:bg-dropdown-hoverBackground select-none my-4 cursor-pointer space-x-3 flex items-center max-w-[25rem] py-3 px-4 rounded-lg", + allowAutoplay ? "cursor-pointer" : "cursor-not-allowed", + allowAutoplay ? "opacity-100" : "opacity-50", + allowAutoplay ? "pointer-events-auto" : "pointer-events-none", + )} >

diff --git a/src/utils/autoplay.ts b/src/utils/autoplay.ts new file mode 100644 index 00000000..aee01ffb --- /dev/null +++ b/src/utils/autoplay.ts @@ -0,0 +1,11 @@ +import { isExtensionActiveCached } from "@/backend/extension/messaging"; +import { conf } from "@/setup/config"; +import { useAuthStore } from "@/stores/auth"; + +export function isAutoplayAllowed() { + return Boolean( + conf().ALLOW_AUTOPLAY || + isExtensionActiveCached() || + useAuthStore.getState().proxySet, + ); +}