mirror of
https://github.com/p-stream/p-stream.git
synced 2026-03-11 17:55:33 +00:00
create getProgressPercentage() function that handles greater than 100% values
Replace all old uses like (itemToDisplay.progress.watched / itemToDisplay.progress.duration) * 100
This commit is contained in:
parent
ba59405612
commit
84165370da
8 changed files with 63 additions and 28 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { useMemo } from "react";
|
||||
|
||||
import { useProgressStore } from "@/stores/progress";
|
||||
import { getProgressPercentage, useProgressStore } from "@/stores/progress";
|
||||
import {
|
||||
ShowProgressResult,
|
||||
shouldShowProgress,
|
||||
|
|
@ -36,7 +36,10 @@ export function WatchedMediaCard(props: WatchedMediaCardProps) {
|
|||
[item],
|
||||
);
|
||||
const percentage = itemToDisplay?.show
|
||||
? (itemToDisplay.progress.watched / itemToDisplay.progress.duration) * 100
|
||||
? getProgressPercentage(
|
||||
itemToDisplay.progress.watched,
|
||||
itemToDisplay.progress.duration,
|
||||
)
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { Icon, Icons } from "@/components/Icon";
|
|||
import { Modal, ModalCard, useModal } from "@/components/overlays/Modal";
|
||||
import { hasAired } from "@/components/player/utils/aired";
|
||||
import { useBookmarkStore } from "@/stores/bookmarks";
|
||||
import { useProgressStore } from "@/stores/progress";
|
||||
import { getProgressPercentage, useProgressStore } from "@/stores/progress";
|
||||
|
||||
import { EpisodeCarouselProps } from "../../types";
|
||||
|
||||
|
|
@ -170,9 +170,10 @@ export function EpisodeCarousel({
|
|||
const episodeProgress =
|
||||
progress[mediaId.toString()]?.episodes?.[episodeId];
|
||||
const percentage = episodeProgress
|
||||
? (episodeProgress.progress.watched /
|
||||
episodeProgress.progress.duration) *
|
||||
100
|
||||
? getProgressPercentage(
|
||||
episodeProgress.progress.watched,
|
||||
episodeProgress.progress.duration,
|
||||
)
|
||||
: 0;
|
||||
|
||||
// If watched (>90%), reset to 0%, otherwise set to 100%
|
||||
|
|
@ -282,9 +283,10 @@ export function EpisodeCarousel({
|
|||
const episodeProgress =
|
||||
progress[mediaId?.toString() ?? ""]?.episodes?.[episode.id];
|
||||
const percentage = episodeProgress
|
||||
? (episodeProgress.progress.watched /
|
||||
episodeProgress.progress.duration) *
|
||||
100
|
||||
? getProgressPercentage(
|
||||
episodeProgress.progress.watched,
|
||||
episodeProgress.progress.duration,
|
||||
)
|
||||
: 0;
|
||||
const isAired = hasAired(episode.air_date);
|
||||
const isWatched = percentage > 90;
|
||||
|
|
@ -299,9 +301,10 @@ export function EpisodeCarousel({
|
|||
const episodeProgress =
|
||||
progress[mediaId?.toString() ?? ""]?.episodes?.[episode.id];
|
||||
const percentage = episodeProgress
|
||||
? (episodeProgress.progress.watched /
|
||||
episodeProgress.progress.duration) *
|
||||
100
|
||||
? getProgressPercentage(
|
||||
episodeProgress.progress.watched,
|
||||
episodeProgress.progress.duration,
|
||||
)
|
||||
: 0;
|
||||
const isAired = hasAired(episode.air_date);
|
||||
const isWatched = percentage > 90;
|
||||
|
|
@ -378,9 +381,10 @@ export function EpisodeCarousel({
|
|||
const episodeProgress =
|
||||
progress[mediaId?.toString() ?? ""]?.episodes?.[episode.id];
|
||||
const percentage = episodeProgress
|
||||
? (episodeProgress.progress.watched /
|
||||
episodeProgress.progress.duration) *
|
||||
100
|
||||
? getProgressPercentage(
|
||||
episodeProgress.progress.watched,
|
||||
episodeProgress.progress.duration,
|
||||
)
|
||||
: 0;
|
||||
const isAired = hasAired(episode.air_date);
|
||||
const isWatched = percentage > 90;
|
||||
|
|
@ -565,9 +569,10 @@ export function EpisodeCarousel({
|
|||
const episodeProgress =
|
||||
progress[mediaId?.toString() ?? ""]?.episodes?.[episode.id];
|
||||
const percentage = episodeProgress
|
||||
? (episodeProgress.progress.watched /
|
||||
episodeProgress.progress.duration) *
|
||||
100
|
||||
? getProgressPercentage(
|
||||
episodeProgress.progress.watched,
|
||||
episodeProgress.progress.duration,
|
||||
)
|
||||
: 0;
|
||||
const isAired = hasAired(episode.air_date);
|
||||
const isExpanded = expandedEpisodes[episode.id];
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next";
|
|||
import { Button } from "@/components/buttons/Button";
|
||||
import { Icon, Icons } from "@/components/Icon";
|
||||
import { useWatchPartySync } from "@/hooks/useWatchPartySync";
|
||||
import { getProgressPercentage } from "@/stores/progress";
|
||||
import { useWatchPartyStore } from "@/stores/watchParty";
|
||||
|
||||
export function WatchPartyStatus() {
|
||||
|
|
@ -110,7 +111,7 @@ export function WatchPartyStatus() {
|
|||
</span>
|
||||
<span className="text-type-secondary">
|
||||
{user.player.duration > 0
|
||||
? `${Math.floor((user.player.time / user.player.duration) * 100)}%`
|
||||
? `${Math.floor(getProgressPercentage(user.player.time, user.player.duration))}%`
|
||||
: `${Math.floor(user.player.time)}s`}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { useBackendUrl } from "@/hooks/auth/useBackendUrl";
|
|||
import { useOverlayRouter } from "@/hooks/useOverlayRouter";
|
||||
import { useWatchPartySync } from "@/hooks/useWatchPartySync";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
import { getProgressPercentage } from "@/stores/progress";
|
||||
import { useWatchPartyStore } from "@/stores/watchParty";
|
||||
|
||||
import { useDownloadLink } from "./Downloads";
|
||||
|
|
@ -326,7 +327,7 @@ export function WatchPartyView({ id }: { id: string }) {
|
|||
</span>
|
||||
<span className="text-type-secondary">
|
||||
{user.player.duration > 0
|
||||
? `${Math.floor((user.player.time / user.player.duration) * 100)}%`
|
||||
? `${Math.floor(getProgressPercentage(user.player.time, user.player.duration))}%`
|
||||
: `${Math.floor(user.player.time)}s`}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import { SourceSelectPart } from "@/pages/parts/player/SourceSelectPart";
|
|||
import { useLastNonPlayerLink } from "@/stores/history";
|
||||
import { PlayerMeta, playerStatus } from "@/stores/player/slices/source";
|
||||
import { usePreferencesStore } from "@/stores/preferences";
|
||||
import { useProgressStore } from "@/stores/progress";
|
||||
import { getProgressPercentage, useProgressStore } from "@/stores/progress";
|
||||
import { needsOnboarding } from "@/utils/onboarding";
|
||||
import { parseTimestamp } from "@/utils/timestamp";
|
||||
|
||||
|
|
@ -107,16 +107,20 @@ export function RealPlayerView() {
|
|||
|
||||
if (meta.type === "movie") {
|
||||
if (!item.progress) return false;
|
||||
const percentage =
|
||||
(item.progress.watched / item.progress.duration) * 100;
|
||||
const percentage = getProgressPercentage(
|
||||
item.progress.watched,
|
||||
item.progress.duration,
|
||||
);
|
||||
return percentage > 80;
|
||||
}
|
||||
|
||||
if (meta.type === "show" && meta.episode?.tmdbId) {
|
||||
const episode = item.episodes?.[meta.episode.tmdbId];
|
||||
if (!episode) return false;
|
||||
const percentage =
|
||||
(episode.progress.watched / episode.progress.duration) * 100;
|
||||
const percentage = getProgressPercentage(
|
||||
episode.progress.watched,
|
||||
episode.progress.duration,
|
||||
);
|
||||
return percentage > 80;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { Title } from "@/components/text/Title";
|
|||
import { ErrorContainer, ErrorLayout } from "@/pages/layouts/ErrorLayout";
|
||||
import { PlayerMeta } from "@/stores/player/slices/source";
|
||||
import { usePlayerStore } from "@/stores/player/store";
|
||||
import { useProgressStore } from "@/stores/progress";
|
||||
import { getProgressPercentage, useProgressStore } from "@/stores/progress";
|
||||
|
||||
export interface ResumePartProps {
|
||||
onResume: () => void;
|
||||
|
|
@ -30,13 +30,19 @@ export function ResumePart(props: ResumePartProps) {
|
|||
|
||||
if (meta.type === "movie") {
|
||||
if (!item.progress) return 0;
|
||||
return (item.progress.watched / item.progress.duration) * 100;
|
||||
return getProgressPercentage(
|
||||
item.progress.watched,
|
||||
item.progress.duration,
|
||||
);
|
||||
}
|
||||
|
||||
if (meta.type === "show" && meta.episode?.tmdbId) {
|
||||
const episode = item.episodes?.[meta.episode.tmdbId];
|
||||
if (!episode) return 0;
|
||||
return (episode.progress.watched / episode.progress.duration) * 100;
|
||||
return getProgressPercentage(
|
||||
episode.progress.watched,
|
||||
episode.progress.duration,
|
||||
);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import { immer } from "zustand/middleware/immer";
|
|||
|
||||
import { PlayerMeta } from "@/stores/player/slices/source";
|
||||
|
||||
export { getProgressPercentage } from "./utils";
|
||||
|
||||
export interface ProgressItem {
|
||||
watched: number;
|
||||
duration: number;
|
||||
|
|
|
|||
|
|
@ -55,6 +55,19 @@ function isFirstEpisodeOfShow(
|
|||
return season.number === 1 && episode.number === 1;
|
||||
}
|
||||
|
||||
export function getProgressPercentage(
|
||||
watched: number,
|
||||
duration: number,
|
||||
): number {
|
||||
// Handle edge cases to prevent infinity or invalid percentages
|
||||
if (!duration || duration <= 0) return 0;
|
||||
if (!watched || watched < 0) return 0;
|
||||
|
||||
// Cap percentage at 100% to prevent >100% values
|
||||
const percentage = Math.min((watched / duration) * 100, 100);
|
||||
return percentage;
|
||||
}
|
||||
|
||||
export function shouldShowProgress(
|
||||
item: ProgressMediaItem,
|
||||
): ShowProgressResult {
|
||||
|
|
|
|||
Loading…
Reference in a new issue