diff --git a/src/api/ateliereLive/pipelines/multiviews/multiviews.ts b/src/api/ateliereLive/pipelines/multiviews/multiviews.ts index 5f24a86..ac76f6c 100644 --- a/src/api/ateliereLive/pipelines/multiviews/multiviews.ts +++ b/src/api/ateliereLive/pipelines/multiviews/multiviews.ts @@ -64,13 +64,12 @@ export async function createMultiviewForPipeline( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion productionSettings.pipelines[multiviewIndex].pipeline_id!; const sources = await getSourcesByIds( - sourceRefs.map((ref) => ref._id.toString()) + sourceRefs.map((ref) => (ref._id ? ref._id.toString() : '')) ); const sourceRefsWithLabels = sourceRefs.map((ref) => { + const refId = ref._id ? ref._id.toString() : ''; if (!ref.label) { - const source = sources.find( - (source) => source._id.toString() === ref._id.toString() - ); + const source = sources.find((source) => source._id.toString() === refId); ref.label = source?.name || ''; } return ref; diff --git a/src/api/manager/productions.ts b/src/api/manager/productions.ts index e364776..12bec1a 100644 --- a/src/api/manager/productions.ts +++ b/src/api/manager/productions.ts @@ -64,6 +64,8 @@ export async function putProduction( name: production.name, isActive: production.isActive, sources: sources, + html: [], + mediaplayers: [], production_settings: production.production_settings }; } diff --git a/src/api/manager/sources.ts b/src/api/manager/sources.ts index 853f43c..4e77f39 100644 --- a/src/api/manager/sources.ts +++ b/src/api/manager/sources.ts @@ -27,7 +27,6 @@ export async function getSourcesByIds( const db = await getDatabase().catch(() => { throw new Error("Can't connect to Database"); }); - const objectIds = _ids.map((id: string) => new ObjectId(id)); const sources = await db diff --git a/src/app/production/[id]/page.tsx b/src/app/production/[id]/page.tsx index a96d3cb..7355155 100644 --- a/src/app/production/[id]/page.tsx +++ b/src/app/production/[id]/page.tsx @@ -118,7 +118,6 @@ export default function ProductionConfiguration({ params }: PageProps) { if (!productionSetup) return; addSource(input, productionSetup).then((updatedSetup) => { - if (!updatedSetup) return; setSourceReferenceToAdd(updatedSetup.sources[0]); setProductionSetup(updatedSetup); @@ -720,7 +719,7 @@ export default function ProductionConfiguration({ params }: PageProps) { {productionSetup?.sources && sources.size > 0 && ( { updateProduction(productionSetup._id, updated); diff --git a/src/components/inventory/Inventory.tsx b/src/components/inventory/Inventory.tsx index c7c7670..dacb262 100644 --- a/src/components/inventory/Inventory.tsx +++ b/src/components/inventory/Inventory.tsx @@ -82,7 +82,7 @@ export default function Inventory() { diff --git a/src/components/sourceCard/SourceCard.tsx b/src/components/sourceCard/SourceCard.tsx index f2b9446..6eed4e2 100644 --- a/src/components/sourceCard/SourceCard.tsx +++ b/src/components/sourceCard/SourceCard.tsx @@ -8,16 +8,14 @@ import { useTranslate } from '../../i18n/useTranslate'; import { ISource } from '../../hooks/useDragableItems'; type SourceCardProps = { - source?: ISource; + source: ISource; label: string; - onSourceUpdate: (source: SourceReference) => void; + onSourceUpdate: (source: SourceReference, sourceItem: ISource) => void; onSourceRemoval: (source: SourceReference) => void; onSelectingText: (bool: boolean) => void; forwardedRef?: React.LegacyRef; style?: object; - src?: string; - sourceRef?: SourceReference; - type: Type; + src: string; }; export default function SourceCard({ @@ -28,13 +26,9 @@ export default function SourceCard({ onSelectingText, forwardedRef, src, - style, - sourceRef, - type + style }: SourceCardProps) { - const [sourceLabel, setSourceLabel] = useState( - sourceRef?.label || source?.name - ); + const [sourceLabel, setSourceLabel] = useState(label ? label : source.name); const t = useTranslate(); @@ -43,29 +37,21 @@ export default function SourceCard({ }; const saveText = () => { onSelectingText(false); - if (sourceLabel?.length === 0) { - if (source) { - setSourceLabel(source.name); - } else if (sourceRef) { - setSourceLabel(sourceRef.label); - } + // if (source.name === label) { + // return; + // } + if (sourceLabel.length === 0) { + setSourceLabel(source.name); } - - if (source) { - onSourceUpdate({ + onSourceUpdate( + { _id: source._id.toString(), - type: 'ingest_source', - label: sourceLabel || source.name, + label: sourceLabel, + type: source.ingest_type as Type, input_slot: source.input_slot - }); - } else if (sourceRef) { - onSourceUpdate({ - _id: sourceRef._id, - type: sourceRef.type, - label: sourceLabel || sourceRef.label, - input_slot: sourceRef.input_slot - }); - } + }, + source + ); }; const handleKeyDown = (event: KeyboardEvent) => { @@ -83,7 +69,7 @@ export default function SourceCard({
{ @@ -92,59 +78,26 @@ export default function SourceCard({ onBlur={saveText} />
- {source && source.src && ( - - )} - {!source && sourceRef && } - {(sourceRef || source) && ( -

- {t('source.input_slot', { - input_slot: - sourceRef?.input_slot?.toString() || - source?.input_slot?.toString() || - '' - })} -

- )} - - {source && ( -

- {t('source.ingest', { - ingest: source.ingest_name - })} -

- )} - {(source || sourceRef) && ( - - )} + +

+ {t('source.ingest', { + ingest: source.ingest_name + })} +

+ ); } diff --git a/src/components/sourceCards/SourceCards.tsx b/src/components/sourceCards/SourceCards.tsx index 9af6ec4..04101d0 100644 --- a/src/components/sourceCards/SourceCards.tsx +++ b/src/components/sourceCards/SourceCards.tsx @@ -1,80 +1,113 @@ 'use client'; import React, { useState } from 'react'; -import { SourceReference } from '../../interfaces/Source'; +import { SourceReference, Type } from '../../interfaces/Source'; import { Production } from '../../interfaces/production'; import DragItem from '../dragElement/DragItem'; import SourceCard from '../sourceCard/SourceCard'; +import { EmptySlotCard } from '../emptySlotCard/EmptySlotCard'; import { ISource, useDragableItems } from '../../hooks/useDragableItems'; export default function SourceCards({ productionSetup, - sourceRef, updateProduction, onSourceUpdate, onSourceRemoval }: { productionSetup: Production; - sourceRef?: SourceReference; updateProduction: (updated: Production) => void; - onSourceUpdate: (source: SourceReference) => void; + onSourceUpdate: (source: SourceReference, sourceItem: ISource) => void; onSourceRemoval: (source: SourceReference) => void; }) { const [items, moveItem, loading] = useDragableItems(productionSetup.sources); const [selectingText, setSelectingText] = useState(false); + const currentOrder: SourceReference[] = items.map((source) => { + return { + _id: source._id.toString(), + label: source.label, + type: source.ingest_type as Type, + input_slot: source.input_slot, + stream_uuids: source.stream_uuids + }; + }); - if (loading || !items) return null; - - // Filter SourceReference and ISource objects correctly - const sourceReferences = items.filter( - (item): item is SourceReference => item.type !== 'ingest_source' - ); - - const isISource = (source: SourceReference | ISource): source is ISource => { - // Use properties unique to ISource to check the type - return 'src' in source; - }; - - const gridItems = items.map((source) => { - const isSource = isISource(source); - - if (!source._id) return; + const gridItems: React.JSX.Element[] = []; + let tempItems = [...items]; + let firstEmptySlot = items.length + 1; - return ( - - {isSource ? ( - setSelectingText(isSelecting)} - type={'ingest_source'} - /> - ) : ( - setSelectingText(isSelecting)} - type={source.type} - /> - )} - - ); - }); + if (!items || items.length === 0) return null; + for (let i = 0; i < items[items.length - 1].input_slot; i++) { + if (!items.some((source) => source.input_slot === i + 1)) { + firstEmptySlot = i + 1; + break; + } + } + for (let i = 0; i < items[items.length - 1].input_slot; i++) { + // console.log(`On input slot: ${i + 1}`); + // console.log(`Checking sources:`); + // console.log(tempItems); + tempItems.every((source) => { + if (source.input_slot === i + 1) { + // console.log(`Found source on input slot: ${i + 1}`); + // console.log(`Removing source "${source.name}" from sources list`); + tempItems = tempItems.filter((i) => i._id !== source._id); + // console.log(`Adding source "${source.name}" to grid`); + if (!productionSetup.isActive) { + gridItems.push( + + + setSelectingText(isSelecting) + } + /> + + ); + } else { + gridItems.push( + + setSelectingText(isSelecting) + } + /> + ); + } + return false; + } else { + // console.log(`No source found on input slot: ${i + 1}`); + // console.log(`Adding empty slot to grid`); + if (productionSetup.isActive) { + gridItems.push( + + ); + } + return false; + } + }); + } return <>{gridItems}; } diff --git a/src/hooks/useDragableItems.ts b/src/hooks/useDragableItems.ts index 5cf6d5a..95601dc 100644 --- a/src/hooks/useDragableItems.ts +++ b/src/hooks/useDragableItems.ts @@ -9,84 +9,61 @@ export interface ISource extends SourceWithId { stream_uuids?: string[]; src: string; } - export function useDragableItems( sources: SourceReference[] -): [ - (SourceReference | ISource)[], - (originId: string, destinationId: string) => void, - boolean -] { +): [ISource[], (originId: string, destinationId: string) => void, boolean] { const [inventorySources, loading] = useSources(); - const [items, setItems] = useState<(SourceReference | ISource)[]>( + const [items, setItems] = useState( sources.flatMap((ref) => { - const source = inventorySources.get(ref._id); + const refId = ref._id ? ref._id : ''; + const source = inventorySources.get(refId); if (!source) return []; return { ...source, - _id: ref._id, label: ref.label, input_slot: ref.input_slot, stream_uuids: ref.stream_uuids, - src: getSourceThumbnail(source), - ingest_source_name: source.ingest_source_name, - ingest_name: source.ingest_name, - video_stream: source.video_stream, - audio_stream: source.audio_stream, - status: source.status, - type: source.type, - tags: source.tags, - name: source.name + src: getSourceThumbnail(source) }; }) ); useEffect(() => { - const updatedItems = sources.map((ref) => { - const source = inventorySources.get(ref._id); - if (!source) return { ...ref }; - return { - ...ref, - _id: ref._id, - status: source.status, - name: source.name, - type: source.type, - tags: source.tags, - ingest_name: source.ingest_name, - ingest_source_name: source.ingest_source_name, - ingest_type: source.ingest_type, - label: ref.label, - input_slot: ref.input_slot, - stream_uuids: ref.stream_uuids, - src: getSourceThumbnail(source), - video_stream: source.video_stream, - audio_stream: source.audio_stream, - lastConnected: source.lastConnected - }; - }); - setItems(updatedItems); + setItems( + sources.flatMap((ref) => { + const refId = ref._id ? ref._id : ''; + const source = inventorySources.get(refId); + if (!source) return []; + return { + ...source, + label: ref.label, + input_slot: ref.input_slot, + stream_uuids: ref.stream_uuids, + src: getSourceThumbnail(source) + }; + }) + ); }, [sources, inventorySources]); const moveItem = (originId: string, destinationId: string) => { - const originSource = items.find((item) => item._id.toString() === originId); + const originSource = items.find((i) => i._id.toString() === originId); const destinationSource = items.find( - (item) => item._id.toString() === destinationId + (i) => i._id.toString() === destinationId ); - if (!originSource || !destinationSource) return; - - const updatedItems = items - .map((item) => { - if (item._id === originSource._id) - return { ...item, input_slot: destinationSource.input_slot }; - if (item._id === destinationSource._id) - return { ...item, input_slot: originSource.input_slot }; - return item; - }) - .sort((a, b) => a.input_slot - b.input_slot); - + const originInputSlot = originSource.input_slot; + const destinationInputSlot = destinationSource.input_slot; + originSource.input_slot = destinationInputSlot; + destinationSource.input_slot = originInputSlot; + const updatedItems = [ + ...items.filter( + (i) => i._id !== originSource._id && i._id !== destinationSource._id + ), + originSource, + destinationSource + ].sort((a, b) => a.input_slot - b.input_slot); setItems(updatedItems); }; - return [allItems, moveItems, loading]; + return [items, moveItem, loading]; }