Compare commits

..

1 Commits

Author SHA1 Message Date
lebaudantoine 14bb3e6400 🔇(frontend) suppress leaked WebSocket error events from livekit-client
livekit-client leaks the raw WebSocket error Event as an unhandled
rejection when the signal WebSocket errors after connect. This is
mostly seen on Firefox and coincides with signal reconnects.

The event carries zero diagnostic content — the close reason is
already logged by the SDK — so it only adds noise to error
tracking.

Filter it out from our reporting.

Upstream issue: https://github.com/livekit/client-sdk-js/issues/2062
2026-08-23 17:58:47 +02:00
19 changed files with 128 additions and 275 deletions
-12
View File
@@ -8,18 +8,6 @@ and this project adheres to
## [Unreleased]
### Changed
- 📱(frontend) collapse mobile control bar items on narrow viewports
- 📱(frontend) stack idle modal buttons in a column on mobile
- 📱(frontend) improve feedback screen responsiveness on mobile
- ⬆️(frontend) upgrade @fontsource-variable/atkinson-hyperlegible-next
- ⬆️(frontend) upgrade i18next-resources-to-backend from 1.2.1 to 1.2.3
- ⬆️(frontend) upgrade @tanstack/react-query from 5.101.1 to 5.101.4
- ⬆️(frontend) upgrade @pandacss/preset-panda from 1.11.3 to 1.12.0
## [1.28.0] - 2026-08-24
### Added
- 📈(frontend) track errors when starting or stopping a recording
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "agents"
version = "1.28.0"
version = "1.27.0"
requires-python = ">=3.12"
dependencies = [
"livekit-agents==1.6.7",
+1 -1
View File
@@ -9,7 +9,7 @@ resolution-markers = [
[[package]]
name = "agents"
version = "1.28.0"
version = "1.27.0"
source = { virtual = "." }
dependencies = [
{ name = "livekit-agents" },
+1 -1
View File
@@ -7,7 +7,7 @@ build-backend = "uv_build"
[project]
name = "meet"
version = "1.28.0"
version = "1.27.0"
authors = [{ "name" = "DINUM", "email" = "dev@mail.numerique.gouv.fr" }]
classifiers = [
"Development Status :: 5 - Production/Stable",
+1 -1
View File
@@ -1187,7 +1187,7 @@ wheels = [
[[package]]
name = "meet"
version = "1.28.0"
version = "1.27.0"
source = { editable = "." }
dependencies = [
{ name = "aiohttp" },
+26 -27
View File
@@ -1,14 +1,14 @@
{
"name": "meet",
"version": "1.28.0",
"version": "1.27.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "meet",
"version": "1.28.0",
"version": "1.27.0",
"dependencies": {
"@fontsource-variable/atkinson-hyperlegible-next": "5.3.0",
"@fontsource-variable/atkinson-hyperlegible-next": "5.2.6",
"@fontsource-variable/lexend": "5.2.11",
"@fontsource/opendyslexic": "5.2.5",
"@libreaudio/la-call": "0.1.4",
@@ -16,10 +16,10 @@
"@livekit/components-styles": "1.2.0",
"@livekit/track-processors": "0.7.2",
"@mediapipe/tasks-vision": "0.10.14",
"@pandacss/preset-panda": "1.12.0",
"@pandacss/preset-panda": "1.11.3",
"@react-types/overlays": "3.10.0",
"@remixicon/react": "4.9.0",
"@tanstack/react-query": "5.101.4",
"@tanstack/react-query": "5.101.1",
"@timephy/rnnoise-wasm": "1.0.0",
"crisp-sdk-web": "1.1.2",
"hoofd": "1.7.3",
@@ -27,7 +27,7 @@
"i18next": "26.3.6",
"i18next-browser-languagedetector": "8.2.1",
"i18next-parser": "9.4.0",
"i18next-resources-to-backend": "1.2.3",
"i18next-resources-to-backend": "1.2.1",
"livekit-client": "2.21.0",
"posthog-js": "1.404.1",
"react": "18.3.1",
@@ -767,9 +767,9 @@
"license": "MIT"
},
"node_modules/@fontsource-variable/atkinson-hyperlegible-next": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@fontsource-variable/atkinson-hyperlegible-next/-/atkinson-hyperlegible-next-5.3.0.tgz",
"integrity": "sha512-UnLzNUy1RWoLDfydAatP4NaRm99X/WbQEph7q/PymJnCFIOOwKOx3pBmp5ys8trO0dM+CKGuJgeZP9fAR4mQpA==",
"version": "5.2.6",
"resolved": "https://registry.npmjs.org/@fontsource-variable/atkinson-hyperlegible-next/-/atkinson-hyperlegible-next-5.2.6.tgz",
"integrity": "sha512-D0Z8peFkRGYACvmWp8Sl8YPGYLBEJbzqapugtsMEYSUUtpQDiZVDHjk9s7bqB4hSCRYCrKuW6V1V+mnHybVnPw==",
"license": "OFL-1.1",
"funding": {
"url": "https://github.com/sponsors/ayuhito"
@@ -1642,21 +1642,21 @@
}
},
"node_modules/@pandacss/preset-panda": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/@pandacss/preset-panda/-/preset-panda-1.12.0.tgz",
"integrity": "sha512-jhzhAmtGY34b1FlMJGEAh/IkfU4WyTNT2mpJfcBUPBi1rZLHSTcs0aqedRmMdwM4tTT43XFOXMiazbztKME60A==",
"version": "1.11.3",
"resolved": "https://registry.npmjs.org/@pandacss/preset-panda/-/preset-panda-1.11.3.tgz",
"integrity": "sha512-IHeRQyIYeGKpQl78A/oI9fGg8MHQiOX/HttH+iQNaRU/MbGN6JsPe/N0ekQC6QY8iiKtLhqR+SRc455SN6JVWw==",
"license": "MIT",
"dependencies": {
"@pandacss/types": "1.12.0"
"@pandacss/types": "1.11.3"
},
"engines": {
"node": ">=20"
}
},
"node_modules/@pandacss/preset-panda/node_modules/@pandacss/types": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/@pandacss/types/-/types-1.12.0.tgz",
"integrity": "sha512-PtlEIOBEV3RzWffeu1zH+/YFmP+fn24M63STGEbgTwjEBMhyo/FfT2sfZGB8oWAbWUBKBp69OMg25E+/rY3klQ==",
"version": "1.11.3",
"resolved": "https://registry.npmjs.org/@pandacss/types/-/types-1.11.3.tgz",
"integrity": "sha512-tUbxa3WzoCuulP6kcMn7f0uNgLBvu81JAg4sfoUpz6PZE36VHA3k9n6ROEwziTbr7vqgeCj5DYQCUldrVNbEGQ==",
"license": "MIT",
"engines": {
"node": ">=20"
@@ -2414,9 +2414,9 @@
}
},
"node_modules/@tanstack/query-core": {
"version": "5.101.4",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.101.4.tgz",
"integrity": "sha512-gNwcvOJcRbLWPOLG/2OBm+zM+Yv+MKsXKEOWC57USuZDEsI71hEErQsiEGx5wX9rzWWkfwM0fVSPoiIFSsxfiw==",
"version": "5.101.1",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.101.1.tgz",
"integrity": "sha512-Y6Y92dkXtNqx67m2pMSxUsA3zOCwv862JexZRP8/EPwvKXMPu9m8rv43spiXWzOUIggQ3SQApttALStzhA8B4g==",
"license": "MIT",
"funding": {
"type": "github",
@@ -2435,12 +2435,12 @@
}
},
"node_modules/@tanstack/react-query": {
"version": "5.101.4",
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.101.4.tgz",
"integrity": "sha512-yRg2pfOCxIs4ZJW3XYYHU/WgtD04FHSnfHlpRT7h7pR77hwkdRG4wxbKe4aq6P0RvXUTBSQpQeadS1SUYUe+KA==",
"version": "5.101.1",
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.101.1.tgz",
"integrity": "sha512-ZnONUuQKJe1bJMStXUL1s5uKN9FcfC28j5cK+iDZcdSHtUv1wtin1cGc/Oewhf2Oc4eKY7lggtpvT/AbMmhHew==",
"license": "MIT",
"dependencies": {
"@tanstack/query-core": "5.101.4"
"@tanstack/query-core": "5.101.1"
},
"funding": {
"type": "github",
@@ -6975,10 +6975,9 @@
}
},
"node_modules/i18next-resources-to-backend": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/i18next-resources-to-backend/-/i18next-resources-to-backend-1.2.3.tgz",
"integrity": "sha512-8Y/LLAm5fqZc2ckQxtTWbu75ndjNLzF7mcYl6rhc4g+WBopIsG3YhdYqF5qhJy64tlYhlU2KSSnEgW3gGHLqwg==",
"license": "MIT",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/i18next-resources-to-backend/-/i18next-resources-to-backend-1.2.1.tgz",
"integrity": "sha512-okHbVA+HZ7n1/76MsfhPqDou0fptl2dAlhRDu2ideXloRRduzHsqDOznJBef+R3DFZnbvWoBW+KxJ7fnFjd6Yw==",
"dependencies": {
"@babel/runtime": "^7.23.2"
}
+5 -5
View File
@@ -1,7 +1,7 @@
{
"name": "meet",
"private": true,
"version": "1.28.0",
"version": "1.27.0",
"type": "module",
"scripts": {
"dev": "panda codegen && vite",
@@ -15,7 +15,7 @@
"check": "prettier --check ./src"
},
"dependencies": {
"@fontsource-variable/atkinson-hyperlegible-next": "5.3.0",
"@fontsource-variable/atkinson-hyperlegible-next": "5.2.6",
"@fontsource-variable/lexend": "5.2.11",
"@fontsource/opendyslexic": "5.2.5",
"@libreaudio/la-call": "0.1.4",
@@ -23,10 +23,10 @@
"@livekit/components-styles": "1.2.0",
"@livekit/track-processors": "0.7.2",
"@mediapipe/tasks-vision": "0.10.14",
"@pandacss/preset-panda": "1.12.0",
"@pandacss/preset-panda": "1.11.3",
"@react-types/overlays": "3.10.0",
"@remixicon/react": "4.9.0",
"@tanstack/react-query": "5.101.4",
"@tanstack/react-query": "5.101.1",
"@timephy/rnnoise-wasm": "1.0.0",
"crisp-sdk-web": "1.1.2",
"hoofd": "1.7.3",
@@ -34,7 +34,7 @@
"i18next": "26.3.6",
"i18next-browser-languagedetector": "8.2.1",
"i18next-parser": "9.4.0",
"i18next-resources-to-backend": "1.2.3",
"i18next-resources-to-backend": "1.2.1",
"livekit-client": "2.21.0",
"posthog-js": "1.404.1",
"react": "18.3.1",
@@ -13,7 +13,7 @@ const controlBarRegion = cva({
mobile: {
true: {
justifyContent: 'center',
width: '100%',
width: '330px',
},
},
},
@@ -1,3 +1,4 @@
import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { RiEmotionLine } from '@remixicon/react'
import { ToggleButton } from '@/primitives'
@@ -6,8 +7,6 @@ import { useRegisterKeyboardShortcut } from '@/features/shortcuts/useRegisterKey
import { REACTIONS_TOOLBAR_ID } from '../constants'
import { useReactionsToolbar } from '../hooks/useReactionsToolbar'
import { layoutStore } from '@/stores/layout'
import { type ButtonRecipeProps } from '@/primitives/buttonRecipe'
import { ToggleButtonProps } from '@/primitives/ToggleButton'
const focusReactionsToolbar = () => {
document
@@ -18,44 +17,35 @@ const focusReactionsToolbar = () => {
export const REACTIONS_TOGGLE_ID = 'reactions-toggle'
/* eslint-disable react-refresh/only-export-components */
export const reactionShortcutHandler = () => {
if (layoutStore.showReactionsToolbar) {
focusReactionsToolbar()
} else {
layoutStore.showReactionsToolbar = true
}
}
type Props = Pick<NonNullable<ButtonRecipeProps>, 'variant'> & ToggleButtonProps
export const ReactionsToggle = ({
variant = 'primaryDark',
onPress,
...props
}: Props) => {
export const ReactionsToggle = () => {
const { t } = useTranslation('rooms', { keyPrefix: 'controls.reactions' })
const { isOpen, toggle } = useReactionsToolbar()
const handleShortcut = useCallback(() => {
if (layoutStore.showReactionsToolbar) {
focusReactionsToolbar()
} else {
layoutStore.showReactionsToolbar = true
}
}, [])
useRegisterKeyboardShortcut({
id: 'reaction',
handler: reactionShortcutHandler,
handler: handleShortcut,
})
return (
<ToggleButton
{...props}
id={REACTIONS_TOGGLE_ID}
data-attr="reactions-toggle"
square
variant={variant}
variant="primaryDark"
aria-label={t('button')}
aria-expanded={isOpen}
tooltip={t('button')}
isSelected={isOpen}
onChange={toggle}
onPress={onPress}
>
<RiEmotionLine />
</ToggleButton>
@@ -15,8 +15,7 @@ const Card = styled('div', {
marginTop: '1.5rem',
borderRadius: '0.25rem',
boxShadow: '',
width: '100%',
maxWidth: '380px',
minWidth: '380px',
minHeight: '196px',
},
})
@@ -38,11 +37,8 @@ const ratingButtonRecipe = cva({
color: 'initial',
border: 'none',
borderRadius: 0,
padding: { base: '0.5rem 0.25rem', xsm: '0.5rem 0.85rem' },
padding: '0.5rem 0.85rem',
flexGrow: '1',
flexBasis: 0,
minWidth: 0,
textAlign: 'center',
cursor: 'pointer',
},
variants: {
@@ -103,9 +99,7 @@ const OpenFeedback = ({
return (
<Card>
<H lvl={3} centered>
{t('question')}
</H>
<H lvl={3}>{t('question')}</H>
<TextArea
id="feedbackInput"
name="feedback"
@@ -174,9 +168,7 @@ const RateQuality = ({
return (
<Card>
<H lvl={3} centered>
{t('question')}
</H>
<H lvl={3}>{t('question')}</H>
<Bar>
{[...Array(maxRating)].map((_, index) => (
<RACButton
@@ -236,9 +228,7 @@ const ConfirmationMessage = ({ onNext }: { onNext: () => void }) => {
}}
>
<VStack gap={0}>
<H lvl={3} centered>
{t('heading')}
</H>
<H lvl={3}>{t('heading')}</H>
<Text as="p" variant="paragraph" centered>
{t('body')}
</Text>
@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'
import { css } from '@/styled-system/css'
import { useSnapshot } from 'valtio'
import { connectionObserverStore } from '@/stores/connectionObserver'
import { Stack } from '@/styled-system/jsx'
import { HStack } from '@/styled-system/jsx'
import { useEffect, useRef, useState } from 'react'
import { navigateTo } from '@/navigation/navigateTo'
import { useScreenReaderAnnounce } from '@/hooks/useScreenReaderAnnounce'
@@ -134,11 +134,7 @@ export const IsIdleDisconnectModal = () => {
</H>
<Description />
<Settings />
<Stack
direction={{ base: 'column', xsm: 'row' }}
align={{ base: 'stretch', xsm: 'center' }}
marginTop="2rem"
>
<HStack marginTop="2rem">
<Button
onPress={() => {
connectionObserverStore.isIdleDisconnectModalOpen = false
@@ -152,7 +148,7 @@ export const IsIdleDisconnectModal = () => {
<Button onPress={close} size="sm" variant="primary">
{t('stayButton')}
</Button>
</Stack>
</HStack>
</div>
)
}}
@@ -10,18 +10,10 @@ import {
showLowerHandToast,
} from '@/features/notifications/utils'
import { useRegisterKeyboardShortcut } from '@/features/shortcuts/useRegisterKeyboardShortcut'
import { type ButtonRecipeProps } from '@/primitives/buttonRecipe'
import { ToggleButtonProps } from '@/primitives/ToggleButton'
const SPEAKING_DETECTION_DELAY = 3000
type Props = Pick<NonNullable<ButtonRecipeProps>, 'variant'> & ToggleButtonProps
export const HandToggle = ({
variant = 'primaryDark',
onPress,
...props
}: Props) => {
export const HandToggle = () => {
const { t } = useTranslation('rooms', { keyPrefix: 'controls.hand' })
const room = useRoomContext()
@@ -82,16 +74,12 @@ export const HandToggle = ({
})}
>
<ToggleButton
{...props}
square
variant={variant}
variant="primaryDark"
aria-label={t(tooltipLabel)}
tooltip={t(tooltipLabel)}
isSelected={isHandRaised}
onPress={(e) => {
handleToggle()
onPress?.(e)
}}
onPress={handleToggle}
data-attr={`controls-hand-${tooltipLabel}`}
>
<RiHand />
@@ -1,7 +1,7 @@
import { supportsScreenSharing } from '@livekit/components-core'
import { useTranslation } from 'react-i18next'
import type { ControlBarAuxProps } from './ControlBar'
import React, { useLayoutEffect, useRef, useState } from 'react'
import React from 'react'
import { css } from '@/styled-system/css'
import { LeaveButton } from '../../components/controls/LeaveButton'
import { Track } from 'livekit-client'
@@ -26,26 +26,7 @@ import { AudioDevicesControl } from '../../components/controls/Device/AudioDevic
import { VideoDeviceControl } from '../../components/controls/Device/VideoDeviceControl'
import { openSettingsDialog } from '@/stores/settings'
import { ControlBarRegion } from '@/features/layout/components/ControlBarRegion'
import {
ReactionsToggle,
reactionShortcutHandler,
} from '@/features/reactions/components/ReactionsToggle'
import { useSize } from '../../hooks/useResizeObserver'
import { useRegisterKeyboardShortcut } from '@/features/shortcuts/useRegisterKeyboardShortcut'
import { useRaisedHand } from '@/features/rooms/livekit/hooks/useRaisedHand'
import { useRoomContext } from '@livekit/components-react'
// Hand collapses first, then reactions; hidden toggles move into the menu.
const COLLAPSIBLE_COUNT = 2
// Layout-neutral measuring wrapper: inherits the region's gap and refuses to
// flex-shrink so measured widths are natural content widths.
const measuredRow = css({
display: 'inline-flex',
alignItems: 'center',
gap: 'inherit',
flexShrink: 0,
})
import { ReactionsToggle } from '@/features/reactions/components/ReactionsToggle'
export function MobileControlBar({
onDeviceError,
@@ -55,107 +36,50 @@ export function MobileControlBar({
const browserSupportsScreenSharing = supportsScreenSharing()
const { toggleEffects } = useSidePanel()
const containerRef = useRef<HTMLDivElement>(null)
const { width } = useSize(containerRef)
const barRef = useRef<HTMLDivElement>(null)
const { width: barWidth } = useSize(barRef)
const collapsibleRef = useRef<HTMLDivElement>(null)
const { width: collapsibleWidth } = useSize(collapsibleRef)
const [hiddenCount, setHiddenCount] = useState(0)
const calibration = useRef<{ essential: number; slot: number }>()
useLayoutEffect(() => {
if (hiddenCount === 0 && collapsibleWidth > 0 && barRef.current) {
const gap = parseFloat(getComputedStyle(barRef.current).columnGap) || 0
calibration.current = {
essential: barWidth - collapsibleWidth - gap,
slot: (collapsibleWidth + gap) / COLLAPSIBLE_COUNT,
}
}
if (!calibration.current || width <= 0) return
const { essential, slot } = calibration.current
const fits = Math.floor((width - essential) / slot)
const next = Math.min(
COLLAPSIBLE_COUNT,
Math.max(0, COLLAPSIBLE_COUNT - fits)
)
if (next !== hiddenCount) setHiddenCount(next)
}, [barWidth, collapsibleWidth, hiddenCount, width, setHiddenCount])
const hideHand = hiddenCount >= 1
const hideReactions = hiddenCount >= 2
const room = useRoomContext()
const { toggleRaisedHand } = useRaisedHand({
participant: room.localParticipant,
})
useRegisterKeyboardShortcut({
id: 'raise-hand',
handler: toggleRaisedHand,
})
useRegisterKeyboardShortcut({
id: 'reaction',
handler: reactionShortcutHandler,
})
const { data } = useConfig()
const closeMenu = () => setIsMenuOpened(false)
return (
<>
<div
className={css({
width: '100vw',
display: 'flex',
padding: '1.125rem',
justifyContent: 'center',
})}
>
<div
ref={containerRef}
className={css({
width: '100%',
display: 'flex',
justifyContent: 'center',
})}
>
<ControlBarRegion mobile>
<div ref={barRef} className={measuredRow}>
<LeaveButton />
<AudioDevicesControl
onDeviceError={(error) =>
onDeviceError?.({ source: Track.Source.Microphone, error })
}
hideMenu={true}
/>
<VideoDeviceControl
onDeviceError={(error) =>
onDeviceError?.({ source: Track.Source.Camera, error })
}
hideMenu={true}
/>
{/* Unmounted when empty so it doesn't leave a stray gap. */}
{!hideReactions && (
<div ref={collapsibleRef} className={measuredRow}>
<ReactionsToggle />
{!hideHand && <HandToggle />}
</div>
)}
<Button
id="room-options-trigger"
square
variant="primaryDark"
aria-label={t('options.buttonLabel')}
tooltip={t('options.buttonLabel')}
onPress={() => setIsMenuOpened(true)}
>
<RiMore2Line />
</Button>
</div>
</ControlBarRegion>
</div>
<ControlBarRegion mobile>
<LeaveButton />
<AudioDevicesControl
onDeviceError={(error) =>
onDeviceError?.({ source: Track.Source.Microphone, error })
}
hideMenu={true}
/>
<VideoDeviceControl
onDeviceError={(error) =>
onDeviceError?.({ source: Track.Source.Camera, error })
}
hideMenu={true}
/>
<ReactionsToggle />
<HandToggle />
<Button
id="room-options-trigger"
square
variant="primaryDark"
aria-label={t('options.buttonLabel')}
tooltip={t('options.buttonLabel')}
onPress={() => setIsMenuOpened(true)}
>
<RiMore2Line />
</Button>
</ControlBarRegion>
</div>
<ResponsiveMenu isOpened={isMenuOpened} onClosed={closeMenu}>
<ResponsiveMenu
isOpened={isMenuOpened}
onClosed={() => setIsMenuOpened(false)}
>
<div
className={css({
display: 'flex',
@@ -174,20 +98,6 @@ export function MobileControlBar({
},
})}
>
{hideReactions && (
<ReactionsToggle
variant="primaryTextDark"
description={true}
onPress={closeMenu}
/>
)}
{hideHand && (
<HandToggle
variant="primaryTextDark"
description={true}
onPress={closeMenu}
/>
)}
{browserSupportsScreenSharing && (
<ScreenShareToggle
onDeviceError={(error) =>
@@ -195,16 +105,25 @@ export function MobileControlBar({
}
variant="primaryTextDark"
description={true}
onPress={closeMenu}
onPress={() => setIsMenuOpened(false)}
/>
)}
<ChatToggle description={true} onPress={closeMenu} />
<ParticipantsToggle description={true} onPress={closeMenu} />
<ToolsToggle description={true} onPress={closeMenu} />
<ChatToggle
description={true}
onPress={() => setIsMenuOpened(false)}
/>
<ParticipantsToggle
description={true}
onPress={() => setIsMenuOpened(false)}
/>
<ToolsToggle
description={true}
onPress={() => setIsMenuOpened(false)}
/>
<Button
onPress={() => {
toggleEffects()
closeMenu()
setIsMenuOpened(false)
}}
variant="primaryTextDark"
aria-label={t('options.items.effects')}
@@ -221,7 +140,7 @@ export function MobileControlBar({
aria-label={t('options.items.feedback')}
description={true}
target="_blank"
onPress={closeMenu}
onPress={() => setIsMenuOpened(false)}
>
<RiMegaphoneLine size={20} />
</LinkButton>
@@ -229,7 +148,7 @@ export function MobileControlBar({
<Button
onPress={() => {
openSettingsDialog()
closeMenu()
setIsMenuOpened(false)
}}
variant="primaryTextDark"
aria-label={t('options.items.settings')}
@@ -238,7 +157,7 @@ export function MobileControlBar({
>
<RiSettings3Line size={20} />
</Button>
<CameraSwitchButton onPress={closeMenu} />
<CameraSwitchButton onPress={() => setIsMenuOpened(false)} />
</div>
</div>
</ResponsiveMenu>
@@ -1,8 +1,7 @@
import { useTranslation } from 'react-i18next'
import { Button } from '@/primitives'
import { Screen } from '@/layout/Screen'
import { Center, Stack, styled, VStack } from '@/styled-system/jsx'
import { css } from '@/styled-system/css'
import { Center, HStack, styled, VStack } from '@/styled-system/jsx'
import { Rating } from '@/features/rooms/components/Rating.tsx'
import { useLocation } from 'wouter'
import { useMemo } from 'react'
@@ -15,18 +14,14 @@ const Heading = styled('h1', {
fontStyle: 'normal',
fontStretch: 'normal',
fontOpticalSizing: 'auto',
fontSize: { base: '1.75rem', xsm: '2.3rem' },
lineHeight: { base: '2.125rem', xsm: '2.5rem' },
fontSize: '2.3rem',
lineHeight: '2.5rem',
letterSpacing: '0',
paddingBottom: { base: '1.5rem', xsm: '2rem' },
paddingBottom: '2rem',
textAlign: 'center',
},
})
const buttonClass = css({
width: { base: '100%', xsm: 'auto' },
})
enum DisconnectReasonKey {
DuplicateIdentity = 'duplicateIdentity',
ParticipantRemoved = 'participantRemoved',
@@ -59,31 +54,19 @@ const FeedbackRoute = () => {
return (
<Screen layout="centered" footer={false}>
<Center width="100%">
<VStack width="100%" paddingX="1rem">
<Center>
<VStack>
<Heading>{t(`feedback.heading.${reasonKey || 'normal'}`)}</Heading>
<Stack
direction={{ base: 'column', xsm: 'row' }}
width={{ base: '100%', xsm: 'auto' }}
maxWidth="380px"
>
<HStack>
{showBackButton && (
<Button
variant="secondary"
className={buttonClass}
onPress={() => window.history.back()}
>
<Button variant="secondary" onPress={() => window.history.back()}>
{t('feedback.back')}
</Button>
)}
<Button
variant="primary"
className={buttonClass}
onPress={() => setLocation('/')}
>
<Button variant="primary" onPress={() => setLocation('/')}>
{t('feedback.home')}
</Button>
</Stack>
</HStack>
<Rating metadata={metadata} />
</VStack>
</Center>
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "mail_mjml",
"version": "1.28.0",
"version": "1.27.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "mail_mjml",
"version": "1.28.0",
"version": "1.27.0",
"license": "MIT",
"dependencies": {
"@html-to/text-cli": "0.6.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "mail_mjml",
"version": "1.28.0",
"version": "1.27.0",
"description": "An util to generate html and text django's templates from mjml templates",
"type": "module",
"dependencies": {
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "sdk",
"version": "1.28.0",
"version": "1.27.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sdk",
"version": "1.28.0",
"version": "1.27.0",
"license": "ISC",
"workspaces": [
"./library",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "sdk",
"version": "1.28.0",
"version": "1.27.0",
"author": "",
"license": "ISC",
"description": "",
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "summary"
version = "1.28.0"
version = "1.27.0"
dependencies = [
"fastapi[standard]>=0.105.0",
"uvicorn>=0.24.0",