diff --git a/types/src/plex/index.ts b/types/src/plex/index.ts
index 27e9105b4..ed8dfb2ef 100644
--- a/types/src/plex/index.ts
+++ b/types/src/plex/index.ts
@@ -21,6 +21,7 @@ export const PlexMediaTypeSchema = z.union([
z.literal('movie'),
z.literal('show'),
z.literal('artist'),
+ z.literal('photo'),
]);
export const PlexLibrarySectionSchema = z.object({
diff --git a/web/src/components/channel_config/JellyfinProgrammingSelector.tsx b/web/src/components/channel_config/JellyfinProgrammingSelector.tsx
index 637a8e1bd..bb79234b7 100644
--- a/web/src/components/channel_config/JellyfinProgrammingSelector.tsx
+++ b/web/src/components/channel_config/JellyfinProgrammingSelector.tsx
@@ -195,7 +195,7 @@ export function JellyfinProgrammingSelector() {
getItemKey={useCallback((item: JellyfinItem) => item.Id, [])}
renderGridItem={renderGridItem}
renderListItem={(item, index) => (
-
+
)}
// renderFinalRow={renderFinalRowInlineModal}
infiniteQuery={jellyfinItemsQuery}
diff --git a/web/src/hooks/plex/usePlex.ts b/web/src/hooks/plex/usePlex.ts
index b46e0a474..47d265b8d 100644
--- a/web/src/hooks/plex/usePlex.ts
+++ b/web/src/hooks/plex/usePlex.ts
@@ -6,6 +6,7 @@ import { useApiQuery } from '../useApiQuery.ts';
import { useTunarrApi } from '../useTunarrApi.ts';
import { plexQueryOptions } from './plexHookUtil.ts';
import { MediaSourceId } from '@tunarr/types/schemas';
+import { identity, reject } from 'lodash-es';
export type PlexPathMappings = [
['/library/sections', PlexLibrarySections],
@@ -23,16 +24,20 @@ type PlexQueryArgs = {
export const usePlex = <
T extends ExtractTypeKeys,
- OutType = FindChild,
+ ResponseType = FindChild,
+ OutType = ResponseType,
>(
serverId: MediaSourceId,
path: string,
enabled: boolean = true,
+ select: (response: ResponseType) => OutType = identity,
) => {
return useApiQuery({
queryKey: ['plex', serverId, path],
- queryFn: (apiClient) => fetchPlexPath(apiClient, serverId, path)(),
+ queryFn: (apiClient) =>
+ fetchPlexPath(apiClient, serverId, path)(),
enabled,
+ select,
});
};
export const usePlexTyped = (
@@ -74,4 +79,13 @@ export const usePlexTyped2 = (
export const usePlexLibraries = (
serverId: MediaSourceId,
enabled: boolean = true,
-) => usePlex<'/library/sections'>(serverId, '/library/sections', enabled);
+) =>
+ usePlex<'/library/sections'>(
+ serverId,
+ '/library/sections',
+ enabled,
+ (response) => ({
+ ...response,
+ Directory: reject(response.Directory, { type: 'photo' }),
+ }),
+ );
diff --git a/web/src/store/programmingSelector/actions.ts b/web/src/store/programmingSelector/actions.ts
index 748dcf7d5..d62bf2c56 100644
--- a/web/src/store/programmingSelector/actions.ts
+++ b/web/src/store/programmingSelector/actions.ts
@@ -13,7 +13,7 @@ import {
isPlexDirectory,
} from '@tunarr/types/plex';
import { MediaSourceId } from '@tunarr/types/schemas';
-import { has, isArray, map, reject, some, uniq } from 'lodash-es';
+import { has, isArray, isUndefined, map, reject, some, uniq } from 'lodash-es';
import useStore from '..';
import {
buildPlexFilterKey,
@@ -27,6 +27,7 @@ export const setProgrammingListingServer = (
) =>
useStore.setState((state) => {
state.currentServer = server;
+ state.currentLibrary = undefined;
});
export const setProgrammingListLibrary = (library: SelectedLibrary) =>
@@ -34,6 +35,11 @@ export const setProgrammingListLibrary = (library: SelectedLibrary) =>
state.currentLibrary = library;
});
+export const clearProgrammingListLibrary = () =>
+ useStore.setState((state) => {
+ state.currentLibrary = undefined;
+ });
+
function uniqueId(item: PlexLibrarySection | PlexMedia): string {
if (isPlexDirectory(item)) {
return item.uuid;
@@ -63,6 +69,9 @@ export const addKnownMediaForServer = (
switch (media.type) {
case 'plex': {
for (const item of media.items) {
+ if (isUndefined(item)) {
+ continue;
+ }
byGuid[uniqueId(item)] = { type: media.type, item };
}
break;