├── .eslintrc ├── .gitignore ├── .prettierrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── custom ├── .gitignore ├── README.md ├── active-speaker │ ├── .babelrc │ ├── README.md │ ├── components │ │ ├── App │ │ │ ├── App.js │ │ │ └── index.js │ │ ├── Room │ │ │ ├── Room.js │ │ │ └── index.js │ │ └── SpeakerView │ │ │ ├── SpeakerTile │ │ │ ├── SpeakerTile.js │ │ │ └── index.js │ │ │ ├── SpeakerView.js │ │ │ └── index.js │ ├── env.example │ ├── image.png │ ├── index.js │ ├── next.config.js │ ├── package.json │ ├── pages │ │ ├── _app.js │ │ ├── api │ │ └── index.js │ └── public │ │ └── assets │ │ ├── daily-logo-dark.svg │ │ ├── daily-logo.svg │ │ ├── join.mp3 │ │ ├── message.mp3 │ │ └── pattern-bg.png ├── basic-call │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── components │ │ ├── App │ │ │ ├── App.js │ │ │ ├── Asides.js │ │ │ ├── Modals.js │ │ │ └── index.js │ │ ├── Call │ │ │ ├── Container.js │ │ │ ├── Header.js │ │ │ ├── Room.js │ │ │ ├── VideoGrid.js │ │ │ └── WaitingRoom.js │ │ └── Prejoin │ │ │ ├── CreatingRoom.js │ │ │ ├── Intro.js │ │ │ └── NotConfigured.js │ ├── env.example │ ├── image.png │ ├── index.js │ ├── next.config.js │ ├── package.json │ ├── pages │ │ ├── _app.js │ │ ├── _document.js │ │ ├── api │ │ │ ├── createRoom.js │ │ │ └── token.js │ │ ├── index.js │ │ └── not-found.js │ └── public │ │ └── assets │ │ ├── daily-logo-dark.svg │ │ ├── daily-logo.svg │ │ ├── join.mp3 │ │ ├── message.mp3 │ │ └── pattern-bg.png ├── fitness-demo │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── components │ │ ├── App │ │ │ ├── App.js │ │ │ ├── AsideHeader.js │ │ │ ├── Asides.js │ │ │ ├── Modals.js │ │ │ └── index.js │ │ ├── Call │ │ │ ├── ChatAside.js │ │ │ ├── Container.js │ │ │ ├── Header.js │ │ │ ├── InviteOthers.js │ │ │ ├── PeopleAside.js │ │ │ ├── Room.js │ │ │ ├── VideoView.js │ │ │ └── WaitingRoom.js │ │ ├── GridView │ │ │ ├── GridView.js │ │ │ └── index.js │ │ ├── Prejoin │ │ │ ├── Intro.js │ │ │ └── NotConfigured.js │ │ ├── SpeakerView │ │ │ ├── ScreensAndPins │ │ │ │ ├── ScreenPinTile.js │ │ │ │ ├── ScreensAndPins.js │ │ │ │ └── index.js │ │ │ ├── SpeakerTile │ │ │ │ ├── SpeakerTile.js │ │ │ │ └── index.js │ │ │ ├── SpeakerView.js │ │ │ └── index.js │ │ └── Tray │ │ │ ├── Chat.js │ │ │ ├── Record.js │ │ │ ├── ScreenShare.js │ │ │ ├── Stream.js │ │ │ └── index.js │ ├── contexts │ │ ├── ChatProvider.js │ │ └── ClassStateProvider.js │ ├── env.example │ ├── image.png │ ├── index.js │ ├── next.config.js │ ├── package.json │ ├── pages │ │ ├── [room].js │ │ ├── _app.js │ │ ├── _document.js │ │ ├── api │ │ │ ├── createRoom.js │ │ │ ├── editRoom.js │ │ │ ├── presence.js │ │ │ ├── room.js │ │ │ └── token.js │ │ ├── index.js │ │ └── not-found.js │ └── public │ │ └── assets │ │ ├── daily-logo-dark.svg │ │ ├── daily-logo.svg │ │ ├── join.mp3 │ │ ├── message.mp3 │ │ ├── pattern-bg.png │ │ └── pattern-ls.svg ├── flying-emojis │ ├── .babelrc │ ├── README.md │ ├── components │ │ ├── App.js │ │ ├── FlyingEmojisOverlay.js │ │ └── Tray.js │ ├── env.example │ ├── image.png │ ├── index.js │ ├── next.config.js │ ├── package.json │ ├── pages │ │ ├── _app.js │ │ ├── _document.js │ │ ├── api │ │ └── index.js │ └── public │ │ └── assets │ │ ├── daily-logo-dark.svg │ │ ├── daily-logo.svg │ │ ├── join.mp3 │ │ ├── message.mp3 │ │ └── pattern-bg.png ├── live-streaming │ ├── .babelrc │ ├── README.md │ ├── components │ │ ├── App.js │ │ ├── LiveStreamingModal.js │ │ └── Tray.js │ ├── env.example │ ├── image.png │ ├── index.js │ ├── next.config.js │ ├── package.json │ ├── pages │ │ ├── _app.js │ │ ├── _document.js │ │ ├── api │ │ └── index.js │ └── public │ │ └── assets │ │ ├── daily-logo-dark.svg │ │ ├── daily-logo.svg │ │ ├── join.mp3 │ │ ├── message.mp3 │ │ └── pattern-bg.png ├── live-transcription │ ├── .babelrc │ ├── README.md │ ├── components │ │ ├── App.js │ │ ├── TranscriptionAside.js │ │ └── Tray.js │ ├── env.example │ ├── image.gif │ ├── index.js │ ├── next.config.js │ ├── package.json │ ├── pages │ │ ├── _app.js │ │ ├── api │ │ └── index.js │ └── public │ │ └── assets │ │ ├── daily-logo-dark.svg │ │ ├── daily-logo.svg │ │ ├── join.mp3 │ │ ├── message.mp3 │ │ └── pattern-bg.png ├── pagination │ ├── .babelrc │ ├── App.js │ ├── README.md │ ├── components │ │ ├── App.js │ │ ├── PaginatedVideoGrid.js │ │ └── Tray.js │ ├── env.example │ ├── image.png │ ├── next.config.js │ ├── package.json │ ├── pages │ │ ├── _app.js │ │ ├── _document.js │ │ ├── api │ │ └── index.js │ └── public │ │ └── assets │ │ ├── daily-logo-dark.svg │ │ ├── daily-logo.svg │ │ ├── join.mp3 │ │ ├── message.mp3 │ │ └── pattern-bg.png ├── recording │ ├── .babelrc │ ├── README.md │ ├── components │ │ ├── App.js │ │ ├── RecordingModal.js │ │ └── Tray.js │ ├── contexts │ │ └── RecordingProvider.js │ ├── env.example │ ├── image.png │ ├── index.js │ ├── next.config.js │ ├── package.json │ ├── pages │ │ ├── _app.js │ │ ├── _document.js │ │ ├── api │ │ └── index.js │ └── public │ │ └── assets │ │ ├── daily-logo-dark.svg │ │ ├── daily-logo.svg │ │ ├── join.mp3 │ │ ├── message.mp3 │ │ └── pattern-bg.png ├── shared │ ├── components │ │ ├── Aside │ │ │ ├── Aside.js │ │ │ ├── NetworkAside.js │ │ │ ├── PeopleAside.js │ │ │ └── index.js │ │ ├── Audio │ │ │ ├── Audio.js │ │ │ ├── AudioTrack.js │ │ │ ├── CombinedAudioTrack.js │ │ │ └── index.js │ │ ├── Button │ │ │ ├── Button.js │ │ │ └── index.js │ │ ├── Capsule │ │ │ ├── Capsule.js │ │ │ └── index.js │ │ ├── Card │ │ │ ├── Card.js │ │ │ └── index.js │ │ ├── DeviceSelect │ │ │ ├── DeviceSelect.js │ │ │ └── index.js │ │ ├── DeviceSelectModal │ │ │ ├── DeviceSelectModal.js │ │ │ └── index.js │ │ ├── ExpiryTimer │ │ │ ├── ExpiryTimer.js │ │ │ └── index.js │ │ ├── Field │ │ │ ├── Field.js │ │ │ └── index.js │ │ ├── GlobalStyle │ │ │ ├── GlobalStyle.js │ │ │ └── index.js │ │ ├── HairCheck │ │ │ ├── HairCheck.js │ │ │ └── index.js │ │ ├── Header │ │ │ ├── Header.js │ │ │ └── index.js │ │ ├── HeaderCapsule │ │ │ ├── HeaderCapsule.js │ │ │ └── index.js │ │ ├── Input │ │ │ ├── Input.js │ │ │ └── index.js │ │ ├── Loader │ │ │ ├── Loader.js │ │ │ └── index.js │ │ ├── MessageCard │ │ │ ├── MessageCard.js │ │ │ └── index.js │ │ ├── Modal │ │ │ ├── Modal.js │ │ │ └── index.js │ │ ├── MuteButton │ │ │ ├── MuteButton.js │ │ │ └── index.js │ │ ├── ParticipantBar │ │ │ ├── ParticipantBar.js │ │ │ ├── index.js │ │ │ └── useBlockScrolling.js │ │ ├── Tile │ │ │ ├── Tile.js │ │ │ ├── Video.js │ │ │ ├── avatar.svg │ │ │ └── index.js │ │ ├── Tray │ │ │ ├── BasicTray.js │ │ │ ├── Tray.js │ │ │ ├── TrayButton.js │ │ │ ├── TrayMicButton.js │ │ │ └── index.js │ │ ├── VideoContainer │ │ │ ├── VideoContainer.js │ │ │ └── index.js │ │ ├── WaitingRoom │ │ │ ├── WaitingParticipantRow.js │ │ │ ├── WaitingRoomModal.js │ │ │ ├── WaitingRoomNotification.js │ │ │ └── index.js │ │ └── Well │ │ │ ├── Well.js │ │ │ └── index.js │ ├── constants.js │ ├── contexts │ │ ├── CallProvider.js │ │ ├── LiveStreamingProvider.js │ │ ├── MediaDeviceProvider.js │ │ ├── ParticipantsProvider.js │ │ ├── ScreenShareProvider.js │ │ ├── TracksProvider.js │ │ ├── TranscriptionProvider.js │ │ ├── UIStateProvider.js │ │ ├── WaitingRoomProvider.js │ │ ├── participantsState.js │ │ ├── tracksState.js │ │ └── useCallMachine.js │ ├── hooks │ │ ├── useActiveSpeaker.js │ │ ├── useAudioLevel.js │ │ ├── useAudioTrack.js │ │ ├── useCallUI.js │ │ ├── useCamSubscriptions.js │ │ ├── useJoinSound.js │ │ ├── useNetworkState.js │ │ ├── useResize.js │ │ ├── useResponsive.js │ │ ├── useScrollbarWidth.js │ │ ├── useSharedState.js │ │ ├── useSound.js │ │ ├── useSoundLoader.js │ │ └── useVideoTrack.js │ ├── icons │ │ ├── add-md.svg │ │ ├── add-person-lg.svg │ │ ├── avatar-md.svg │ │ ├── camera-off-md.svg │ │ ├── camera-off-sm.svg │ │ ├── camera-on-md.svg │ │ ├── camera-on-sm.svg │ │ ├── chat-md.svg │ │ ├── close-sm.svg │ │ ├── emoji-sm.svg │ │ ├── grid-md.svg │ │ ├── leave-md.svg │ │ ├── lock-md.svg │ │ ├── mic-off-md.svg │ │ ├── mic-off-sm.svg │ │ ├── mic-on-md.svg │ │ ├── mic-on-sm.svg │ │ ├── more-md.svg │ │ ├── network-md.svg │ │ ├── people-md.svg │ │ ├── play-sm.svg │ │ ├── raquo-md.svg │ │ ├── record-md.svg │ │ ├── settings-md.svg │ │ ├── settings-sm.svg │ │ ├── share-sm.svg │ │ ├── speaker-view-md.svg │ │ ├── star-md.svg │ │ └── streaming-md.svg │ ├── index.js │ ├── lib │ │ ├── demoProps.js │ │ ├── mediaUtils.js │ │ ├── slugify.js │ │ ├── sortByKey.js │ │ ├── sortLastActive.js │ │ └── token.js │ ├── package.json │ └── styles │ │ ├── defaultTheme.js │ │ └── global.js └── text-chat │ ├── .babelrc │ ├── README.md │ ├── components │ ├── App.js │ ├── ChatAside.js │ └── Tray.js │ ├── contexts │ └── ChatProvider.js │ ├── env.example │ ├── hooks │ └── useMessageSound.js │ ├── image.png │ ├── index.js │ ├── next.config.js │ ├── package.json │ ├── pages │ ├── _app.js │ ├── _document.js │ ├── api │ └── index.js │ └── public │ ├── assets │ ├── daily-logo-dark.svg │ ├── daily-logo.svg │ ├── join.mp3 │ ├── message.mp3 │ └── pattern-bg.png │ └── components │ └── Header │ ├── Header.js │ └── index.js ├── logo.png ├── package-lock.json ├── package.json ├── prebuilt ├── README.md ├── basic-embed │ ├── .env.example │ ├── .gitignore │ ├── README.md │ ├── basic-embed.gif │ ├── components │ │ ├── Call.js │ │ ├── CreateRoomButton.js │ │ ├── ExpiryTimer.js │ │ └── Home.js │ ├── next.config.js │ ├── package.json │ ├── pages │ │ ├── _app.js │ │ ├── api │ │ │ └── room │ │ │ │ └── index.js │ │ └── index.js │ ├── public │ │ ├── daily-logo.svg │ │ ├── favicon.ico │ │ └── github-logo.png │ └── yarn.lock ├── chat-overlay │ ├── README.md │ ├── image.jpg │ ├── index.html │ ├── main.css │ └── main.js └── ios-webview │ ├── .gitignore │ ├── README.md │ ├── WebViewPrebuilt.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── WebViewPrebuilt │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── SceneDelegate.swift │ └── ViewController.swift │ └── image.png └── yarn.lock /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["next/core-web-vitals", "prettier"], 3 | "env": { 4 | "browser": true, 5 | "node": true, 6 | "es6": true 7 | }, 8 | "rules": { 9 | "import/no-extraneous-dependencies": 0, 10 | "@next/next/no-img-element": 0, 11 | "import/order": [ 12 | "error", 13 | { 14 | "groups": ["builtin", "external", "parent", "sibling", "index"], 15 | "pathGroups": [ 16 | { 17 | "pattern": "react", 18 | "group": "external", 19 | "position": "before" 20 | } 21 | ], 22 | "pathGroupsExcludedImportTypes": ["react"], 23 | "alphabetize": { 24 | "order": "asc" 25 | } 26 | } 27 | ] 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | .pnp 6 | .pnp.js 7 | 8 | # testing 9 | coverage 10 | 11 | # next.js 12 | .next 13 | out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env 29 | .env.local 30 | .env.development.local 31 | .env.test.local 32 | .env.production.local 33 | 34 | # vercel 35 | .vercel -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "singleQuote": true 6 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2021, Daily 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Daily Examples](./logo.png) 2 | 3 | # [Daily](https://daily.co) | Examples 4 | 5 | This repository uses [yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/) so it's required to have yarn [installed](https://classic.yarnpkg.com/en/docs/install). 6 | 7 | ## Getting started 8 | 9 | Setup dependencies via `yarn install`. 10 | 11 | Add the required environment variables (e.g. your Daily API key) for the demo being used. Each demo's README will list the required environment variables to run it locally. 12 | 13 | Run an example via `yarn workspace @custom/basic-call dev` (replacing `basic-call` with the name of the demo). 14 | 15 | Please note: these demos are intended as educational resources for using the Daily platform as well as showcasing common usage patterns and best practices. That said, they are not intended to be used as production ready applications. 16 | 17 | --- 18 | 19 | ## Contents 20 | 21 | ## [Custom (Web)](./custom/) 22 | 23 | Examples that showcase the Daily call object using our Javascript library 24 | 25 | ## [Prebuilt UI](./prebuilt) 26 | 27 | Examples that showcase using and customizing the Daily Prebuilt UI 28 | 29 | --- 30 | 31 | ## Contributions 32 | 33 | We welcome all contributions that make it easier for developers to get to know Daily through these demos. If you'd like to open or claim an issue, add your own demo, or contribute in another way, please read CONTRIBUTING.md. 34 | 35 | ## Contact us 36 | 37 | We're always happy to help developers building on Daily. Reach out to us any time at help@daily.co, or chat with us. 38 | -------------------------------------------------------------------------------- /custom/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | .pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | .next 13 | out 14 | 15 | # production 16 | build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env 29 | .env.local 30 | .env.development.local 31 | .env.test.local 32 | .env.production.local 33 | 34 | # vercel 35 | .vercel -------------------------------------------------------------------------------- /custom/active-speaker/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["next/babel"], 3 | "plugins": ["inline-react-svg"] 4 | } 5 | -------------------------------------------------------------------------------- /custom/active-speaker/README.md: -------------------------------------------------------------------------------- 1 | # Active Speaker 2 | 3 | ![Active Speaker](./image.png) 4 | 5 | ### Live example 6 | 7 | **[See it in action here ➡️](https://custom-active-speaker.vercel.app)** 8 | 9 | --- 10 | 11 | ## What does this demo do? 12 | 13 | - Uses an active speaker view mode that shows the currently talking participant (or active screen share) in a larger tile 14 | - Introduces the `ParticipantBar` column that virtually scrolls through all call participants 15 | - Uses manual subscriptions to paginate between tiles that are currently in view. For more information about how this works, please refer to the [pagination demo](../pagination) 16 | 17 | Please note: this demo is not currently mobile optimised 18 | 19 | ### Getting started 20 | 21 | ``` 22 | # set both DAILY_API_KEY and DAILY_DOMAIN 23 | mv env.example .env.local 24 | 25 | yarn 26 | yarn workspace @custom/active-speaker dev 27 | ``` 28 | 29 | ## Deploy your own on Vercel 30 | 31 | [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/daily-co/clone-flow?repository-url=https%3A%2F%2Fgithub.com%2Fdaily-demos%2Fexamples.git&env=DAILY_DOMAIN%2CDAILY_API_KEY&envDescription=Your%20Daily%20domain%20and%20API%20key%20can%20be%20found%20on%20your%20account%20dashboard&envLink=https%3A%2F%2Fdashboard.daily.co&project-name=daily-examples&repo-name=daily-examples) 32 | -------------------------------------------------------------------------------- /custom/active-speaker/components/App/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import App from '@custom/basic-call/components/App'; 4 | import { Room } from '../Room'; 5 | 6 | // Extend our basic call app component with our custom Room componenet 7 | export const AppWithSpeakerViewRoom = () => ( 8 | , 11 | }} 12 | /> 13 | ); 14 | 15 | export default AppWithSpeakerViewRoom; 16 | -------------------------------------------------------------------------------- /custom/active-speaker/components/App/index.js: -------------------------------------------------------------------------------- 1 | export { AppWithSpeakerViewRoom as default } from './App'; 2 | -------------------------------------------------------------------------------- /custom/active-speaker/components/Room/Room.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { SpeakerView } from '../SpeakerView'; 4 | 5 | export const Room = () => ; 6 | 7 | export default Room; 8 | -------------------------------------------------------------------------------- /custom/active-speaker/components/Room/index.js: -------------------------------------------------------------------------------- 1 | export { Room as default } from './Room'; 2 | export { Room } from './Room'; 3 | -------------------------------------------------------------------------------- /custom/active-speaker/components/SpeakerView/SpeakerTile/index.js: -------------------------------------------------------------------------------- 1 | export { SpeakerTile as default } from './SpeakerTile'; 2 | export { SpeakerTile } from './SpeakerTile'; 3 | -------------------------------------------------------------------------------- /custom/active-speaker/components/SpeakerView/index.js: -------------------------------------------------------------------------------- 1 | export { SpeakerView as default } from './SpeakerView'; 2 | export { SpeakerView } from './SpeakerView'; 3 | -------------------------------------------------------------------------------- /custom/active-speaker/env.example: -------------------------------------------------------------------------------- 1 | # Domain excluding 'https://' and 'daily.co' e.g. 'somedomain' 2 | DAILY_DOMAIN= 3 | 4 | # Obtained from https://dashboard.daily.co/developers 5 | DAILY_API_KEY= 6 | 7 | # Daily REST API endpoint 8 | DAILY_REST_DOMAIN=https://api.daily.co/v1 9 | 10 | 11 | # Enable manual track subscriptions 12 | MANUAL_TRACK_SUBS=1 -------------------------------------------------------------------------------- /custom/active-speaker/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-demos/examples/562a32174d6a2c5b677a32b51d990f0ecfdb2043/custom/active-speaker/image.png -------------------------------------------------------------------------------- /custom/active-speaker/index.js: -------------------------------------------------------------------------------- 1 | // Note: I am here because next-transpile-modules requires a mainfile 2 | -------------------------------------------------------------------------------- /custom/active-speaker/next.config.js: -------------------------------------------------------------------------------- 1 | const withPlugins = require('next-compose-plugins'); 2 | const withTM = require('next-transpile-modules')([ 3 | '@custom/shared', 4 | '@custom/basic-call', 5 | ]); 6 | 7 | const packageJson = require('./package.json'); 8 | 9 | module.exports = withPlugins([withTM], { 10 | env: { 11 | PROJECT_TITLE: packageJson.description, 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /custom/active-speaker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@custom/active-speaker", 3 | "description": "Basic Call + Active Speaker", 4 | "version": "0.1.0", 5 | "private": true, 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "start": "next start", 10 | "lint": "next lint" 11 | }, 12 | "dependencies": { 13 | "@custom/basic-call": "*", 14 | "@custom/shared": "*", 15 | "next": "^11.0.0", 16 | "pluralize": "^8.0.0", 17 | "react": "^17.0.2", 18 | "react-dom": "^17.0.2" 19 | }, 20 | "devDependencies": { 21 | "babel-plugin-module-resolver": "^4.1.0", 22 | "next-compose-plugins": "^2.2.1", 23 | "next-transpile-modules": "^8.0.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /custom/active-speaker/pages/_app.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import App from '@custom/basic-call/pages/_app'; 3 | import AppWithSpeakerViewRoom from '../components/App'; 4 | 5 | App.customAppComponent = ; 6 | 7 | export default App; 8 | -------------------------------------------------------------------------------- /custom/active-speaker/pages/api: -------------------------------------------------------------------------------- 1 | ../../basic-call/pages/api -------------------------------------------------------------------------------- /custom/active-speaker/pages/index.js: -------------------------------------------------------------------------------- 1 | import Index from '@custom/basic-call/pages'; 2 | import getDemoProps from '@custom/shared/lib/demoProps'; 3 | 4 | export async function getStaticProps() { 5 | const defaultProps = getDemoProps(); 6 | 7 | // Pass through domain as prop 8 | return { 9 | props: defaultProps, 10 | }; 11 | } 12 | 13 | export default Index; 14 | -------------------------------------------------------------------------------- /custom/active-speaker/public/assets/join.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-demos/examples/562a32174d6a2c5b677a32b51d990f0ecfdb2043/custom/active-speaker/public/assets/join.mp3 -------------------------------------------------------------------------------- /custom/active-speaker/public/assets/message.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-demos/examples/562a32174d6a2c5b677a32b51d990f0ecfdb2043/custom/active-speaker/public/assets/message.mp3 -------------------------------------------------------------------------------- /custom/active-speaker/public/assets/pattern-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-demos/examples/562a32174d6a2c5b677a32b51d990f0ecfdb2043/custom/active-speaker/public/assets/pattern-bg.png -------------------------------------------------------------------------------- /custom/basic-call/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["next/babel"], 3 | "plugins": ["inline-react-svg"] 4 | } 5 | -------------------------------------------------------------------------------- /custom/basic-call/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | .pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | .next 13 | out 14 | 15 | # production 16 | build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env 29 | .env.local 30 | .env.development.local 31 | .env.test.local 32 | .env.production.local 33 | 34 | # vercel 35 | .vercel -------------------------------------------------------------------------------- /custom/basic-call/README.md: -------------------------------------------------------------------------------- 1 | # Basic call 2 | 3 | ![Basic Call](./image.png) 4 | 5 | ### Live example 6 | 7 | **[See it in action here ➡️](https://custom-basic-call.vercel.app)** 8 | 9 | --- 10 | 11 | ## What does this demo do? 12 | 13 | - Built on [NextJS](https://nextjs.org/) 14 | - Create a Daily instance using call object mode 15 | - Manage user media devices 16 | - Render UI based on the call state 17 | - Handle media and call errors 18 | - Obtain call access token via Daily REST API 19 | - Handle preauthentication, knock for access and auto join 20 | 21 | Please note: this demo is not currently mobile optimised 22 | 23 | ### Getting started 24 | 25 | ``` 26 | # set both DAILY_API_KEY and DAILY_DOMAIN 27 | mv env.example .env.local 28 | 29 | # from project root... 30 | yarn 31 | yarn workspace @custom/basic-call dev 32 | ``` 33 | 34 | ## How does this example work? 35 | 36 | This demo puts to work the following [shared libraries](../shared): 37 | 38 | **[MediaDeviceProvider.js](../shared/contexts/MediaDeviceProvider.js)** 39 | Convenience context that provides an interface to media devices throughout app 40 | 41 | **[CallProvider.js](../shared/contexts/CallProvider.js)** 42 | Primary call context that manages Daily call state, participant state and call object interaction 43 | 44 | **[useCallMachine.js](../shared/contexts/useCallMachine.js)** 45 | Abstraction hook that manages Daily call state and error handling 46 | 47 | **[ParticipantsProvider.js](../shared/contexts/ParticipantsProvider.js)** 48 | Manages participant state and abstracts common selectors / derived data 49 | 50 | ## Deploy your own on Vercel 51 | 52 | [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/daily-co/clone-flow?repository-url=https%3A%2F%2Fgithub.com%2Fdaily-demos%2Fexamples.git&env=DAILY_DOMAIN%2CDAILY_API_KEY&envDescription=Your%20Daily%20domain%20and%20API%20key%20can%20be%20found%20on%20your%20account%20dashboard&envLink=https%3A%2F%2Fdashboard.daily.co&project-name=daily-examples&repo-name=daily-examples) 53 | -------------------------------------------------------------------------------- /custom/basic-call/components/App/App.js: -------------------------------------------------------------------------------- 1 | import React, { useMemo } from 'react'; 2 | import ExpiryTimer from '@custom/shared/components/ExpiryTimer'; 3 | import { useCallState } from '@custom/shared/contexts/CallProvider'; 4 | import { useCallUI } from '@custom/shared/hooks/useCallUI'; 5 | 6 | import PropTypes from 'prop-types'; 7 | import Room from '../Call/Room'; 8 | import { Asides } from './Asides'; 9 | import { Modals } from './Modals'; 10 | 11 | export const App = ({ customComponentForState }) => { 12 | const { roomExp, state } = useCallState(); 13 | 14 | const componentForState = useCallUI({ 15 | state, 16 | room: , 17 | ...customComponentForState, 18 | }); 19 | 20 | // Memoize children to avoid unnecessary renders from HOC 21 | return useMemo( 22 | () => ( 23 | <> 24 | {roomExp && } 25 |
26 | {componentForState()} 27 | 28 | 29 | 40 |
41 | 42 | ), 43 | [componentForState, roomExp] 44 | ); 45 | }; 46 | 47 | App.propTypes = { 48 | customComponentForState: PropTypes.any, 49 | }; 50 | 51 | export default App; 52 | -------------------------------------------------------------------------------- /custom/basic-call/components/App/Asides.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { NetworkAside } from '@custom/shared/components/Aside'; 3 | import { PeopleAside } from '@custom/shared/components/Aside'; 4 | import { useUIState } from '@custom/shared/contexts/UIStateProvider'; 5 | 6 | export const Asides = () => { 7 | const { asides } = useUIState(); 8 | 9 | return ( 10 | <> 11 | 12 | 13 | {asides.map((AsideComponent) => ( 14 | 15 | ))} 16 | 17 | ); 18 | }; 19 | 20 | export default Asides; 21 | -------------------------------------------------------------------------------- /custom/basic-call/components/App/Modals.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import DeviceSelectModal from '@custom/shared/components/DeviceSelectModal/DeviceSelectModal'; 3 | import { useUIState } from '@custom/shared/contexts/UIStateProvider'; 4 | 5 | export const Modals = () => { 6 | const { modals } = useUIState(); 7 | 8 | return ( 9 | <> 10 | 11 | {modals.map((ModalComponent) => ( 12 | 13 | ))} 14 | 15 | ); 16 | }; 17 | 18 | export default Modals; 19 | -------------------------------------------------------------------------------- /custom/basic-call/components/App/index.js: -------------------------------------------------------------------------------- 1 | export { App as default } from './App'; 2 | -------------------------------------------------------------------------------- /custom/basic-call/components/Call/Container.js: -------------------------------------------------------------------------------- 1 | import React, { useMemo } from 'react'; 2 | import { Audio } from '@custom/shared/components/Audio'; 3 | import { BasicTray } from '@custom/shared/components/Tray'; 4 | import { useParticipants } from '@custom/shared/contexts/ParticipantsProvider'; 5 | import { useJoinSound } from '@custom/shared/hooks/useJoinSound'; 6 | import PropTypes from 'prop-types'; 7 | import { WaitingRoom } from './WaitingRoom'; 8 | 9 | export const Container = ({ children }) => { 10 | const { isOwner } = useParticipants(); 11 | 12 | useJoinSound(); 13 | 14 | const roomComponents = useMemo( 15 | () => ( 16 | <> 17 | {/* Show waiting room notification & modal if call owner */} 18 | {isOwner && } 19 | {/* Tray buttons */} 20 | 21 | {/* Audio tags */} 22 |