Convert playstatebutton and ratingbuttons to react
This commit is contained in:
parent
5fc549ef6b
commit
78b680f614
3 changed files with 206 additions and 0 deletions
74
src/elements/emby-playstatebutton/PlayedButton.tsx
Normal file
74
src/elements/emby-playstatebutton/PlayedButton.tsx
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client';
|
||||||
|
import React, { FC, useCallback } from 'react';
|
||||||
|
import CheckIcon from '@mui/icons-material/Check';
|
||||||
|
import { IconButton } from '@mui/material';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import globalize from 'scripts/globalize';
|
||||||
|
import { useTogglePlayedMutation } from 'hooks/useFetchItems';
|
||||||
|
|
||||||
|
interface PlayedButtonProps {
|
||||||
|
className?: string;
|
||||||
|
playedState : boolean | undefined;
|
||||||
|
itemId: string | null | undefined;
|
||||||
|
itemType: string | null | undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const PlayedButton: FC<PlayedButtonProps> = ({
|
||||||
|
className,
|
||||||
|
playedState = false,
|
||||||
|
itemId,
|
||||||
|
itemType
|
||||||
|
}) => {
|
||||||
|
const { mutateAsync: togglePlayedMutation } = useTogglePlayedMutation();
|
||||||
|
const [isPlayed, setIsPlayed] = React.useState<boolean | undefined>(
|
||||||
|
playedState ?? false
|
||||||
|
);
|
||||||
|
|
||||||
|
const getTitle = useCallback(() => {
|
||||||
|
let buttonTitle;
|
||||||
|
if (itemType !== BaseItemKind.AudioBook) {
|
||||||
|
buttonTitle = isPlayed ? globalize.translate('Watched') : globalize.translate('MarkPlayed');
|
||||||
|
} else {
|
||||||
|
buttonTitle = isPlayed ? globalize.translate('Played') : globalize.translate('MarkPlayed');
|
||||||
|
}
|
||||||
|
|
||||||
|
return buttonTitle;
|
||||||
|
}, [isPlayed, itemType]);
|
||||||
|
|
||||||
|
const onClick = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
if (!itemId) {
|
||||||
|
throw new Error('Item has no Id');
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await togglePlayedMutation({
|
||||||
|
itemId,
|
||||||
|
isPlayed
|
||||||
|
});
|
||||||
|
setIsPlayed(response?.Played);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}, [isPlayed, itemId, togglePlayedMutation]);
|
||||||
|
|
||||||
|
const btnClass = classNames(
|
||||||
|
className,
|
||||||
|
{ 'playstatebutton-played': isPlayed }
|
||||||
|
);
|
||||||
|
|
||||||
|
const iconClass = classNames(
|
||||||
|
{ 'playstatebutton-icon-played': isPlayed }
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<IconButton
|
||||||
|
title={getTitle()}
|
||||||
|
className={btnClass}
|
||||||
|
size='small'
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
<CheckIcon className={iconClass} />
|
||||||
|
</IconButton>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PlayedButton;
|
59
src/elements/emby-ratingbutton/FavoriteButton.tsx
Normal file
59
src/elements/emby-ratingbutton/FavoriteButton.tsx
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import React, { FC, useCallback } from 'react';
|
||||||
|
import FavoriteIcon from '@mui/icons-material/Favorite';
|
||||||
|
import { IconButton } from '@mui/material';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { useToggleFavoriteMutation } from 'hooks/useFetchItems';
|
||||||
|
import globalize from 'scripts/globalize';
|
||||||
|
|
||||||
|
interface FavoriteButtonProps {
|
||||||
|
className?: string;
|
||||||
|
favoriteState: boolean | undefined;
|
||||||
|
itemId: string | null | undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const FavoriteButton: FC<FavoriteButtonProps> = ({
|
||||||
|
className,
|
||||||
|
favoriteState,
|
||||||
|
itemId
|
||||||
|
}) => {
|
||||||
|
const { mutateAsync: toggleFavoriteMutation } = useToggleFavoriteMutation();
|
||||||
|
const [isFavorite, setIsFavorite] = React.useState<boolean | undefined>(favoriteState ?? false);
|
||||||
|
|
||||||
|
const onClick = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
if (!itemId) {
|
||||||
|
throw new Error('Item has no Id');
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await toggleFavoriteMutation({
|
||||||
|
itemId,
|
||||||
|
isFavorite
|
||||||
|
});
|
||||||
|
setIsFavorite(response?.IsFavorite);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}, [isFavorite, itemId, toggleFavoriteMutation]);
|
||||||
|
|
||||||
|
const btnClass = classNames(
|
||||||
|
className,
|
||||||
|
{ 'ratingbutton-withrating': isFavorite }
|
||||||
|
);
|
||||||
|
|
||||||
|
const iconClass = classNames(
|
||||||
|
{ 'ratingbutton-icon-withrating': isFavorite }
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IconButton
|
||||||
|
title={isFavorite ? globalize.translate('Favorite') : globalize.translate('AddToFavorites')}
|
||||||
|
className={btnClass}
|
||||||
|
size='small'
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
<FavoriteIcon className={iconClass} />
|
||||||
|
</IconButton>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FavoriteButton;
|
|
@ -15,6 +15,7 @@ import { getStudiosApi } from '@jellyfin/sdk/lib/utils/api/studios-api';
|
||||||
import { getTvShowsApi } from '@jellyfin/sdk/lib/utils/api/tv-shows-api';
|
import { getTvShowsApi } from '@jellyfin/sdk/lib/utils/api/tv-shows-api';
|
||||||
import { getUserLibraryApi } from '@jellyfin/sdk/lib/utils/api/user-library-api';
|
import { getUserLibraryApi } from '@jellyfin/sdk/lib/utils/api/user-library-api';
|
||||||
import { getPlaylistsApi } from '@jellyfin/sdk/lib/utils/api/playlists-api';
|
import { getPlaylistsApi } from '@jellyfin/sdk/lib/utils/api/playlists-api';
|
||||||
|
import { getPlaystateApi } from '@jellyfin/sdk/lib/utils/api/playstate-api';
|
||||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
import { useMutation, useQuery } from '@tanstack/react-query';
|
||||||
import datetime from 'scripts/datetime';
|
import datetime from 'scripts/datetime';
|
||||||
import globalize from 'scripts/globalize';
|
import globalize from 'scripts/globalize';
|
||||||
|
@ -621,3 +622,75 @@ export const useGetGroupsUpcomingEpisodes = (parentId: ParentId) => {
|
||||||
enabled: !!parentId
|
enabled: !!parentId
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface ToggleFavoriteMutationProp {
|
||||||
|
itemId: string;
|
||||||
|
isFavorite: boolean | undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchUpdateFavoriteStatus = async (
|
||||||
|
currentApi: JellyfinApiContext,
|
||||||
|
itemId: string,
|
||||||
|
isFavorite: boolean | undefined
|
||||||
|
) => {
|
||||||
|
const { api, user } = currentApi;
|
||||||
|
if (api && user?.Id) {
|
||||||
|
if (isFavorite) {
|
||||||
|
const response = await getUserLibraryApi(api).unmarkFavoriteItem({
|
||||||
|
userId: user?.Id,
|
||||||
|
itemId: itemId
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
} else {
|
||||||
|
const response = await getUserLibraryApi(api).markFavoriteItem({
|
||||||
|
userId: user?.Id,
|
||||||
|
itemId: itemId
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useToggleFavoriteMutation = () => {
|
||||||
|
const currentApi = useApi();
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: ({ itemId, isFavorite }: ToggleFavoriteMutationProp) =>
|
||||||
|
fetchUpdateFavoriteStatus(currentApi, itemId, isFavorite )
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
interface TogglePlayedMutationProp {
|
||||||
|
itemId: string;
|
||||||
|
isPlayed: boolean | undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchUpdatePlayedState = async (
|
||||||
|
currentApi: JellyfinApiContext,
|
||||||
|
itemId: string,
|
||||||
|
isPlayed: boolean | undefined
|
||||||
|
) => {
|
||||||
|
const { api, user } = currentApi;
|
||||||
|
if (api && user?.Id) {
|
||||||
|
if (isPlayed) {
|
||||||
|
const response = await getPlaystateApi(api).markUnplayedItem({
|
||||||
|
userId: user?.Id,
|
||||||
|
itemId: itemId
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
} else {
|
||||||
|
const response = await getPlaystateApi(api).markPlayedItem({
|
||||||
|
userId: user?.Id,
|
||||||
|
itemId: itemId
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useTogglePlayedMutation = () => {
|
||||||
|
const currentApi = useApi();
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: ({ itemId, isPlayed }: TogglePlayedMutationProp) =>
|
||||||
|
fetchUpdatePlayedState(currentApi, itemId, isPlayed )
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue