This commit is contained in:
Nathan Vasse
2025-02-03 16:53:51 +01:00
parent 414b3720f1
commit e2887880c6
9 changed files with 184 additions and 34 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ import { routes } from './routes'
import './i18n/init'
import { queryClient } from '@/api/queryClient'
import { AppInitialization } from '@/components/AppInitialization'
import { SdkCreateButton } from './features/rooms/routes/sdk/CreateButton'
import { SdkCreateButton } from './features/sdk/routes/CreateButton'
function App() {
const { i18n } = useTranslation()
@@ -0,0 +1,25 @@
export enum ClientMessageType {
ROOM_CREATED = 'ROOM_CREATED',
}
export class SdkReverseClient {
/**
* TODO: Use API Key. Must be based on some sort of credentials ?
*/
static getAllowTargetOrigin() {
return '*'
}
static post(type: ClientMessageType, data: unknown = {}) {
console.log('POST !', type, data, window.parent)
// TODO: Make sure to use the correct origin.
window.parent.postMessage(
{
type,
data,
},
SdkReverseClient.getAllowTargetOrigin()
)
// TODO: Maybe use this to enforce security.
}
}
@@ -1,14 +1,13 @@
import { Button } from '@/primitives/Button'
import { useTranslation } from 'react-i18next'
import { generateRoomId } from '../../utils/generateRoomId'
import { useCreateRoom } from '../../api/createRoom'
import { usePersistentUserChoices } from '@livekit/components-react'
import { useState } from 'react'
import { getRouteUrl } from '@/navigation/getRouteUrl'
import { css } from '@/styled-system/css'
import { RiCheckLine, RiFileCopyLine } from '@remixicon/react'
import { Loader } from '@/primitives/Loader'
import { VisioIcon } from '@/assets/VisioIcon'
import { generateRoomId, useCreateRoom } from '../../rooms'
import { ClientMessageType, SdkReverseClient } from '../SdkReverseClient'
export const SdkCreateButton = () => {
const { t } = useTranslation('sdk', { keyPrefix: 'createButton' })
@@ -30,8 +29,11 @@ export const SdkCreateButton = () => {
const roomUrlTmp = getRouteUrl('room', data.slug)
setRoomUrl(roomUrlTmp)
setIsLoading(false)
SdkReverseClient.post(ClientMessageType.ROOM_CREATED, {
url: roomUrlTmp,
})
})
}, 2000)
}, 0)
}
const [isCopied, setIsCopied] = useState(false)
@@ -44,33 +46,39 @@ export const SdkCreateButton = () => {
}
return (
<div className={css({})}>
<div
className={css({
paddingTop: '3px',
paddingLeft: '3px',
})}
>
{roomUrl ? (
<Button
variant={isCopied ? 'success' : 'tertiaryText'}
variant={isCopied ? 'success' : 'quaternary'}
onHoverChange={setIsHovered}
data-attr="sdk-create-copy"
onPress={copy}
className={css({
...(isCopied
? {}
: {
paddingLeft: 0,
}),
})}
icon={
isCopied ? (
<RiCheckLine size={18} style={{ marginRight: '8px' }} />
) : undefined
) : (
<RiFileCopyLine size={24} />
)
}
>
{isCopied ? (
th('laterMeetingDialog.copied')
) : (
<div
className={css({
display: 'flex',
alignItems: 'center',
color: 'greyscale.600',
gap: '0.5rem',
})}
>
<div>{roomUrl}</div>
<RiFileCopyLine size={24} />
</div>
<>
{isHovered ? th('laterMeetingDialog.copy') : <div>{roomUrl}</div>}
</>
)}
</Button>
) : (
+3 -2
View File
@@ -23,12 +23,13 @@ export const Button = ({
...props
}: ButtonProps) => {
const [variantProps, componentProps] = buttonRecipe.splitVariantProps(props)
const { className, ...remainingComponentProps } = componentProps
return (
<TooltipWrapper tooltip={tooltip} tooltipType={tooltipType}>
<RACButton
className={buttonRecipe(variantProps)}
{...(componentProps as RACButtonsProps)}
className={[buttonRecipe(variantProps), className].join(' ')}
{...(remainingComponentProps as RACButtonsProps)}
>
{!props.loading && props.icon}
{props.loading && <Loader />}
@@ -140,6 +140,18 @@ export const buttonRecipe = cva({
color: 'primaryDark.100',
},
},
quaternaryText: {
backgroundColor: 'transparent',
color: 'greyscale.600',
'&[data-hovered]': {
backgroundColor: 'greyscale.100',
color: 'greyscale.700',
},
'&[data-pressed]': {
backgroundColor: 'greyscale.100',
color: 'greyscale.700',
},
},
greyscale: {
backgroundColor: 'transparent',
color: 'greyscale.400',
-6
View File
@@ -1,6 +1,5 @@
import { FeedbackRoute, RoomRoute, roomIdPattern } from '@/features/rooms'
import { HomeRoute } from '@/features/home'
import { SdkCreateButton } from './features/rooms/routes/sdk/CreateButton'
export const routes: Record<
'home' | 'room' | 'feedback' | 'sdkCreateButton',
@@ -28,11 +27,6 @@ export const routes: Record<
path: '/feedback',
Component: FeedbackRoute,
},
// sdkCreateButton: {
// name: 'sdkCreateButton',
// path: '/sdk/create-button',
// Component: SdkCreateButton,
// },
}
export type RouteName = keyof typeof routes
+33 -3
View File
@@ -1,11 +1,41 @@
import { VisioCreateButton } from "@gouvfr-lasuite/visio-sdk";
import "./App.css";
import { useState } from "react";
function App() {
const [roomUrl, setRoomUrl] = useState("");
return (
<div>
<VisioCreateButton />
</div>
<form className="form">
<div className="header">
<h2>Create event</h2>
<span>Visio demo app</span>
</div>
<div className="group">
<label>Subject</label>
<input type="text" />
</div>
<div className="group">
<label>Place</label>
<input type="text" />
</div>
<div className="group">
<label>Visioconference</label>
<VisioCreateButton onRoomCreated={setRoomUrl} />
</div>
<div className="group">
<label>Description</label>
<textarea />
</div>
<button
type="button"
onClick={() => {
alert("Room url: " + roomUrl);
}}
>
Create
</button>
</form>
);
}
+74
View File
@@ -0,0 +1,74 @@
* {
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
"Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
box-sizing: border-box;
color: rgb(9, 9, 11);
}
body {
background-color: oklch(0.985 0 0);
display: flex;
justify-content: center;
padding-top: 2rem;
}
h2 {
margin: 0;
}
span {
font-size: 14px;
color: oklch(0.372 0.044 257.287);
}
.form {
display: flex;
flex-direction: column;
width: 500px;
gap: 1rem;
border: 1px solid #e5e7eb;
background-color: white;
border-radius: 1rem;
padding: 3rem;
}
.header {
margin-bottom: 2rem;
}
.group {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0.5rem;
}
label {
color: rgb(9, 9, 11);
font-weight: 500;
font-size: 14px;
}
input,
textarea {
border: 1px rgb(228, 228, 231) solid;
border-radius: 6px;
height: 36px;
width: 100%;
padding: 0.75rem;
}
textarea {
height: 200px;
}
button {
background-color: rgb(45, 45, 70);
color: white;
height: 46px;
border-radius: 4px;
font-size: 16px;
font-weight: 300;
cursor: pointer;
}
@@ -2,9 +2,11 @@ import { DEFAULT_CONFIG } from "@/Config";
import { ClientMessageType } from "@/Types";
import { useEffect, useRef } from "react";
export const VisioCreateButton = () => {
const iframe = useRef<HTMLIFrameElement>(null);
export const VisioCreateButton = ({
onRoomCreated,
}: {
onRoomCreated: (roomUrl: string) => void;
}) => {
useEffect(() => {
window.onmessage = (event) => {
// TODO: Verify origin.
@@ -16,16 +18,20 @@ export const VisioCreateButton = () => {
if (event.data.type === ClientMessageType.ROOM_CREATED) {
console.log("event", event);
const data = event.data.data;
const roomUrl = data.url;
console.log("roomUrl", roomUrl);
onRoomCreated(roomUrl);
}
};
}, []);
return (
<iframe
allow="clipboard-read; clipboard-write"
src={DEFAULT_CONFIG.url + "/create-button"}
style={{
width: "100%",
height: "48px",
height: "52px",
border: "none",
}}
></iframe>