wip
This commit is contained in:
@@ -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.
|
||||
}
|
||||
}
|
||||
+26
-18
@@ -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>
|
||||
) : (
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user