mirror of
https://github.com/p-stream/p-stream.git
synced 2026-03-30 19:18:48 +00:00
Add toggle for skipping at 99%
This commit is contained in:
parent
81138d5d90
commit
1aa47cfe7c
6 changed files with 76 additions and 4 deletions
|
|
@ -673,6 +673,9 @@
|
|||
"autoplay": "Autoplay",
|
||||
"autoplayDescription": "Automatically play the next episode in a series after reaching the end. Can be enabled by users with the browser extension, a custom proxy, or with the default setup if allowed by the host.",
|
||||
"autoplayLabel": "Autoplay",
|
||||
"skipCredits": "Skip End Credits",
|
||||
"skipCreditsDescription": "When enabled, automatically play the next episode at 99% completion to skip end credits. When disabled, wait until the episode is fully completed.",
|
||||
"skipCreditsLabel": "Skip end credits",
|
||||
"sourceOrder": "Reordering sources",
|
||||
"sourceOrderDescription": "Drag and drop to reorder sources. This will determine the order in which sources are checked for the media you are trying to watch. If a source is greyed out, it means the <bold>extension</bold> is required for that source. <br><br> <strong>(The default order is best for most users)</strong>",
|
||||
"title": "Preferences",
|
||||
|
|
|
|||
|
|
@ -101,13 +101,14 @@ export function NextEpisodeButton(props: {
|
|||
const { setDirectMeta } = usePlayerMeta();
|
||||
const metaType = usePlayerStore((s) => s.meta?.type);
|
||||
const time = usePlayerStore((s) => s.progress.time);
|
||||
const enableAutoplay = usePreferencesStore((s) => s.enableAutoplay);
|
||||
const enableSkipCredits = usePreferencesStore((s) => s.enableSkipCredits);
|
||||
const showingState = shouldShowNextEpisodeButton(time, duration);
|
||||
const status = usePlayerStore((s) => s.status);
|
||||
const setShouldStartFromBeginning = usePlayerStore(
|
||||
(s) => s.setShouldStartFromBeginning,
|
||||
);
|
||||
const updateItem = useProgressStore((s) => s.updateItem);
|
||||
const enableAutoplay = usePreferencesStore((s) => s.enableAutoplay);
|
||||
|
||||
const isLastEpisode =
|
||||
!meta?.episode?.number || !meta?.episodes?.at(-1)?.number
|
||||
|
|
@ -187,14 +188,25 @@ export function NextEpisodeButton(props: {
|
|||
useEffect(() => {
|
||||
if (!enableAutoplay || metaType !== "show") return;
|
||||
const onePercent = duration / 100;
|
||||
const isEnding = time >= duration - onePercent && duration !== 0;
|
||||
|
||||
// When skipCredits is enabled, use the 99% threshold; otherwise require 100% completion
|
||||
const isEnding = enableSkipCredits
|
||||
? time >= duration - onePercent && duration !== 0 // 99% completion
|
||||
: time >= duration && duration !== 0; // 100% completion
|
||||
|
||||
if (duration === 0) hasAutoplayed.current = false;
|
||||
if (isEnding && isAutoplayAllowed() && !hasAutoplayed.current) {
|
||||
hasAutoplayed.current = true;
|
||||
loadNextEpisode();
|
||||
}
|
||||
}, [duration, enableAutoplay, loadNextEpisode, metaType, time]);
|
||||
}, [
|
||||
duration,
|
||||
enableAutoplay,
|
||||
enableSkipCredits,
|
||||
loadNextEpisode,
|
||||
metaType,
|
||||
time,
|
||||
]);
|
||||
|
||||
if (!meta?.episode || !nextEp) return null;
|
||||
if (metaType !== "show") return null;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ export function useSettingsState(
|
|||
sourceOrder: string[],
|
||||
enableSourceOrder: boolean,
|
||||
proxyTmdb: boolean,
|
||||
enableSkipCredits: boolean,
|
||||
) {
|
||||
const [proxyUrlsState, setProxyUrls, resetProxyUrls, proxyUrlsChanged] =
|
||||
useDerived(proxyUrls);
|
||||
|
|
@ -103,6 +104,12 @@ export function useSettingsState(
|
|||
resetEnableAutoplay,
|
||||
enableAutoplayChanged,
|
||||
] = useDerived(enableAutoplay);
|
||||
const [
|
||||
enableSkipCreditsState,
|
||||
setEnableSkipCreditsState,
|
||||
resetEnableSkipCredits,
|
||||
enableSkipCreditsChanged,
|
||||
] = useDerived(enableSkipCredits);
|
||||
const [
|
||||
enableDiscoverState,
|
||||
setEnableDiscoverState,
|
||||
|
|
@ -142,6 +149,7 @@ export function useSettingsState(
|
|||
resetProfile();
|
||||
resetEnableThumbnails();
|
||||
resetEnableAutoplay();
|
||||
resetEnableSkipCredits();
|
||||
resetEnableDiscover();
|
||||
resetEnablePopDetails();
|
||||
resetSourceOrder();
|
||||
|
|
@ -160,6 +168,7 @@ export function useSettingsState(
|
|||
profileChanged ||
|
||||
enableThumbnailsChanged ||
|
||||
enableAutoplayChanged ||
|
||||
enableSkipCreditsChanged ||
|
||||
enableDiscoverChanged ||
|
||||
enablePopDetailsChanged ||
|
||||
sourceOrderChanged ||
|
||||
|
|
@ -219,6 +228,11 @@ export function useSettingsState(
|
|||
set: setEnableAutoplayState,
|
||||
changed: enableAutoplayChanged,
|
||||
},
|
||||
enableSkipCredits: {
|
||||
state: enableSkipCreditsState,
|
||||
set: setEnableSkipCreditsState,
|
||||
changed: enableSkipCreditsChanged,
|
||||
},
|
||||
enableDiscover: {
|
||||
state: enableDiscoverState,
|
||||
set: setEnableDiscoverState,
|
||||
|
|
|
|||
|
|
@ -140,6 +140,11 @@ export function SettingsPage() {
|
|||
const enableAutoplay = usePreferencesStore((s) => s.enableAutoplay);
|
||||
const setEnableAutoplay = usePreferencesStore((s) => s.setEnableAutoplay);
|
||||
|
||||
const enableSkipCredits = usePreferencesStore((s) => s.enableSkipCredits);
|
||||
const setEnableSkipCredits = usePreferencesStore(
|
||||
(s) => s.setEnableSkipCredits,
|
||||
);
|
||||
|
||||
const sourceOrder = usePreferencesStore((s) => s.sourceOrder);
|
||||
const setSourceOrder = usePreferencesStore((s) => s.setSourceOrder);
|
||||
|
||||
|
|
@ -178,7 +183,7 @@ export function SettingsPage() {
|
|||
proxySet,
|
||||
backendUrlSetting,
|
||||
febboxToken,
|
||||
account?.profile,
|
||||
account ? account.profile : undefined,
|
||||
enableThumbnails,
|
||||
enableAutoplay,
|
||||
enableDiscover,
|
||||
|
|
@ -186,6 +191,7 @@ export function SettingsPage() {
|
|||
sourceOrder,
|
||||
enableSourceOrder,
|
||||
proxyTmdb,
|
||||
enableSkipCredits,
|
||||
);
|
||||
|
||||
const availableSources = useMemo(() => {
|
||||
|
|
@ -256,6 +262,7 @@ export function SettingsPage() {
|
|||
|
||||
setEnableThumbnails(state.enableThumbnails.state);
|
||||
setEnableAutoplay(state.enableAutoplay.state);
|
||||
setEnableSkipCredits(state.enableSkipCredits.state);
|
||||
setEnableDiscover(state.enableDiscover.state);
|
||||
setEnablePopDetails(state.enablePopDetails.state);
|
||||
setSourceOrder(state.sourceOrder.state);
|
||||
|
|
@ -289,6 +296,7 @@ export function SettingsPage() {
|
|||
setFebboxToken,
|
||||
state,
|
||||
setEnableAutoplay,
|
||||
setEnableSkipCredits,
|
||||
setEnableDiscover,
|
||||
setEnablePopDetails,
|
||||
setSourceOrder,
|
||||
|
|
@ -344,6 +352,8 @@ export function SettingsPage() {
|
|||
setEnableThumbnails={state.enableThumbnails.set}
|
||||
enableAutoplay={state.enableAutoplay.state}
|
||||
setEnableAutoplay={state.enableAutoplay.set}
|
||||
enableSkipCredits={state.enableSkipCredits.state}
|
||||
setEnableSkipCredits={state.enableSkipCredits.set}
|
||||
sourceOrder={availableSources}
|
||||
setSourceOrder={state.sourceOrder.set}
|
||||
enableSourceOrder={state.enableSourceOrder.state}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ export function PreferencesPart(props: {
|
|||
setEnableThumbnails: (v: boolean) => void;
|
||||
enableAutoplay: boolean;
|
||||
setEnableAutoplay: (v: boolean) => void;
|
||||
enableSkipCredits: boolean;
|
||||
setEnableSkipCredits: (v: boolean) => void;
|
||||
sourceOrder: string[];
|
||||
setSourceOrder: (v: string[]) => void;
|
||||
enableSourceOrder: boolean;
|
||||
|
|
@ -122,6 +124,29 @@ export function PreferencesPart(props: {
|
|||
{t("settings.preferences.autoplayLabel")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Skip End Credits Preference */}
|
||||
{props.enableAutoplay && allowAutoplay && (
|
||||
<div className="pt-4">
|
||||
<p className="text-white font-bold mb-3">
|
||||
{t("settings.preferences.skipCredits")}
|
||||
</p>
|
||||
<p className="max-w-[25rem] font-medium">
|
||||
{t("settings.preferences.skipCreditsDescription")}
|
||||
</p>
|
||||
<div
|
||||
onClick={() =>
|
||||
props.setEnableSkipCredits(!props.enableSkipCredits)
|
||||
}
|
||||
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"
|
||||
>
|
||||
<Toggle enabled={props.enableSkipCredits} />
|
||||
<p className="flex-1 text-white font-bold">
|
||||
{t("settings.preferences.skipCreditsLabel")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { immer } from "zustand/middleware/immer";
|
|||
export interface PreferencesStore {
|
||||
enableThumbnails: boolean;
|
||||
enableAutoplay: boolean;
|
||||
enableSkipCredits: boolean;
|
||||
enableDiscover: boolean;
|
||||
enablePopDetails: boolean;
|
||||
sourceOrder: string[];
|
||||
|
|
@ -13,6 +14,7 @@ export interface PreferencesStore {
|
|||
|
||||
setEnableThumbnails(v: boolean): void;
|
||||
setEnableAutoplay(v: boolean): void;
|
||||
setEnableSkipCredits(v: boolean): void;
|
||||
setEnableDiscover(v: boolean): void;
|
||||
setEnablePopDetails(v: boolean): void;
|
||||
setSourceOrder(v: string[]): void;
|
||||
|
|
@ -25,6 +27,7 @@ export const usePreferencesStore = create(
|
|||
immer<PreferencesStore>((set) => ({
|
||||
enableThumbnails: false,
|
||||
enableAutoplay: true,
|
||||
enableSkipCredits: true,
|
||||
enableDiscover: true,
|
||||
enablePopDetails: false,
|
||||
sourceOrder: [],
|
||||
|
|
@ -40,6 +43,11 @@ export const usePreferencesStore = create(
|
|||
s.enableAutoplay = v;
|
||||
});
|
||||
},
|
||||
setEnableSkipCredits(v) {
|
||||
set((s) => {
|
||||
s.enableSkipCredits = v;
|
||||
});
|
||||
},
|
||||
setEnableDiscover(v) {
|
||||
set((s) => {
|
||||
s.enableDiscover = v;
|
||||
|
|
|
|||
Loading…
Reference in a new issue