Skip to content

Commit

Permalink
Filter-out active providers in selector
Browse files Browse the repository at this point in the history
  • Loading branch information
sleepyfran committed Aug 27, 2024
1 parent dfd1377 commit 2979a7e
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 8 deletions.
32 changes: 24 additions & 8 deletions packages/components/add-provider/src/AddProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<div>
{Match.value(loadStatus).pipe(
return Match.value(activeProvidersStatus).pipe(
Match.tag("Initial", () => <h1>Loading...</h1>),
Match.tag("Success", ({ value: activeProviders }) =>
Match.value(loadStatus).pipe(
Match.tag("Initial", () => (
<ProviderSelector onProviderSelected={onProviderSelected} />
<ProviderSelector
currentlyActiveProviders={activeProviders}
onProviderSelected={onProviderSelected}
/>
)),
Match.tag("Success", () => <ProviderAuthenticator />),
Match.tag("Failure", () => (
<div style={{ color: "red" }}>Failed to load provider.</div>
)),
Match.exhaustive,
)}
</div>
),
),
Match.tag("Failure", (error) => (
<div>Failed to retrieve current providers: {JSON.stringify(error)}</div>
)),
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) => (
<button key={metadata.id} onClick={() => onProviderSelected(metadata)}>
{metadata.id}
</button>
Expand Down
11 changes: 11 additions & 0 deletions packages/core/types/src/services/active-media-provider-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}[]
>;
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type Empty = Record<string, never>;
* Workflow that orchestrates the process of adding a new provider to the application.
*/
export type IAddProviderWorkflow = {
readonly activeProviders: Effect.Effect<ProviderMetadata[]>;
readonly loadProvider: (metadata: ProviderMetadata) => Effect.Effect<Empty>;
readonly connectToProvider: () => Effect.Effect<
FolderMetadata[],
Expand Down
4 changes: 4 additions & 0 deletions packages/services/active-media-provider-cache/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ const makeActiveMediaProviderCache = Effect.gen(function* () {
});
}),
),
getAll: Effect.gen(function* () {
const providerMap = yield* Ref.get(providerByIdRef);
return Array.from(providerMap.values());
}),
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 })),
Expand Down

0 comments on commit 2979a7e

Please sign in to comment.