diff --git a/apps/dashboard/src/lib/features/course/components/lesson/video/library-video.svelte b/apps/dashboard/src/lib/features/course/components/lesson/video/library-video.svelte
index 253629c0..bc363688 100644
--- a/apps/dashboard/src/lib/features/course/components/lesson/video/library-video.svelte
+++ b/apps/dashboard/src/lib/features/course/components/lesson/video/library-video.svelte
@@ -3,6 +3,7 @@
import { Spinner } from '@cio/ui/base/spinner';
import { Empty } from '@cio/ui/custom/empty';
import { InputField } from '@cio/ui/custom/input-field';
+ import VideoIcon from '@lucide/svelte/icons/video';
import { lessonApi } from '$features/course/api';
import { mediaApi } from '$features/media/api';
import type { OrganizationAsset } from '$features/media/utils';
@@ -21,10 +22,21 @@
let search = $state('');
let isLoading = $state(false);
let addingAssetId = $state(null);
- // Local copy so adding a video swipes it out of this list without mutating the
- // shared mediaApi.assets store (which also backs the media manager page).
+ // Local copy so the fetch (which also backs the media manager page via the
+ // shared mediaApi.assets store) doesn't leak removals between surfaces.
let assets = $state([]);
+ // Asset ids already attached to this lesson, so the library hides them.
+ const addedAssetIds = $derived(
+ new Set(
+ (lessonApi.lesson?.videos ?? [])
+ .map((video) => (video as { assetId?: string }).assetId)
+ .filter((id): id is string => Boolean(id))
+ )
+ );
+
+ const visibleAssets = $derived(assets.filter((asset) => !addedAssetIds.has(asset.id)));
+
async function loadLibrary() {
isLoading = true;
await mediaApi.listAssets({
@@ -53,7 +65,6 @@
}
lessonApi.updateLessonState('videos', [lessonVideo], { append: true });
- assets = assets.filter((item) => item.id !== asset.id);
snackbar.success('snackbar.media_manager.added_to_lesson');
} finally {
addingAssetId = null;
@@ -65,7 +76,7 @@
});
-
+
- {:else if assets.length === 0}
+ {:else if visibleAssets.length === 0}