mirror of
https://github.com/suitenumerique/meet.git
synced 2026-07-27 12:19:10 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6593e449e2 | |||
| de6b8e1e22 | |||
| 7ddf9070aa |
@@ -212,7 +212,7 @@ class LobbyService:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
utils.notify_participants(
|
utils.notify_participants(
|
||||||
room_name=str(room_id),
|
room_name=room_id,
|
||||||
notification_data={
|
notification_data={
|
||||||
"type": settings.LOBBY_NOTIFICATION_TYPE,
|
"type": settings.LOBBY_NOTIFICATION_TYPE,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -442,7 +442,7 @@ def test_enter_success(
|
|||||||
timeout=settings.LOBBY_WAITING_TIMEOUT,
|
timeout=settings.LOBBY_WAITING_TIMEOUT,
|
||||||
)
|
)
|
||||||
mock_notify.assert_called_once_with(
|
mock_notify.assert_called_once_with(
|
||||||
room_name=str(room.id), notification_data={"type": "participantWaiting"}
|
room_name=room.id, notification_data={"type": "participantWaiting"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "meet"
|
name = "meet"
|
||||||
version = "0.1.30"
|
version = "0.1.29"
|
||||||
authors = [{ "name" = "DINUM", "email" = "dev@mail.numerique.gouv.fr" }]
|
authors = [{ "name" = "DINUM", "email" = "dev@mail.numerique.gouv.fr" }]
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"Development Status :: 5 - Production/Stable",
|
"Development Status :: 5 - Production/Stable",
|
||||||
|
|||||||
Generated
+2
-54
@@ -1,19 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "meet",
|
"name": "meet",
|
||||||
"version": "0.1.30",
|
"version": "0.1.29",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "meet",
|
"name": "meet",
|
||||||
"version": "0.1.30",
|
"version": "0.1.29",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@livekit/components-react": "2.9.13",
|
"@livekit/components-react": "2.9.13",
|
||||||
"@livekit/components-styles": "1.1.6",
|
"@livekit/components-styles": "1.1.6",
|
||||||
"@livekit/track-processors": "0.5.7",
|
"@livekit/track-processors": "0.5.7",
|
||||||
"@pandacss/preset-panda": "0.54.0",
|
"@pandacss/preset-panda": "0.54.0",
|
||||||
"@react-aria/toast": "3.0.5",
|
"@react-aria/toast": "3.0.5",
|
||||||
"@react-hook/size": "2.1.2",
|
|
||||||
"@remixicon/react": "4.6.0",
|
"@remixicon/react": "4.6.0",
|
||||||
"@tanstack/react-query": "5.81.5",
|
"@tanstack/react-query": "5.81.5",
|
||||||
"@timephy/rnnoise-wasm": "1.0.0",
|
"@timephy/rnnoise-wasm": "1.0.0",
|
||||||
@@ -1211,12 +1210,6 @@
|
|||||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@juggle/resize-observer": {
|
|
||||||
"version": "3.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz",
|
|
||||||
"integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==",
|
|
||||||
"license": "Apache-2.0"
|
|
||||||
},
|
|
||||||
"node_modules/@livekit/components-core": {
|
"node_modules/@livekit/components-core": {
|
||||||
"version": "0.12.8",
|
"version": "0.12.8",
|
||||||
"resolved": "https://registry.npmjs.org/@livekit/components-core/-/components-core-0.12.8.tgz",
|
"resolved": "https://registry.npmjs.org/@livekit/components-core/-/components-core-0.12.8.tgz",
|
||||||
@@ -2708,51 +2701,6 @@
|
|||||||
"react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
|
"react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-hook/latest": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-hook/latest/-/latest-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-dy6duzl+JnAZcDbNTfmaP3xHiKtbXYOaz3G51MGVljh548Y8MWzTr+PHLOfvpypEVW9zwvl+VyKjbWKEVbV1Rg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": ">=16.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-hook/passive-layout-effect": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-hook/passive-layout-effect/-/passive-layout-effect-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-IwEphTD75liO8g+6taS+4oqz+nnroocNfWVHWz7j+N+ZO2vYrc6PV1q7GQhuahL0IOR7JccFTsFKQ/mb6iZWAg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": ">=16.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-hook/resize-observer": {
|
|
||||||
"version": "1.2.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-hook/resize-observer/-/resize-observer-1.2.6.tgz",
|
|
||||||
"integrity": "sha512-DlBXtLSW0DqYYTW3Ft1/GQFZlTdKY5VAFIC4+km6IK5NiPPDFchGbEJm1j6pSgMqPRHbUQgHJX7RaR76ic1LWA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@juggle/resize-observer": "^3.3.1",
|
|
||||||
"@react-hook/latest": "^1.0.2",
|
|
||||||
"@react-hook/passive-layout-effect": "^1.2.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": ">=16.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-hook/size": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-hook/size/-/size-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-BmE5asyRDxSuQ9p14FUKJ0iBRgV9cROjqNG9jT/EjCM+xHha1HVqbPoT+14FQg1K7xIydabClCibUY4+1tw/iw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@react-hook/passive-layout-effect": "^1.2.0",
|
|
||||||
"@react-hook/resize-observer": "^1.2.1"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": ">=16.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-stately/autocomplete": {
|
"node_modules/@react-stately/autocomplete": {
|
||||||
"version": "3.0.0-beta.2",
|
"version": "3.0.0-beta.2",
|
||||||
"resolved": "https://registry.npmjs.org/@react-stately/autocomplete/-/autocomplete-3.0.0-beta.2.tgz",
|
"resolved": "https://registry.npmjs.org/@react-stately/autocomplete/-/autocomplete-3.0.0-beta.2.tgz",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "meet",
|
"name": "meet",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.1.30",
|
"version": "0.1.29",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "panda codegen && vite",
|
"dev": "panda codegen && vite",
|
||||||
@@ -18,7 +18,6 @@
|
|||||||
"@livekit/track-processors": "0.5.7",
|
"@livekit/track-processors": "0.5.7",
|
||||||
"@pandacss/preset-panda": "0.54.0",
|
"@pandacss/preset-panda": "0.54.0",
|
||||||
"@react-aria/toast": "3.0.5",
|
"@react-aria/toast": "3.0.5",
|
||||||
"@react-hook/size": "2.1.2",
|
|
||||||
"@remixicon/react": "4.6.0",
|
"@remixicon/react": "4.6.0",
|
||||||
"@tanstack/react-query": "5.81.5",
|
"@tanstack/react-query": "5.81.5",
|
||||||
"@timephy/rnnoise-wasm": "1.0.0",
|
"@timephy/rnnoise-wasm": "1.0.0",
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ import {
|
|||||||
MediaDeviceFailure,
|
MediaDeviceFailure,
|
||||||
Room,
|
Room,
|
||||||
RoomOptions,
|
RoomOptions,
|
||||||
supportsAdaptiveStream,
|
|
||||||
supportsDynacast,
|
|
||||||
} from 'livekit-client'
|
} from 'livekit-client'
|
||||||
import { keys } from '@/api/queryKeys'
|
import { keys } from '@/api/queryKeys'
|
||||||
import { queryClient } from '@/api/queryClient'
|
import { queryClient } from '@/api/queryClient'
|
||||||
@@ -76,8 +74,8 @@ export const Conference = ({
|
|||||||
|
|
||||||
const roomOptions = useMemo((): RoomOptions => {
|
const roomOptions = useMemo((): RoomOptions => {
|
||||||
return {
|
return {
|
||||||
adaptiveStream: supportsAdaptiveStream(),
|
adaptiveStream: true,
|
||||||
dynacast: supportsDynacast(),
|
dynacast: true,
|
||||||
publishDefaults: {
|
publishDefaults: {
|
||||||
videoCodec: 'vp9',
|
videoCodec: 'vp9',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import { useMemo, useRef } from 'react'
|
|||||||
import { ScreenSharePreferenceStore } from '@/stores/ScreenSharePreferences'
|
import { ScreenSharePreferenceStore } from '@/stores/ScreenSharePreferences'
|
||||||
import { useSnapshot } from 'valtio'
|
import { useSnapshot } from 'valtio'
|
||||||
import { useLocalParticipant } from '@livekit/components-react'
|
import { useLocalParticipant } from '@livekit/components-react'
|
||||||
|
import { useSize } from '../hooks/useResizeObserver'
|
||||||
import { TrackReferenceOrPlaceholder } from '@livekit/components-core'
|
import { TrackReferenceOrPlaceholder } from '@livekit/components-core'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useSize from '@react-hook/size'
|
|
||||||
|
|
||||||
export const FullScreenShareWarning = ({
|
export const FullScreenShareWarning = ({
|
||||||
trackReference,
|
trackReference,
|
||||||
@@ -16,7 +16,7 @@ export const FullScreenShareWarning = ({
|
|||||||
const { t } = useTranslation('rooms', { keyPrefix: 'fullScreenWarning' })
|
const { t } = useTranslation('rooms', { keyPrefix: 'fullScreenWarning' })
|
||||||
|
|
||||||
const warningContainerRef = useRef<HTMLDivElement>(null)
|
const warningContainerRef = useRef<HTMLDivElement>(null)
|
||||||
const containerWidth = useSize(warningContainerRef)[0]
|
const { width: containerWidth } = useSize(warningContainerRef)
|
||||||
const { localParticipant } = useLocalParticipant()
|
const { localParticipant } = useLocalParticipant()
|
||||||
const screenSharePreferences = useSnapshot(ScreenSharePreferenceStore)
|
const screenSharePreferences = useSnapshot(ScreenSharePreferenceStore)
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import { styled } from '@/styled-system/jsx'
|
|||||||
import { Avatar } from '@/components/Avatar'
|
import { Avatar } from '@/components/Avatar'
|
||||||
import { useIsSpeaking } from '@livekit/components-react'
|
import { useIsSpeaking } from '@livekit/components-react'
|
||||||
import { getParticipantColor } from '@/features/rooms/utils/getParticipantColor'
|
import { getParticipantColor } from '@/features/rooms/utils/getParticipantColor'
|
||||||
|
import { useSize } from '@/features/rooms/livekit/hooks/useResizeObserver'
|
||||||
import { useMemo, useRef } from 'react'
|
import { useMemo, useRef } from 'react'
|
||||||
import useSize from '@react-hook/size'
|
|
||||||
|
|
||||||
const StyledParticipantPlaceHolder = styled('div', {
|
const StyledParticipantPlaceHolder = styled('div', {
|
||||||
base: {
|
base: {
|
||||||
@@ -28,7 +28,7 @@ export const ParticipantPlaceholder = ({
|
|||||||
const participantColor = getParticipantColor(participant)
|
const participantColor = getParticipantColor(participant)
|
||||||
|
|
||||||
const placeholderEl = useRef<HTMLDivElement>(null)
|
const placeholderEl = useRef<HTMLDivElement>(null)
|
||||||
const [width, height] = useSize(placeholderEl)
|
const { width, height } = useSize(placeholderEl)
|
||||||
|
|
||||||
const minDimension = Math.min(width, height)
|
const minDimension = Math.min(width, height)
|
||||||
const avatarSize = useMemo(
|
const avatarSize = useMemo(
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
import * as React from 'react'
|
|
||||||
import { createInteractingObservable } from '@livekit/components-core'
|
|
||||||
import { usePagination } from '@livekit/components-react'
|
|
||||||
import { RiArrowLeftSLine, RiArrowRightSLine } from '@remixicon/react'
|
|
||||||
|
|
||||||
export interface PaginationControlProps
|
|
||||||
extends Pick<
|
|
||||||
ReturnType<typeof usePagination>,
|
|
||||||
'totalPageCount' | 'nextPage' | 'prevPage' | 'currentPage'
|
|
||||||
> {
|
|
||||||
/** Reference to an HTML element that holds the pages, while interacting (`mouseover`)
|
|
||||||
* with it, the pagination controls will appear for a while. */
|
|
||||||
pagesContainer?: React.RefObject<HTMLElement>
|
|
||||||
}
|
|
||||||
|
|
||||||
export function PaginationControl({
|
|
||||||
totalPageCount,
|
|
||||||
nextPage,
|
|
||||||
prevPage,
|
|
||||||
currentPage,
|
|
||||||
pagesContainer: connectedElement,
|
|
||||||
}: PaginationControlProps) {
|
|
||||||
const [interactive, setInteractive] = React.useState(false)
|
|
||||||
React.useEffect(() => {
|
|
||||||
let subscription:
|
|
||||||
| ReturnType<ReturnType<typeof createInteractingObservable>['subscribe']>
|
|
||||||
| undefined
|
|
||||||
if (connectedElement) {
|
|
||||||
subscription = createInteractingObservable(
|
|
||||||
connectedElement.current,
|
|
||||||
2000
|
|
||||||
).subscribe(setInteractive)
|
|
||||||
}
|
|
||||||
return () => {
|
|
||||||
if (subscription) {
|
|
||||||
subscription.unsubscribe()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [connectedElement])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="lk-pagination-control"
|
|
||||||
data-lk-user-interaction={interactive}
|
|
||||||
>
|
|
||||||
<button className="lk-button" onClick={prevPage}>
|
|
||||||
<RiArrowLeftSLine />
|
|
||||||
</button>
|
|
||||||
<span className="lk-pagination-count">{`${currentPage} of ${totalPageCount}`}</span>
|
|
||||||
<button className="lk-button" onClick={nextPage}>
|
|
||||||
<RiArrowRightSLine />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
import * as React from 'react'
|
|
||||||
|
|
||||||
export interface PaginationIndicatorProps {
|
|
||||||
totalPageCount: number
|
|
||||||
currentPage: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export const PaginationIndicator: (
|
|
||||||
props: PaginationIndicatorProps & React.RefAttributes<HTMLDivElement>
|
|
||||||
) => React.ReactNode = /* @__PURE__ */ React.forwardRef<
|
|
||||||
HTMLDivElement,
|
|
||||||
PaginationIndicatorProps
|
|
||||||
>(function PaginationIndicator(
|
|
||||||
{ totalPageCount, currentPage }: PaginationIndicatorProps,
|
|
||||||
ref
|
|
||||||
) {
|
|
||||||
const bubbles = new Array(totalPageCount).fill('').map((_, index) => {
|
|
||||||
if (index + 1 === currentPage) {
|
|
||||||
return <span data-lk-active key={index} />
|
|
||||||
} else {
|
|
||||||
return <span key={index} />
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div ref={ref} className="lk-pagination-indicator">
|
|
||||||
{bubbles}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
import type { TrackReferenceOrPlaceholder } from '@livekit/components-core'
|
|
||||||
import { getScrollBarWidth } from '@livekit/components-core'
|
|
||||||
import * as React from 'react'
|
|
||||||
import { TrackLoop, useVisualStableUpdate } from '@livekit/components-react'
|
|
||||||
import useSize from '@react-hook/size'
|
|
||||||
|
|
||||||
const MIN_HEIGHT = 130
|
|
||||||
const MIN_WIDTH = 140
|
|
||||||
const MIN_VISIBLE_TILES = 1
|
|
||||||
const ASPECT_RATIO = 16 / 10
|
|
||||||
const ASPECT_RATIO_INVERT = (1 - ASPECT_RATIO) * -1
|
|
||||||
|
|
||||||
/** @public */
|
|
||||||
export interface CarouselLayoutProps
|
|
||||||
extends React.HTMLAttributes<HTMLMediaElement> {
|
|
||||||
tracks: TrackReferenceOrPlaceholder[]
|
|
||||||
children: React.ReactNode
|
|
||||||
/** Place the tiles vertically or horizontally next to each other.
|
|
||||||
* If undefined orientation is guessed by the dimensions of the container. */
|
|
||||||
orientation?: 'vertical' | 'horizontal'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `CarouselLayout` component displays a list of tracks in a scroll container.
|
|
||||||
* It will display as many tiles as possible and overflow the rest.
|
|
||||||
* @remarks
|
|
||||||
* To ensure visual stability when tiles are reordered due to track updates,
|
|
||||||
* the component uses the `useVisualStableUpdate` hook.
|
|
||||||
* @example
|
|
||||||
* ```tsx
|
|
||||||
* const tracks = useTracks([Track.Source.Camera]);
|
|
||||||
* <CarouselLayout tracks={tracks}>
|
|
||||||
* <ParticipantTile />
|
|
||||||
* </CarouselLayout>
|
|
||||||
* ```
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
export function CarouselLayout({
|
|
||||||
tracks,
|
|
||||||
orientation,
|
|
||||||
...props
|
|
||||||
}: CarouselLayoutProps) {
|
|
||||||
const asideEl = React.useRef<HTMLDivElement>(null)
|
|
||||||
const [prevTiles, setPrevTiles] = React.useState(0)
|
|
||||||
const [width, height] = useSize(asideEl)
|
|
||||||
const carouselOrientation = orientation
|
|
||||||
? orientation
|
|
||||||
: height >= width
|
|
||||||
? 'vertical'
|
|
||||||
: 'horizontal'
|
|
||||||
|
|
||||||
const tileSpan =
|
|
||||||
carouselOrientation === 'vertical'
|
|
||||||
? Math.max(width * ASPECT_RATIO_INVERT, MIN_HEIGHT)
|
|
||||||
: Math.max(height * ASPECT_RATIO, MIN_WIDTH)
|
|
||||||
const scrollBarWidth = getScrollBarWidth()
|
|
||||||
|
|
||||||
const tilesThatFit =
|
|
||||||
carouselOrientation === 'vertical'
|
|
||||||
? Math.max((height - scrollBarWidth) / tileSpan, MIN_VISIBLE_TILES)
|
|
||||||
: Math.max((width - scrollBarWidth) / tileSpan, MIN_VISIBLE_TILES)
|
|
||||||
|
|
||||||
let maxVisibleTiles = Math.round(tilesThatFit)
|
|
||||||
if (Math.abs(tilesThatFit - prevTiles) < 0.5) {
|
|
||||||
maxVisibleTiles = Math.round(prevTiles)
|
|
||||||
} else if (prevTiles !== tilesThatFit) {
|
|
||||||
setPrevTiles(tilesThatFit)
|
|
||||||
}
|
|
||||||
|
|
||||||
const sortedTiles = useVisualStableUpdate(tracks, maxVisibleTiles)
|
|
||||||
|
|
||||||
React.useLayoutEffect(() => {
|
|
||||||
if (asideEl.current) {
|
|
||||||
asideEl.current.dataset.lkOrientation = carouselOrientation
|
|
||||||
asideEl.current.style.setProperty(
|
|
||||||
'--lk-max-visible-tiles',
|
|
||||||
maxVisibleTiles.toString()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}, [maxVisibleTiles, carouselOrientation])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<aside
|
|
||||||
key={carouselOrientation}
|
|
||||||
className="lk-carousel"
|
|
||||||
ref={asideEl}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
<TrackLoop tracks={sortedTiles}>{props.children}</TrackLoop>
|
|
||||||
</aside>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
import * as React from 'react'
|
|
||||||
import type { TrackReferenceOrPlaceholder } from '@livekit/components-core'
|
|
||||||
import {
|
|
||||||
TrackLoop,
|
|
||||||
usePagination,
|
|
||||||
UseParticipantsOptions,
|
|
||||||
useSwipe,
|
|
||||||
} from '@livekit/components-react'
|
|
||||||
import { mergeProps } from '@/utils/mergeProps'
|
|
||||||
import { PaginationIndicator } from '../controls/PaginationIndicator'
|
|
||||||
import { useGridLayout } from '../../hooks/useGridLayout'
|
|
||||||
import { PaginationControl } from '../controls/PaginationControl'
|
|
||||||
|
|
||||||
/** @public */
|
|
||||||
export interface GridLayoutProps
|
|
||||||
extends React.HTMLAttributes<HTMLDivElement>,
|
|
||||||
Pick<UseParticipantsOptions, 'updateOnlyOn'> {
|
|
||||||
children: React.ReactNode
|
|
||||||
tracks: TrackReferenceOrPlaceholder[]
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `GridLayout` component displays the nested participants in a grid where every participants has the same size.
|
|
||||||
* It also supports pagination if there are more participants than the grid can display.
|
|
||||||
* @remarks
|
|
||||||
* To ensure visual stability when tiles are reordered due to track updates,
|
|
||||||
* the component uses the `useVisualStableUpdate` hook.
|
|
||||||
* @example
|
|
||||||
* ```tsx
|
|
||||||
* <LiveKitRoom>
|
|
||||||
* <GridLayout tracks={tracks}>
|
|
||||||
* <ParticipantTile />
|
|
||||||
* </GridLayout>
|
|
||||||
* <LiveKitRoom>
|
|
||||||
* ```
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
export function GridLayout({ tracks, ...props }: GridLayoutProps) {
|
|
||||||
const gridEl = React.createRef<HTMLDivElement>()
|
|
||||||
|
|
||||||
const elementProps = React.useMemo(
|
|
||||||
() => mergeProps(props, { className: 'lk-grid-layout' }),
|
|
||||||
[props]
|
|
||||||
)
|
|
||||||
const { layout } = useGridLayout(gridEl, tracks.length)
|
|
||||||
const pagination = usePagination(layout.maxTiles, tracks)
|
|
||||||
|
|
||||||
useSwipe(gridEl, {
|
|
||||||
onLeftSwipe: pagination.nextPage,
|
|
||||||
onRightSwipe: pagination.prevPage,
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
ref={gridEl}
|
|
||||||
data-lk-pagination={pagination.totalPageCount > 1}
|
|
||||||
{...elementProps}
|
|
||||||
>
|
|
||||||
<TrackLoop tracks={pagination.tracks}>{props.children}</TrackLoop>
|
|
||||||
{tracks.length > layout.maxTiles && (
|
|
||||||
<>
|
|
||||||
<PaginationIndicator
|
|
||||||
totalPageCount={pagination.totalPageCount}
|
|
||||||
currentPage={pagination.currentPage}
|
|
||||||
/>
|
|
||||||
<PaginationControl pagesContainer={gridEl} {...pagination} />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
import { GRID_LAYOUTS, selectGridLayout } from '@livekit/components-core'
|
|
||||||
import type {
|
|
||||||
GridLayoutDefinition,
|
|
||||||
GridLayoutInfo,
|
|
||||||
} from '@livekit/components-core'
|
|
||||||
import * as React from 'react'
|
|
||||||
import useSize from '@react-hook/size'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `useGridLayout` hook tries to select the best layout to fit all tiles.
|
|
||||||
* If the available screen space is not enough, it will reduce the number of maximum visible
|
|
||||||
* tiles and select a layout that still works visually within the given limitations.
|
|
||||||
* As the order of tiles changes over time, the hook tries to keep visual updates to a minimum
|
|
||||||
* while trying to display important tiles such as speaking participants or screen shares.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```tsx
|
|
||||||
* const { layout } = useGridLayout(gridElement, trackCount);
|
|
||||||
* ```
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
export function useGridLayout(
|
|
||||||
/** HTML element that contains the grid. */
|
|
||||||
gridElement: React.RefObject<HTMLDivElement>,
|
|
||||||
/** Count of tracks that should get layed out */
|
|
||||||
trackCount: number,
|
|
||||||
options: {
|
|
||||||
gridLayouts?: GridLayoutDefinition[]
|
|
||||||
} = {}
|
|
||||||
): { layout: GridLayoutInfo; containerWidth: number; containerHeight: number } {
|
|
||||||
const gridLayouts = options.gridLayouts ?? GRID_LAYOUTS
|
|
||||||
const [width, height] = useSize(gridElement)
|
|
||||||
const layout = selectGridLayout(gridLayouts, trackCount, width, height)
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (gridElement.current && layout) {
|
|
||||||
gridElement.current.style.setProperty(
|
|
||||||
'--lk-col-count',
|
|
||||||
layout?.columns.toString()
|
|
||||||
)
|
|
||||||
gridElement.current.style.setProperty(
|
|
||||||
'--lk-row-count',
|
|
||||||
layout?.rows.toString()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}, [gridElement, layout])
|
|
||||||
|
|
||||||
return {
|
|
||||||
layout,
|
|
||||||
containerWidth: width,
|
|
||||||
containerHeight: height,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import * as React from 'react'
|
||||||
|
|
||||||
|
const useLatest = <T>(current: T) => {
|
||||||
|
const storedValue = React.useRef(current)
|
||||||
|
React.useEffect(() => {
|
||||||
|
storedValue.current = current
|
||||||
|
})
|
||||||
|
return storedValue
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A React hook that fires a callback whenever ResizeObserver detects a change to its size
|
||||||
|
* code extracted from https://github.com/jaredLunde/react-hook/blob/master/packages/resize-observer/src/index.tsx in order to not include the polyfill for resize-observer
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export function useResizeObserver<T extends HTMLElement>(
|
||||||
|
target: React.RefObject<T>,
|
||||||
|
callback: UseResizeObserverCallback
|
||||||
|
) {
|
||||||
|
const resizeObserver = getResizeObserver()
|
||||||
|
const storedCallback = useLatest(callback)
|
||||||
|
|
||||||
|
React.useLayoutEffect(() => {
|
||||||
|
let didUnsubscribe = false
|
||||||
|
|
||||||
|
const targetEl = target.current
|
||||||
|
if (!targetEl) return
|
||||||
|
|
||||||
|
function cb(entry: ResizeObserverEntry, observer: ResizeObserver) {
|
||||||
|
if (didUnsubscribe) return
|
||||||
|
storedCallback.current(entry, observer)
|
||||||
|
}
|
||||||
|
|
||||||
|
resizeObserver?.subscribe(targetEl as HTMLElement, cb)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
didUnsubscribe = true
|
||||||
|
resizeObserver?.unsubscribe(targetEl as HTMLElement, cb)
|
||||||
|
}
|
||||||
|
}, [target.current, resizeObserver, storedCallback])
|
||||||
|
|
||||||
|
return resizeObserver?.observer
|
||||||
|
}
|
||||||
|
|
||||||
|
function createResizeObserver() {
|
||||||
|
let ticking = false
|
||||||
|
let allEntries: ResizeObserverEntry[] = []
|
||||||
|
|
||||||
|
const callbacks: Map<unknown, Array<UseResizeObserverCallback>> = new Map()
|
||||||
|
|
||||||
|
if (typeof window === 'undefined') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const observer = new ResizeObserver(
|
||||||
|
(entries: ResizeObserverEntry[], obs: ResizeObserver) => {
|
||||||
|
allEntries = allEntries.concat(entries)
|
||||||
|
if (!ticking) {
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
const triggered = new Set<Element>()
|
||||||
|
for (let i = 0; i < allEntries.length; i++) {
|
||||||
|
if (triggered.has(allEntries[i].target)) continue
|
||||||
|
triggered.add(allEntries[i].target)
|
||||||
|
const cbs = callbacks.get(allEntries[i].target)
|
||||||
|
cbs?.forEach((cb) => cb(allEntries[i], obs))
|
||||||
|
}
|
||||||
|
allEntries = []
|
||||||
|
ticking = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
ticking = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
observer,
|
||||||
|
subscribe(target: HTMLElement, callback: UseResizeObserverCallback) {
|
||||||
|
observer.observe(target)
|
||||||
|
const cbs = callbacks.get(target) ?? []
|
||||||
|
cbs.push(callback)
|
||||||
|
callbacks.set(target, cbs)
|
||||||
|
},
|
||||||
|
unsubscribe(target: HTMLElement, callback: UseResizeObserverCallback) {
|
||||||
|
const cbs = callbacks.get(target) ?? []
|
||||||
|
if (cbs.length === 1) {
|
||||||
|
observer.unobserve(target)
|
||||||
|
callbacks.delete(target)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const cbIndex = cbs.indexOf(callback)
|
||||||
|
if (cbIndex !== -1) cbs.splice(cbIndex, 1)
|
||||||
|
callbacks.set(target, cbs)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let _resizeObserver: ReturnType<typeof createResizeObserver>
|
||||||
|
|
||||||
|
const getResizeObserver = () =>
|
||||||
|
!_resizeObserver
|
||||||
|
? (_resizeObserver = createResizeObserver())
|
||||||
|
: _resizeObserver
|
||||||
|
|
||||||
|
export type UseResizeObserverCallback = (
|
||||||
|
entry: ResizeObserverEntry,
|
||||||
|
observer: ResizeObserver
|
||||||
|
) => unknown
|
||||||
|
|
||||||
|
export const useSize = (target: React.RefObject<HTMLDivElement>) => {
|
||||||
|
const [size, setSize] = React.useState({ width: 0, height: 0 })
|
||||||
|
React.useLayoutEffect(() => {
|
||||||
|
if (target.current) {
|
||||||
|
const { width, height } = target.current.getBoundingClientRect()
|
||||||
|
setSize({ width, height })
|
||||||
|
}
|
||||||
|
}, [target.current])
|
||||||
|
|
||||||
|
const resizeCallback = React.useCallback(
|
||||||
|
(entry: ResizeObserverEntry) => setSize(entry.contentRect),
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
// Where the magic happens
|
||||||
|
useResizeObserver(target, resizeCallback)
|
||||||
|
return size
|
||||||
|
}
|
||||||
@@ -4,13 +4,13 @@ import { ParticipantsToggle } from '../../components/controls/Participants/Parti
|
|||||||
import { ToolsToggle } from '../../components/controls/ToolsToggle'
|
import { ToolsToggle } from '../../components/controls/ToolsToggle'
|
||||||
import { InfoToggle } from '../../components/controls/InfoToggle'
|
import { InfoToggle } from '../../components/controls/InfoToggle'
|
||||||
import { AdminToggle } from '../../components/AdminToggle'
|
import { AdminToggle } from '../../components/AdminToggle'
|
||||||
|
import { useSize } from '../../hooks/useResizeObserver'
|
||||||
import { useState, RefObject } from 'react'
|
import { useState, RefObject } from 'react'
|
||||||
import { Dialog, DialogTrigger, Popover } from 'react-aria-components'
|
import { Dialog, DialogTrigger, Popover } from 'react-aria-components'
|
||||||
import { Button } from '@/primitives'
|
import { Button } from '@/primitives'
|
||||||
import { ToggleButtonProps } from '@/primitives/ToggleButton'
|
import { ToggleButtonProps } from '@/primitives/ToggleButton'
|
||||||
import { RiArrowDownSLine, RiArrowUpSLine } from '@remixicon/react'
|
import { RiArrowDownSLine, RiArrowUpSLine } from '@remixicon/react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useSize from '@react-hook/size'
|
|
||||||
|
|
||||||
const CONTROL_BAR_BREAKPOINT = 1100
|
const CONTROL_BAR_BREAKPOINT = 1100
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ export const MoreOptions = ({
|
|||||||
}: {
|
}: {
|
||||||
parentElement: RefObject<HTMLDivElement>
|
parentElement: RefObject<HTMLDivElement>
|
||||||
}) => {
|
}) => {
|
||||||
const parentWidth = useSize(parentElement)[0]
|
const { width: parentWidth } = useSize(parentElement)
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={css({
|
className={css({
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { RoomEvent, Track } from 'livekit-client'
|
|||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import {
|
import {
|
||||||
|
CarouselLayout,
|
||||||
ConnectionStateToast,
|
ConnectionStateToast,
|
||||||
FocusLayoutContainer,
|
FocusLayoutContainer,
|
||||||
GridLayout,
|
GridLayout,
|
||||||
@@ -31,7 +32,6 @@ import { RecordingStateToast } from '@/features/recording'
|
|||||||
import { ScreenShareErrorModal } from '../components/ScreenShareErrorModal'
|
import { ScreenShareErrorModal } from '../components/ScreenShareErrorModal'
|
||||||
import { useConnectionObserver } from '../hooks/useConnectionObserver'
|
import { useConnectionObserver } from '../hooks/useConnectionObserver'
|
||||||
import { useNoiseReduction } from '../hooks/useNoiseReduction'
|
import { useNoiseReduction } from '../hooks/useNoiseReduction'
|
||||||
import { CarouselLayout } from '../components/layout/CarouselLayout'
|
|
||||||
|
|
||||||
const LayoutWrapper = styled(
|
const LayoutWrapper = styled(
|
||||||
'div',
|
'div',
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import { AccountTab } from './tabs/AccountTab'
|
|||||||
import { NotificationsTab } from './tabs/NotificationsTab'
|
import { NotificationsTab } from './tabs/NotificationsTab'
|
||||||
import { GeneralTab } from './tabs/GeneralTab'
|
import { GeneralTab } from './tabs/GeneralTab'
|
||||||
import { AudioTab } from './tabs/AudioTab'
|
import { AudioTab } from './tabs/AudioTab'
|
||||||
|
import { useSize } from '@/features/rooms/livekit/hooks/useResizeObserver'
|
||||||
import { useRef } from 'react'
|
import { useRef } from 'react'
|
||||||
import { useMediaQuery } from '@/features/rooms/livekit/hooks/useMediaQuery'
|
|
||||||
|
|
||||||
const tabsStyle = css({
|
const tabsStyle = css({
|
||||||
maxHeight: '40.625rem', // fixme size copied from meet settings modal
|
maxHeight: '40.625rem', // fixme size copied from meet settings modal
|
||||||
@@ -51,7 +51,8 @@ export const SettingsDialogExtended = (props: SettingsDialogExtended) => {
|
|||||||
const { t } = useTranslation('settings')
|
const { t } = useTranslation('settings')
|
||||||
|
|
||||||
const dialogEl = useRef<HTMLDivElement>(null)
|
const dialogEl = useRef<HTMLDivElement>(null)
|
||||||
const isWideScreen = useMediaQuery('(min-width: 800px)') // fixme - hardcoded 50rem in pixel
|
const { width } = useSize(dialogEl)
|
||||||
|
const isWideScreen = !width || width >= 800 // fixme - hardcoded 50rem in pixel
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog innerRef={dialogEl} {...props} role="dialog" type="flex">
|
<Dialog innerRef={dialogEl} {...props} role="dialog" type="flex">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { DialogProps, Field, H, Switch, Text } from '@/primitives'
|
import { DialogProps, Field, H, Switch } from '@/primitives'
|
||||||
|
|
||||||
import { TabPanel, TabPanelProps } from '@/primitives/Tabs'
|
import { TabPanel, TabPanelProps } from '@/primitives/Tabs'
|
||||||
import {
|
import {
|
||||||
@@ -174,7 +174,7 @@ export const AudioTab = ({ id }: AudioTabProps) => {
|
|||||||
</RowWrapper>
|
</RowWrapper>
|
||||||
{/* Safari has a known limitation where its implementation of 'enumerateDevices' does not include audio output devices.
|
{/* Safari has a known limitation where its implementation of 'enumerateDevices' does not include audio output devices.
|
||||||
To prevent errors or an empty selection list, we only render the speakers selection field on non-Safari browsers. */}
|
To prevent errors or an empty selection list, we only render the speakers selection field on non-Safari browsers. */}
|
||||||
{!isSafari() ? (
|
{!isSafari() && (
|
||||||
<RowWrapper heading={t('audio.speakers.heading')}>
|
<RowWrapper heading={t('audio.speakers.heading')}>
|
||||||
<Field
|
<Field
|
||||||
type="select"
|
type="select"
|
||||||
@@ -193,13 +193,6 @@ export const AudioTab = ({ id }: AudioTabProps) => {
|
|||||||
/>
|
/>
|
||||||
<SoundTester />
|
<SoundTester />
|
||||||
</RowWrapper>
|
</RowWrapper>
|
||||||
) : (
|
|
||||||
<RowWrapper heading={t('audio.speakers.heading')}>
|
|
||||||
<Text variant="warning" margin="md">
|
|
||||||
{t('audio.speakers.safariWarning')}
|
|
||||||
</Text>
|
|
||||||
<div />
|
|
||||||
</RowWrapper>
|
|
||||||
)}
|
)}
|
||||||
{noiseReductionAvailable && (
|
{noiseReductionAvailable && (
|
||||||
<RowWrapper heading={t('audio.noiseReduction.heading')} beta>
|
<RowWrapper heading={t('audio.noiseReduction.heading')} beta>
|
||||||
|
|||||||
@@ -25,8 +25,7 @@
|
|||||||
"heading": "Lautsprecher",
|
"heading": "Lautsprecher",
|
||||||
"label": "Wählen Sie Ihre Audioausgabe",
|
"label": "Wählen Sie Ihre Audioausgabe",
|
||||||
"test": "Testen",
|
"test": "Testen",
|
||||||
"ongoingTest": "Soundtest läuft…",
|
"ongoingTest": "Soundtest läuft…"
|
||||||
"safariWarning": "Die Lautsprecherauswahl ist auf Safari aufgrund von Browser-Einschränkungen noch nicht verfügbar."
|
|
||||||
},
|
},
|
||||||
"permissionsRequired": "Berechtigungen erforderlich"
|
"permissionsRequired": "Berechtigungen erforderlich"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -25,8 +25,7 @@
|
|||||||
"heading": "Speakers",
|
"heading": "Speakers",
|
||||||
"label": "Select your audio output",
|
"label": "Select your audio output",
|
||||||
"test": "Test",
|
"test": "Test",
|
||||||
"ongoingTest": "Testing sound…",
|
"ongoingTest": "Testing sound…"
|
||||||
"safariWarning": "Speaker selection is not available yet on Safari due to browser limitations."
|
|
||||||
},
|
},
|
||||||
"permissionsRequired": "Permissions required"
|
"permissionsRequired": "Permissions required"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -25,8 +25,7 @@
|
|||||||
"heading": "Haut-parleurs",
|
"heading": "Haut-parleurs",
|
||||||
"label": "Sélectionner votre sortie audio",
|
"label": "Sélectionner votre sortie audio",
|
||||||
"test": "Tester",
|
"test": "Tester",
|
||||||
"ongoingTest": "Test du son…",
|
"ongoingTest": "Test du son…"
|
||||||
"safariWarning": "La sélection du haut-parleur n'est pas encore disponible sur Safari en raison de limitations du navigateur."
|
|
||||||
},
|
},
|
||||||
"permissionsRequired": "Autorisations nécessaires"
|
"permissionsRequired": "Autorisations nécessaires"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -25,8 +25,7 @@
|
|||||||
"heading": "Luidsprekers",
|
"heading": "Luidsprekers",
|
||||||
"label": "Selecteer uw audio-uitvoer",
|
"label": "Selecteer uw audio-uitvoer",
|
||||||
"test": "Test",
|
"test": "Test",
|
||||||
"ongoingTest": "Testgeluid ...",
|
"ongoingTest": "Testgeluid ..."
|
||||||
"safariWarning": "Luidsprekerselectie is nog niet beschikbaar op Safari vanwege browserbeperkingen."
|
|
||||||
},
|
},
|
||||||
"permissionsRequired": "Machtigingen vereist"
|
"permissionsRequired": "Machtigingen vereist"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -53,9 +53,6 @@ export const text = cva({
|
|||||||
note: {
|
note: {
|
||||||
color: 'default.subtle-text',
|
color: 'default.subtle-text',
|
||||||
},
|
},
|
||||||
warning: {
|
|
||||||
color: 'danger.subtle-text',
|
|
||||||
},
|
|
||||||
smNote: {
|
smNote: {
|
||||||
color: 'default.subtle-text',
|
color: 'default.subtle-text',
|
||||||
textStyle: 'sm',
|
textStyle: 'sm',
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "mail_mjml",
|
"name": "mail_mjml",
|
||||||
"version": "0.1.30",
|
"version": "0.1.29",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "mail_mjml",
|
"name": "mail_mjml",
|
||||||
"version": "0.1.30",
|
"version": "0.1.29",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@html-to/text-cli": "0.5.4",
|
"@html-to/text-cli": "0.5.4",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mail_mjml",
|
"name": "mail_mjml",
|
||||||
"version": "0.1.30",
|
"version": "0.1.29",
|
||||||
"description": "An util to generate html and text django's templates from mjml templates",
|
"description": "An util to generate html and text django's templates from mjml templates",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "sdk",
|
"name": "sdk",
|
||||||
"version": "0.1.30",
|
"version": "0.1.29",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "sdk",
|
"name": "sdk",
|
||||||
"version": "0.1.30",
|
"version": "0.1.29",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"./library",
|
"./library",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sdk",
|
"name": "sdk",
|
||||||
"version": "0.1.30",
|
"version": "0.1.29",
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"description": "",
|
"description": "",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "summary"
|
name = "summary"
|
||||||
version = "0.1.30"
|
version = "0.1.29"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fastapi[standard]>=0.105.0",
|
"fastapi[standard]>=0.105.0",
|
||||||
"uvicorn>=0.24.0",
|
"uvicorn>=0.24.0",
|
||||||
|
|||||||
@@ -107,13 +107,12 @@ class MetadataManager:
|
|||||||
"retries": 0,
|
"retries": 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
_required_args_count = 7
|
_required_args_count = 4
|
||||||
if len(task_args) != _required_args_count:
|
if len(task_args) != _required_args_count:
|
||||||
logger.error("Invalid number of arguments.")
|
logger.error("Invalid number of arguments.")
|
||||||
return
|
return
|
||||||
|
|
||||||
filename, email, _, received_at, *_ = task_args
|
filename, email, _, received_at = task_args
|
||||||
|
|
||||||
initial_metadata = {
|
initial_metadata = {
|
||||||
**initial_metadata,
|
**initial_metadata,
|
||||||
"filename": filename,
|
"filename": filename,
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
"""Celery Config."""
|
|
||||||
|
|
||||||
# https://github.com/danihodovic/celery-exporter
|
# https://github.com/danihodovic/celery-exporter
|
||||||
# Enable task events for Prometheus monitoring via celery-exporter.
|
# Enable task events for Prometheus monitoring via celery-exporter.
|
||||||
|
|
||||||
# worker_send_task_events: Sends task lifecycle events (e.g., started, succeeded),
|
# worker_send_task_events: Sends task lifecycle events (e.g., started, succeeded, failed),
|
||||||
# allowing the exporter to track task execution metrics and durations.
|
# allowing the exporter to track task execution metrics and durations.
|
||||||
worker_send_task_events = True
|
worker_send_task_events = True
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ celery = Celery(
|
|||||||
broker_connection_retry_on_startup=True,
|
broker_connection_retry_on_startup=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
celery.config_from_object("summary.core.celery_config")
|
celery.config_from_object('summary.core.celery_config')
|
||||||
|
|
||||||
if settings.sentry_dsn and settings.sentry_is_enabled:
|
if settings.sentry_dsn and settings.sentry_is_enabled:
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user