diff --git a/sample-apps/react/egress-composite/package.json b/sample-apps/react/egress-composite/package.json index 0bfd34f0ff..bcd3b7a8c7 100644 --- a/sample-apps/react/egress-composite/package.json +++ b/sample-apps/react/egress-composite/package.json @@ -13,6 +13,7 @@ "dependencies": { "@emotion/css": "^11.13.5", "@sentry/react": "^10.19.0", + "@skooldev/skool-stream-layout": "^1.0.1", "@stream-io/video-react-sdk": "workspace:^", "clsx": "^2.0.0", "js-base64": "^3.7.8", diff --git a/sample-apps/react/egress-composite/src/ConfigurationContext.tsx b/sample-apps/react/egress-composite/src/ConfigurationContext.tsx index b1a0656fea..b57b885318 100644 --- a/sample-apps/react/egress-composite/src/ConfigurationContext.tsx +++ b/sample-apps/react/egress-composite/src/ConfigurationContext.tsx @@ -135,6 +135,11 @@ export type ConfigurationValue = { 'layout.spotlight.participants_bar_limit'?: 'dynamic' | number; // ✅ custom_actions?: CustomActions; + // used for customer-specific layouts that aren't yet available for + // selection through our dashboard UI. In this case, customers can enable + // them by specifying their identifier in call recording's advanced options. + custom_layout_override?: Layout; + custom_screen_share_layout_override?: ScreenshareLayout; }; } & { setOptionsOverride: Dispatch< @@ -201,6 +206,11 @@ export const applyConfigurationDefaults = ( ...rest } = configuration; + // apply overrides + rest.layout = options.custom_layout_override ?? rest.layout; + rest.screenshare_layout = + options.custom_screen_share_layout_override ?? rest.screenshare_layout; + return { api_key, token, diff --git a/sample-apps/react/egress-composite/src/components/layouts/index.ts b/sample-apps/react/egress-composite/src/components/layouts/index.ts index d277a9efcc..26ca9edd1b 100644 --- a/sample-apps/react/egress-composite/src/components/layouts/index.ts +++ b/sample-apps/react/egress-composite/src/components/layouts/index.ts @@ -4,6 +4,17 @@ import { DominantSpeaker, DominantSpeakerScreenShare } from './DominantSpeaker'; import { PaginatedGrid } from './PaginatedGrid'; import { Spotlight } from './Spotlight'; +// NOTE: with the current setup of the app, using this layout breaks in DEV mode. +// The reason for it seems to be yarn and how `workspace:^` versions are resolved. +// This app and the skool layout package both depend on `@stream-io/video-react-sdk` +// and this causes some resolution conflict internally. +// +// The production builds don't seem to be affected, and we have a workaround for dev. +// The workaround is to modify the egress-composite/package.json with +// `"@stream-io/video-react-sdk": "x.y.z"` (where x.y.z) is the previously released version +// e.g.: current: 1.25.1 -> x.y.z should be 1.25.0 +import { SkoolStreamLayout } from '@skooldev/skool-stream-layout'; + export const DEFAULT_LAYOUT: Layout = 'spotlight'; export const DEFAULT_SCREENSHARE_LAYOUT: ScreenshareLayout = 'spotlight'; @@ -12,12 +23,17 @@ export type Layout = | 'single-participant' | 'spotlight' | 'mobile' - | 'dominant-speaker'; + | 'dominant-speaker' + // custom layouts + | 'skool'; + // NOTE: should always be a subset of the Layout type export type ScreenshareLayout = | 'single-participant' | 'spotlight' - | 'dominant-speaker'; + | 'dominant-speaker' + // custom layouts + | 'skool'; export const layoutMap: Record< Layout, @@ -29,4 +45,7 @@ export const layoutMap: Record< mobile: [DominantSpeaker, DominantSpeakerScreenShare], grid: [PaginatedGrid], spotlight: [Spotlight, Spotlight], + + // custom layouts + skool: [SkoolStreamLayout, SkoolStreamLayout], }; diff --git a/sample-apps/react/egress-composite/src/main.tsx b/sample-apps/react/egress-composite/src/main.tsx index 7fcc851ac8..56488a1631 100644 --- a/sample-apps/react/egress-composite/src/main.tsx +++ b/sample-apps/react/egress-composite/src/main.tsx @@ -9,6 +9,7 @@ import { import { CompositeApp } from './CompositeApp'; import '@stream-io/video-react-sdk/dist/css/styles.css'; +import '@skooldev/skool-stream-layout/dist/styles.css'; // Uncomment this line to test your own custom CSS // import cssUrl from '../public/example/custom.css?url'; diff --git a/yarn.lock b/yarn.lock index ed71bd7bce..2024e3d787 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7052,6 +7052,17 @@ __metadata: languageName: node linkType: hard +"@skooldev/skool-stream-layout@npm:^1.0.1": + version: 1.0.1 + resolution: "@skooldev/skool-stream-layout@npm:1.0.1" + peerDependencies: + "@stream-io/video-react-sdk": ^1.25.0 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + checksum: 10/ff87dd44de90a5622fe77c11260832091e52d9dd957b694cc92199cf57480a4bf1c191b2603f2d86575bdf5fa93a693f39bf58f06b6a1d79dc055258cb7f4078 + languageName: node + linkType: hard + "@stream-io/audio-filters-web@workspace:^, @stream-io/audio-filters-web@workspace:packages/audio-filters-web": version: 0.0.0-use.local resolution: "@stream-io/audio-filters-web@workspace:packages/audio-filters-web" @@ -7108,6 +7119,7 @@ __metadata: "@playwright/test": "npm:^1.56.0" "@sentry/react": "npm:^10.19.0" "@sentry/vite-plugin": "npm:^4.3.0" + "@skooldev/skool-stream-layout": "npm:^1.0.1" "@stream-io/video-react-sdk": "workspace:^" "@types/react": "npm:~19.1.17" "@types/react-dom": "npm:~19.1.11"