Merge pull request #7491 from PeachesMLG/fix_jellyfin_sdk_type_errors
This commit is contained in:
Generated
+4
-4
@@ -18,7 +18,7 @@
|
||||
"@fontsource/noto-sans-sc": "5.2.6",
|
||||
"@fontsource/noto-sans-tc": "5.2.6",
|
||||
"@jellyfin/libass-wasm": "4.2.3",
|
||||
"@jellyfin/sdk": "0.0.0-unstable.202512091852",
|
||||
"@jellyfin/sdk": "0.0.0-unstable.202601090504",
|
||||
"@jellyfin/ux-web": "1.0.0",
|
||||
"@mui/icons-material": "6.4.12",
|
||||
"@mui/material": "6.4.12",
|
||||
@@ -4130,9 +4130,9 @@
|
||||
"license": "LGPL-2.1-or-later AND (FTL OR GPL-2.0-or-later) AND MIT AND MIT-Modern-Variant AND ISC AND NTP AND Zlib AND BSL-1.0"
|
||||
},
|
||||
"node_modules/@jellyfin/sdk": {
|
||||
"version": "0.0.0-unstable.202512091852",
|
||||
"resolved": "https://registry.npmjs.org/@jellyfin/sdk/-/sdk-0.0.0-unstable.202512091852.tgz",
|
||||
"integrity": "sha512-N+QEsrKk4KculkV6KMBb7XpzTLWcXEzqTHbS+b4rov0VYVwR6DIsJkmUzB3hM2YZsrLIHEFKhFRy/r4itkFeHw==",
|
||||
"version": "0.0.0-unstable.202601090504",
|
||||
"resolved": "https://registry.npmjs.org/@jellyfin/sdk/-/sdk-0.0.0-unstable.202601090504.tgz",
|
||||
"integrity": "sha512-ZTtSUMYjyfin54dXGZ5i9fZxLkKbMPxxsFxnmLoSVrjNrvL8JMV3Thb0fevCgd5gpkJpLVJXpx5YjwNbrze6DQ==",
|
||||
"license": "MPL-2.0",
|
||||
"peerDependencies": {
|
||||
"axios": "^1.12.0"
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@
|
||||
"@fontsource/noto-sans-sc": "5.2.6",
|
||||
"@fontsource/noto-sans-tc": "5.2.6",
|
||||
"@jellyfin/libass-wasm": "4.2.3",
|
||||
"@jellyfin/sdk": "0.0.0-unstable.202512091852",
|
||||
"@jellyfin/sdk": "0.0.0-unstable.202601090504",
|
||||
"@jellyfin/ux-web": "1.0.0",
|
||||
"@mui/icons-material": "6.4.12",
|
||||
"@mui/material": "6.4.12",
|
||||
|
||||
@@ -1,35 +1,36 @@
|
||||
import type { FolderStorageDto } from '@jellyfin/sdk/lib/generated-client/models/folder-storage-dto';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { calculateUsedPercentage, calculateTotal } from './space';
|
||||
|
||||
describe('calculateTotal()', () => {
|
||||
it('should return the total', () => {
|
||||
expect(calculateTotal({ FreeSpace: 1, UsedSpace: 2 })).toBe(3);
|
||||
expect(calculateTotal({ FreeSpace: 1, UsedSpace: 2 } as FolderStorageDto)).toBe(3);
|
||||
});
|
||||
|
||||
it('should return -1 for invalid used space values', () => {
|
||||
expect(calculateTotal({ FreeSpace: 1 })).toBe(-1);
|
||||
expect(calculateTotal({ FreeSpace: 1, UsedSpace: -1 })).toBe(-1);
|
||||
expect(calculateTotal({ FreeSpace: 1 } as FolderStorageDto)).toBe(-1);
|
||||
expect(calculateTotal({ FreeSpace: 1, UsedSpace: -1 } as FolderStorageDto)).toBe(-1);
|
||||
});
|
||||
|
||||
it('should treat invalid free space values as 0', () => {
|
||||
expect(calculateTotal({ UsedSpace: 1 })).toBe(1);
|
||||
expect(calculateTotal({ FreeSpace: -1, UsedSpace: 1 })).toBe(1);
|
||||
expect(calculateTotal({ UsedSpace: 1 } as FolderStorageDto)).toBe(1);
|
||||
expect(calculateTotal({ FreeSpace: -1, UsedSpace: 1 } as FolderStorageDto)).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('calculateUsedPercentage', () => {
|
||||
it('should return the percentage used', () => {
|
||||
expect(calculateUsedPercentage({ FreeSpace: 1, UsedSpace: 3 })).toBe(75);
|
||||
expect(calculateUsedPercentage({ FreeSpace: 1, UsedSpace: 3 } as FolderStorageDto)).toBe(75);
|
||||
});
|
||||
|
||||
it('should return 0 for invalid used space values', () => {
|
||||
expect(calculateUsedPercentage({ FreeSpace: 1 })).toBe(0);
|
||||
expect(calculateUsedPercentage({ FreeSpace: 1, UsedSpace: -1 })).toBe(0);
|
||||
expect(calculateUsedPercentage({ FreeSpace: 1 } as FolderStorageDto)).toBe(0);
|
||||
expect(calculateUsedPercentage({ FreeSpace: 1, UsedSpace: -1 } as FolderStorageDto)).toBe(0);
|
||||
});
|
||||
|
||||
it('should return 100 for invalid free space values', () => {
|
||||
expect(calculateUsedPercentage({ UsedSpace: 1 })).toBe(100);
|
||||
expect(calculateUsedPercentage({ FreeSpace: -1, UsedSpace: 1 })).toBe(100);
|
||||
expect(calculateUsedPercentage({ UsedSpace: 1 } as FolderStorageDto)).toBe(100);
|
||||
expect(calculateUsedPercentage({ FreeSpace: -1, UsedSpace: 1 } as FolderStorageDto)).toBe(100);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@ import type { NullableString } from 'types/base/common/shared/types';
|
||||
import type { ItemDto } from 'types/base/models/item-dto';
|
||||
|
||||
interface PlayAllFromHereOptions {
|
||||
item: ItemDto;
|
||||
item?: ItemDto;
|
||||
items: ItemDto[];
|
||||
serverId: NullableString;
|
||||
queue?: boolean;
|
||||
@@ -166,7 +166,7 @@ const MoreCommandsButton: FC<MoreCommandsButtonProps> = ({
|
||||
serverId: item?.ServerId
|
||||
});
|
||||
playAllFromHere({
|
||||
item: item || {},
|
||||
item: item,
|
||||
items: items || [],
|
||||
serverId: item?.ServerId
|
||||
}).catch(err => {
|
||||
@@ -174,7 +174,7 @@ const MoreCommandsButton: FC<MoreCommandsButtonProps> = ({
|
||||
});
|
||||
} else if (result.command === 'queueallfromhere') {
|
||||
playAllFromHere({
|
||||
item: item || {},
|
||||
item: item,
|
||||
items: items || [],
|
||||
serverId: item?.ServerId,
|
||||
queue: true
|
||||
|
||||
@@ -47,7 +47,7 @@ export function getImageUrl(item: ItemDto, options: ImageOptions = {}) {
|
||||
const itemId = item.PrimaryImageItemId || item.Id;
|
||||
|
||||
if (itemId && item.ImageTags?.[options.type]) {
|
||||
options.tag = item.ImageTags[options.type];
|
||||
options.tag = item.ImageTags[options.type] ?? undefined;
|
||||
return ServerConnections.getApiClient(item.ServerId).getScaledImageUrl(itemId, options);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { getItemTextLines } from './itemText';
|
||||
|
||||
describe('getItemTextLines', () => {
|
||||
it('Should return undefined if item is invalid', () => {
|
||||
let lines = getItemTextLines({});
|
||||
let lines = getItemTextLines({} as ItemDto);
|
||||
expect(lines).toBeUndefined();
|
||||
lines = getItemTextLines(null);
|
||||
expect(lines).toBeUndefined();
|
||||
@@ -16,9 +16,9 @@ describe('getItemTextLines', () => {
|
||||
});
|
||||
|
||||
it('Should return the name and index number', () => {
|
||||
const item: ItemDto = {
|
||||
const item = {
|
||||
Name: 'Item Name'
|
||||
};
|
||||
} as ItemDto;
|
||||
let lines = getItemTextLines(item);
|
||||
expect(lines).toBeDefined();
|
||||
expect(lines).toHaveLength(1);
|
||||
@@ -39,13 +39,13 @@ describe('getItemTextLines', () => {
|
||||
});
|
||||
|
||||
it('Should add artist names', () => {
|
||||
let item: ItemDto = {
|
||||
let item = {
|
||||
Name: 'Item Name',
|
||||
ArtistItems: [
|
||||
{ Name: 'Artist 1' },
|
||||
{ Name: 'Artist 2' }
|
||||
]
|
||||
};
|
||||
} as ItemDto;
|
||||
let lines = getItemTextLines(item);
|
||||
expect(lines).toBeDefined();
|
||||
expect(lines).toHaveLength(2);
|
||||
@@ -58,7 +58,7 @@ describe('getItemTextLines', () => {
|
||||
'Artist 1',
|
||||
'Artist 2'
|
||||
]
|
||||
};
|
||||
} as ItemDto;
|
||||
lines = getItemTextLines(item);
|
||||
expect(lines).toBeDefined();
|
||||
expect(lines).toHaveLength(2);
|
||||
@@ -67,10 +67,10 @@ describe('getItemTextLines', () => {
|
||||
});
|
||||
|
||||
it('Should add album or series name', () => {
|
||||
let item: ItemDto = {
|
||||
let item = {
|
||||
Name: 'Item Name',
|
||||
SeriesName: 'Series'
|
||||
};
|
||||
} as ItemDto;
|
||||
let lines = getItemTextLines(item);
|
||||
expect(lines).toBeDefined();
|
||||
expect(lines).toHaveLength(2);
|
||||
@@ -80,7 +80,7 @@ describe('getItemTextLines', () => {
|
||||
item = {
|
||||
Name: 'Item Name',
|
||||
Album: 'Album'
|
||||
};
|
||||
} as ItemDto;
|
||||
lines = getItemTextLines(item);
|
||||
expect(lines).toBeDefined();
|
||||
expect(lines).toHaveLength(2);
|
||||
@@ -92,7 +92,7 @@ describe('getItemTextLines', () => {
|
||||
const item = {
|
||||
Name: 'Item Name',
|
||||
ProductionYear: 2025
|
||||
};
|
||||
} as ItemDto;
|
||||
const lines = getItemTextLines(item);
|
||||
expect(lines).toBeDefined();
|
||||
expect(lines).toHaveLength(2);
|
||||
|
||||
@@ -7,11 +7,11 @@ import type { CardOptions } from 'types/cardOptions';
|
||||
import type { ItemDto } from 'types/base/models/item-dto';
|
||||
|
||||
interface CardProps {
|
||||
item?: ItemDto;
|
||||
item: ItemDto;
|
||||
cardOptions: CardOptions;
|
||||
}
|
||||
|
||||
const Card: FC<CardProps> = ({ item = {}, cardOptions }) => {
|
||||
const Card: FC<CardProps> = ({ item, cardOptions }) => {
|
||||
const { getCardWrapperProps, getCardBoxProps } = useCard({ item, cardOptions } );
|
||||
const cardWrapperProps = getCardWrapperProps();
|
||||
const cardBoxProps = getCardBoxProps();
|
||||
|
||||
@@ -217,6 +217,7 @@ function getParentTitle(
|
||||
.map(artist => {
|
||||
const artistItem: ItemDto = {
|
||||
...artist,
|
||||
Key: artist.Id ?? '',
|
||||
Type: BaseItemKind.MusicArtist,
|
||||
IsFolder: true
|
||||
};
|
||||
@@ -511,6 +512,7 @@ function getChannelName(item: ItemDto) {
|
||||
if (item.ChannelId) {
|
||||
return getTextActionButton(
|
||||
{
|
||||
Key: item.ChannelId,
|
||||
Id: item.ChannelId,
|
||||
ServerId: item.ServerId,
|
||||
Name: item.ChannelName,
|
||||
@@ -598,6 +600,7 @@ function getMediaTitle(cardOptions: CardOptions, item: ItemDto): TextLine {
|
||||
});
|
||||
|
||||
return getTextActionButton({
|
||||
Key: item.Id ?? '',
|
||||
Id: item.Id,
|
||||
ServerId: item.ServerId,
|
||||
Name: name,
|
||||
@@ -620,6 +623,7 @@ function getParentTitleOrTitle(
|
||||
) {
|
||||
if (item.SeriesId) {
|
||||
return getTextActionButton({
|
||||
Key: item.SeriesId,
|
||||
Id: item.SeriesId,
|
||||
ServerId: item.ServerId,
|
||||
Name: item.SeriesName,
|
||||
|
||||
@@ -39,7 +39,7 @@ function useCard({ item, cardOptions }: UseCardProps) {
|
||||
shape
|
||||
});
|
||||
const imgUrl = imgInfo.imgUrl;
|
||||
const blurhash = imgInfo.blurhash;
|
||||
const blurhash = imgInfo.blurhash ?? undefined;
|
||||
const forceName = imgInfo.forceName;
|
||||
const coveredImage = cardOptions.coverImage ?? imgInfo.coverImage;
|
||||
const overlayText = cardOptions.overlayText;
|
||||
|
||||
@@ -111,7 +111,7 @@ function shouldShowPreferBanner(
|
||||
}
|
||||
|
||||
function shouldShowPreferDisc(
|
||||
imageTagsDisc: string | undefined,
|
||||
imageTagsDisc: string | null | undefined,
|
||||
cardOptions: CardOptions
|
||||
): boolean {
|
||||
return cardOptions.preferDisc === true && Boolean(imageTagsDisc);
|
||||
|
||||
@@ -154,8 +154,8 @@ const useIndicator = (item: ItemDto) => {
|
||||
|
||||
const getPlayedIndicator = () => {
|
||||
if (enablePlayedIndicator(item)) {
|
||||
const userData = item.UserData || {};
|
||||
if (userData.UnplayedItemCount) {
|
||||
const userData = item.UserData;
|
||||
if (userData?.UnplayedItemCount) {
|
||||
return (
|
||||
<Box className='countIndicator indicator unplayedItemCount'>
|
||||
{formatCountIndicator(userData.UnplayedItemCount)}
|
||||
@@ -164,9 +164,9 @@ const useIndicator = (item: ItemDto) => {
|
||||
}
|
||||
|
||||
if (
|
||||
(userData.PlayedPercentage
|
||||
&& userData.PlayedPercentage >= 100)
|
||||
|| userData.Played
|
||||
(userData?.PlayedPercentage
|
||||
&& userData?.PlayedPercentage >= 100)
|
||||
|| userData?.Played
|
||||
) {
|
||||
return (
|
||||
<Box className='playedIndicator indicator'>
|
||||
|
||||
@@ -28,7 +28,7 @@ interface ListImageContainerProps {
|
||||
}
|
||||
|
||||
const ListImageContainer: FC<ListImageContainerProps> = ({
|
||||
item = {},
|
||||
item,
|
||||
listOptions,
|
||||
action,
|
||||
isLargeStyle,
|
||||
@@ -73,7 +73,7 @@ const ListImageContainer: FC<ListImageContainerProps> = ({
|
||||
className={imageClass}
|
||||
>
|
||||
|
||||
<Media item={item} imgUrl={imgUrl} blurhash={blurhash} defaultCardImageIcon={defaultCardImageIcon} />
|
||||
<Media item={item} imgUrl={imgUrl} blurhash={blurhash ?? undefined} defaultCardImageIcon={defaultCardImageIcon} />
|
||||
|
||||
{disableIndicators !== true && mediaSourceIndicator}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ interface ListItemBodyProps {
|
||||
}
|
||||
|
||||
const ListItemBody: FC<ListItemBodyProps> = ({
|
||||
item = {},
|
||||
item,
|
||||
listOptions = {},
|
||||
action,
|
||||
isLargeStyle,
|
||||
|
||||
@@ -95,7 +95,7 @@ function createPlaylist(dlg: DialogElement) {
|
||||
return getPlaylistsApi(api)
|
||||
.createPlaylist({
|
||||
createPlaylistDto: {
|
||||
Name: name,
|
||||
Name: name ?? '',
|
||||
IsPublic: dlg.querySelector<HTMLInputElement>('#chkPlaylistPublic')?.checked,
|
||||
Ids: itemIds?.split(','),
|
||||
UserId: apiClient.getCurrentUserId()
|
||||
|
||||
Reference in New Issue
Block a user