From 2979a7eefdb818aebccb5562784646edd5452481 Mon Sep 17 00:00:00 2001 From: sleepyfran Date: Tue, 27 Aug 2024 11:24:47 +0200 Subject: [PATCH] Filter-out active providers in selector --- .../add-provider/src/AddProvider.tsx | 32 ++++++++++++++----- .../services/active-media-provider-cache.ts | 11 +++++++ .../workflows/add-provider.workflow.ts | 1 + .../active-media-provider-cache/index.ts | 4 +++ .../src/add-provider.machine.ts | 4 +++ 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/packages/components/add-provider/src/AddProvider.tsx b/packages/components/add-provider/src/AddProvider.tsx index f4ade4f..b46fb69 100644 --- a/packages/components/add-provider/src/AddProvider.tsx +++ b/packages/components/add-provider/src/AddProvider.tsx @@ -9,45 +9,61 @@ import { MainLive } from "@echo/services-bootstrap"; import { Rx } from "@effect-rx/rx"; import { useRx } from "@effect-rx/rx-react"; import { Layer, Match } from "effect"; -import { useCallback } from "react"; +import { useCallback, useEffect } from "react"; const runtime = Rx.runtime( AddProviderWorkflowLive.pipe(Layer.provide(MainLive)), ); +const activeProvidersFn = runtime.fn(() => AddProviderWorkflow.activeProviders); const loadProviderFn = runtime.fn(AddProviderWorkflow.loadProvider); const connectToProviderFn = runtime.fn(AddProviderWorkflow.connectToProvider); const selectRootFn = runtime.fn(AddProviderWorkflow.selectRoot); export const AddProvider = () => { + const [activeProvidersStatus, loadActiveProviders] = useRx(activeProvidersFn); const [loadStatus, loadProvider] = useRx(loadProviderFn); + useEffect(loadActiveProviders, [loadActiveProviders]); + const onProviderSelected = useCallback( (metadata: ProviderMetadata) => loadProvider(metadata), [loadProvider], ); - return ( -
- {Match.value(loadStatus).pipe( + return Match.value(activeProvidersStatus).pipe( + Match.tag("Initial", () =>

Loading...

), + Match.tag("Success", ({ value: activeProviders }) => + Match.value(loadStatus).pipe( Match.tag("Initial", () => ( - + )), Match.tag("Success", () => ), Match.tag("Failure", () => (
Failed to load provider.
)), Match.exhaustive, - )} -
+ ), + ), + Match.tag("Failure", (error) => ( +
Failed to retrieve current providers: {JSON.stringify(error)}
+ )), + Match.exhaustive, ); }; const ProviderSelector = ({ + currentlyActiveProviders, onProviderSelected, }: { + currentlyActiveProviders: ProviderMetadata[]; onProviderSelected: (metadata: ProviderMetadata) => void; }) => - AvailableProviders.map((metadata) => ( + AvailableProviders.filter( + (m) => !currentlyActiveProviders.some((p) => p.id === m.id), + ).map((metadata) => ( diff --git a/packages/core/types/src/services/active-media-provider-cache.ts b/packages/core/types/src/services/active-media-provider-cache.ts index 72f5e47..366100f 100644 --- a/packages/core/types/src/services/active-media-provider-cache.ts +++ b/packages/core/types/src/services/active-media-provider-cache.ts @@ -39,6 +39,17 @@ export type IActiveMediaProviderCache = { player: MediaPlayer; }> >; + + /** + * Returns all currently active media providers. + */ + readonly getAll: Effect.Effect< + { + metadata: ProviderMetadata; + provider: MediaProvider; + player: MediaPlayer; + }[] + >; }; /** diff --git a/packages/core/types/src/services/workflows/add-provider.workflow.ts b/packages/core/types/src/services/workflows/add-provider.workflow.ts index 3f724c5..1ea386e 100644 --- a/packages/core/types/src/services/workflows/add-provider.workflow.ts +++ b/packages/core/types/src/services/workflows/add-provider.workflow.ts @@ -15,6 +15,7 @@ export type Empty = Record; * Workflow that orchestrates the process of adding a new provider to the application. */ export type IAddProviderWorkflow = { + readonly activeProviders: Effect.Effect; readonly loadProvider: (metadata: ProviderMetadata) => Effect.Effect; readonly connectToProvider: () => Effect.Effect< FolderMetadata[], diff --git a/packages/services/active-media-provider-cache/index.ts b/packages/services/active-media-provider-cache/index.ts index 1b4ee39..b93a78d 100644 --- a/packages/services/active-media-provider-cache/index.ts +++ b/packages/services/active-media-provider-cache/index.ts @@ -56,6 +56,10 @@ const makeActiveMediaProviderCache = Effect.gen(function* () { }); }), ), + getAll: Effect.gen(function* () { + const providerMap = yield* Ref.get(providerByIdRef); + return Array.from(providerMap.values()); + }), }); }); diff --git a/packages/services/add-provider-workflow/src/add-provider.machine.ts b/packages/services/add-provider-workflow/src/add-provider.machine.ts index 191480f..8257bec 100644 --- a/packages/services/add-provider-workflow/src/add-provider.machine.ts +++ b/packages/services/add-provider-workflow/src/add-provider.machine.ts @@ -182,8 +182,12 @@ export const AddProviderWorkflowLive = Layer.scoped( AddProviderWorkflow, Effect.gen(function* () { const actor = yield* Machine.boot(addProviderWorkflow); + const activeMediaProviderCache = yield* ActiveMediaProviderCache; return { + activeProviders: activeMediaProviderCache.getAll.pipe( + Effect.map((providers) => providers.map((p) => p.metadata)), + ), loadProvider: (metadata) => actor.send(new LoadProvider({ metadata })), connectToProvider: () => actor.send(new ConnectToProvider({})), selectRoot: (rootFolder) => actor.send(new SelectRoot({ rootFolder })),