flying emojis
This commit is contained in:
parent
30e77c985c
commit
51192c8f58
|
|
@ -1,20 +1,18 @@
|
||||||
# Text Chat
|
# Flying Emojis
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Live example
|
### Live example
|
||||||
|
|
||||||
**[See it in action here ➡️](https://dailyjs-text-chat.vercel.app)**
|
**[See it in action here ➡️](https://dailyjs-flying-emojis.vercel.app)**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## What does this demo do?
|
## What does this demo do?
|
||||||
|
|
||||||
- Use [sendAppMessage](https://docs.daily.co/reference#%EF%B8%8F-sendappmessage) to send messages
|
- Use [sendAppMessage](https://docs.daily.co/reference#%EF%B8%8F-sendappmessage) to send flying emojis to all clients
|
||||||
- Listen for incoming messages using the call object `app-message` event
|
- Implements a custom `<App />` that adds `<FlyingEmojisOverlay />` component that listens for incoming emoji events and appends a new node to the DOM
|
||||||
- Extend the basic call demo with a chat provider and aside
|
- Todo: pool emoji DOM nodes to optimise on DOM mutations
|
||||||
- Show a notification bubble on chat tray button when a new message is received
|
|
||||||
- Demonstrate how to play a sound whenever a message is received
|
|
||||||
|
|
||||||
Please note: this demo is not currently mobile optimised
|
Please note: this demo is not currently mobile optimised
|
||||||
|
|
||||||
|
|
@ -25,17 +23,9 @@ Please note: this demo is not currently mobile optimised
|
||||||
mv env.example .env.local
|
mv env.example .env.local
|
||||||
|
|
||||||
yarn
|
yarn
|
||||||
yarn workspace @dailyjs/text-chat dev
|
yarn workspace @dailyjs/flying-emojis dev
|
||||||
```
|
```
|
||||||
|
|
||||||
## How does this example work?
|
|
||||||
|
|
||||||
In this example we extend the [basic call demo](../basic-call) with the ability to send chat messages.
|
|
||||||
|
|
||||||
We pass a custom tray object, a custom app object (wrapping the original in a new `ChatProvider`) as well as add our `ChatAside` panel. We also symlink both the `public` and `pages/api` folders from the basic call.
|
|
||||||
|
|
||||||
In a real world use case you would likely want to implement serverside logic so that participants joining a call can retrieve previously sent messages. This round trip could be done inside of the Chat context.
|
|
||||||
|
|
||||||
## Deploy your own on Vercel
|
## Deploy your own on Vercel
|
||||||
|
|
||||||
[](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)
|
[](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)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { useCallState } from '@dailyjs/shared/contexts/CallProvider';
|
||||||
const EMOJI_MAP = {
|
const EMOJI_MAP = {
|
||||||
fire: '🔥',
|
fire: '🔥',
|
||||||
squid: '🦑',
|
squid: '🦑',
|
||||||
|
laugh: '🤣',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FlyingEmojisOverlay = () => {
|
export const FlyingEmojisOverlay = () => {
|
||||||
|
|
@ -23,7 +24,7 @@ export const FlyingEmojisOverlay = () => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`⭐ New flying emoji: ${emoji}`);
|
console.log(`⭐ Displaying flying emoji: ${emoji}`);
|
||||||
|
|
||||||
const node = document.createElement('div');
|
const node = document.createElement('div');
|
||||||
node.appendChild(document.createTextNode(EMOJI_MAP[emoji]));
|
node.appendChild(document.createTextNode(EMOJI_MAP[emoji]));
|
||||||
|
|
@ -93,8 +94,8 @@ export const FlyingEmojisOverlay = () => {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
left: 0px;
|
left: 24px;
|
||||||
right: 0px;
|
right: 24px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
@ -123,7 +124,7 @@ export const FlyingEmojisOverlay = () => {
|
||||||
|
|
||||||
@keyframes emerge {
|
@keyframes emerge {
|
||||||
to {
|
to {
|
||||||
bottom: 300px;
|
bottom: 85%;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import Button from '@dailyjs/shared/components/Button';
|
import Button from '@dailyjs/shared/components/Button';
|
||||||
import { TrayButton } from '@dailyjs/shared/components/Tray';
|
import { TrayButton } from '@dailyjs/shared/components/Tray';
|
||||||
|
|
@ -12,7 +12,6 @@ export const Tray = () => {
|
||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('reaction_added', { detail: { emoji } })
|
new CustomEvent('reaction_added', { detail: { emoji } })
|
||||||
);
|
);
|
||||||
|
|
||||||
setShowEmojis(false);
|
setShowEmojis(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -20,8 +19,27 @@ export const Tray = () => {
|
||||||
<div>
|
<div>
|
||||||
{showEmojis && (
|
{showEmojis && (
|
||||||
<div className="emojis">
|
<div className="emojis">
|
||||||
<Button onClick={() => sendEmoji('fire')}>A</Button>
|
<Button
|
||||||
<Button onClick={() => sendEmoji('squid')}>B</Button>
|
variant="outline-gray"
|
||||||
|
size="small-square"
|
||||||
|
onClick={() => sendEmoji('fire')}
|
||||||
|
>
|
||||||
|
🔥
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline-gray"
|
||||||
|
size="small-square"
|
||||||
|
onClick={() => sendEmoji('squid')}
|
||||||
|
>
|
||||||
|
🦑
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline-gray"
|
||||||
|
size="small-square"
|
||||||
|
onClick={() => sendEmoji('laugh')}
|
||||||
|
>
|
||||||
|
🤣
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<TrayButton label="Emoji" onClick={() => setShowEmojis(!showEmojis)}>
|
<TrayButton label="Emoji" onClick={() => setShowEmojis(!showEmojis)}>
|
||||||
|
|
@ -33,8 +51,15 @@ export const Tray = () => {
|
||||||
.emojis {
|
.emojis {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: flex;
|
display: flex;
|
||||||
top: -50px;
|
top: calc(-100% + var(--spacing-xs));
|
||||||
|
left: 0px;
|
||||||
|
transform: translateX(calc(-50% + 26px));
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
|
background: white;
|
||||||
|
padding: var(--spacing-xxxs);
|
||||||
|
column-gap: 5px;
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
box-shadow: var(--shadow-depth-2);
|
||||||
}
|
}
|
||||||
`}</style>
|
`}</style>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue