@evolve.ui/core-components 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/evolve-ui.entries.json +556 -0
- package/fileUpload/testUtils/mockFilesAndImages.d.cts +3 -3
- package/fileUpload/testUtils/mockFilesAndImages.d.cts.map +1 -1
- package/fileUpload/testUtils/mockFilesAndImages.d.mts +3 -3
- package/fileUpload/testUtils/mockFilesAndImages.d.mts.map +1 -1
- package/fileUpload/testUtils/testUtils.d.cts +1 -1
- package/fileUpload/testUtils/testUtils.d.cts.map +1 -1
- package/fileUpload/testUtils/testUtils.d.mts +1 -1
- package/fileUpload/testUtils/testUtils.d.mts.map +1 -1
- package/package.json +2 -2
- package/src/Accordion/Accordion.tsx +233 -0
- package/src/AddressDisplay/AddressDisplay.tsx +43 -0
- package/src/AddressDisplay/components/addressComponents.tsx +111 -0
- package/src/AddressDisplay/components/addressField.tsx +25 -0
- package/src/AddressDisplay/components/addressSection.tsx +8 -0
- package/src/AddressDisplay/components/getCountryValue.tsx +31 -0
- package/src/AddressDisplay/types.ts +26 -0
- package/src/AutomatedCarousel/AutomatedCarousel.tsx +163 -0
- package/src/AutomatedCarousel/automatedCarousel.types.ts +7 -0
- package/src/AutomatedCarousel/components/CarouselProgressBar/CarouselProgressBar.tsx +139 -0
- package/src/AutomatedCarousel/components/CarouselProgressBar/components/CarouselProgressBarUnit/CarouselProgressBarUnit.tsx +165 -0
- package/src/Badge/Badge.tsx +104 -0
- package/src/Badge/Badge.types.ts +58 -0
- package/src/Badge/ItemBadge.tsx +97 -0
- package/src/Badge/LiveStatusBadge.tsx +93 -0
- package/src/BannerNotification/BannerNotification.tsx +157 -0
- package/src/BannerNotification/components/BannerNotificationSkeleton.tsx +39 -0
- package/src/BannerNotification/components/CalloutIcon/BannerIcon.tsx +48 -0
- package/src/BannerNotification/utils/getRandomTooltipId.ts +3 -0
- package/src/BottomSheet/BottomSheet.tsx +476 -0
- package/src/BottomSheet/components/BottomSheetBackdrop/BottomSheetBackdrop.tsx +47 -0
- package/src/BottomSheet/components/BottomSheetContentArea/BottomSheetContentArea.tsx +92 -0
- package/src/BottomSheet/components/BottomSheetOverlay/BottomSheetOverlayTranslate3d.tsx +196 -0
- package/src/BottomSheet/components/SheetDescription/SheetDescription.tsx +22 -0
- package/src/BottomSheet/components/SheetTitle/SheetTitle.tsx +21 -0
- package/src/BottomSheet/components/index.tsx +5 -0
- package/src/BottomSheet/hooks/index.tsx +13 -0
- package/src/BottomSheet/hooks/useAriaHider.tsx +91 -0
- package/src/BottomSheet/hooks/useBottomSheetServices.tsx +224 -0
- package/src/BottomSheet/hooks/useDragHandler.tsx +282 -0
- package/src/BottomSheet/hooks/useFocusTrap.tsx +113 -0
- package/src/BottomSheet/hooks/useLayoutEffect.tsx +4 -0
- package/src/BottomSheet/hooks/useOptimizedResizeObserver.tsx +94 -0
- package/src/BottomSheet/hooks/useOptimizedScrollState.tsx +87 -0
- package/src/BottomSheet/hooks/useReady.tsx +34 -0
- package/src/BottomSheet/hooks/useReducedMotion.tsx +22 -0
- package/src/BottomSheet/hooks/useScrollLock.tsx +143 -0
- package/src/BottomSheet/hooks/useSnapPoints.tsx +355 -0
- package/src/BottomSheet/hooks/useSpring.tsx +47 -0
- package/src/BottomSheet/hooks/useSpringInterpolationsTranslate3d.tsx +101 -0
- package/src/BottomSheet/index.tsx +237 -0
- package/src/BottomSheet/state/atoms.ts +147 -0
- package/src/BottomSheet/state/useBottomSheetStateMachine.ts +246 -0
- package/src/BottomSheet/types.ts +172 -0
- package/src/BottomSheet/utils.ts +65 -0
- package/src/Breadcrumbs/Breadcrumbs.tsx +126 -0
- package/src/Button/Button.tsx +164 -0
- package/src/Button/Button.types.ts +80 -0
- package/src/Button/buttonColorClasses.ts +53 -0
- package/src/Callout/Callout.tsx +136 -0
- package/src/Callout/Callout.types.ts +29 -0
- package/src/Callout/components/CalloutIcon/CalloutIcon.tsx +56 -0
- package/src/Card/CardGrid.tsx +263 -0
- package/src/Card/SingleCard.tsx +22 -0
- package/src/Card/cardFactory.tsx +176 -0
- package/src/Card/components/createBadge.tsx +34 -0
- package/src/Card/components/createFavoriteButton.tsx +40 -0
- package/src/Card/components/createImage.tsx +64 -0
- package/src/Card/components/createInfo.tsx +84 -0
- package/src/Card/components/createName.tsx +63 -0
- package/src/Card/components/createPriceStatus.tsx +100 -0
- package/src/Card/components/types.ts +4 -0
- package/src/Card/hooks/useCardVisibilityTracking.ts +82 -0
- package/src/Card/sharedProps.ts +12 -0
- package/src/Card/types.ts +62 -0
- package/src/Carousel/Carousel.tsx +513 -0
- package/src/Carousel/Carousel.types.ts +43 -0
- package/src/Carousel/Carousel.utils.ts +63 -0
- package/src/Carousel/components/DotButton/DotButton.tsx +42 -0
- package/src/Carousel/components/NavigationButtons/NavigationButtons.tsx +77 -0
- package/src/Carousel/components/TitleSection/TitleSection.tsx +61 -0
- package/src/Carousel/components/TitleSection/components/SubHeaderLeft/SubHeaderLeft.tsx +53 -0
- package/src/Carousel/components/TitleSection/components/Title/Title.tsx +46 -0
- package/src/Carousel/index.ts +2 -0
- package/src/Carousel/testUtils.ts +10 -0
- package/src/Chips/Chip.tsx +153 -0
- package/src/Chips/ChipGroup.tsx +173 -0
- package/src/Chips/SuggestionChip.tsx +15 -0
- package/src/Chips/chipTypes.ts +113 -0
- package/src/Chips/index.ts +4 -0
- package/src/ChoiceListItem/Checkbox.tsx +69 -0
- package/src/ChoiceListItem/Radio.tsx +61 -0
- package/src/ChoiceListItem/choiceListItem.tsx +99 -0
- package/src/ChoiceListItem/common.tsx +148 -0
- package/src/ChoiceListItem/index.ts +3 -0
- package/src/Collapsible/Collapsible.tsx +58 -0
- package/src/Confetti/Confetti.tsx +270 -0
- package/src/Confetti/index.ts +2 -0
- package/src/ContentPager/ContentPager.tsx +189 -0
- package/src/ContentPager/components/Page.tsx +24 -0
- package/src/CookieConsent/components/CookieCategoryRow/CookieCategoryRow.tsx +30 -0
- package/src/CookieConsent/components/CookieConsent/CookieConsent.tsx +74 -0
- package/src/CookieConsent/components/CookieConsentBanner/CookieConsentBanner.tsx +51 -0
- package/src/CookieConsent/components/CookieConsentModal/CookieConsentModal.tsx +64 -0
- package/src/CookieConsent/hooks/useCookieConsent.ts +170 -0
- package/src/CookieConsent/hooks/useCookieConsentState.ts +142 -0
- package/src/CookieConsent/index.ts +16 -0
- package/src/CookieConsent/types/cookieConsent.types.ts +79 -0
- package/src/CookieConsent/types/index.ts +7 -0
- package/src/Countdown/Countdown.tsx +161 -0
- package/src/Countdown/Countdown.types.ts +4 -0
- package/src/Countdown/hooks/useGetCountdown.ts +103 -0
- package/src/DateTimeInput/dateInput/DateInput.tsx +199 -0
- package/src/DateTimeInput/datePicker/DatePicker.tsx +138 -0
- package/src/DateTimeInput/datePicker/components/calendar/Calendar.tsx +72 -0
- package/src/DateTimeInput/datePicker/index.ts +2 -0
- package/src/DateTimeInput/timeInput/TimeInput.tsx +128 -0
- package/src/DateTimeInput/timePicker/TimePicker.tsx +118 -0
- package/src/DateTimeInput/timePicker/components/TimePopover/AmPmSwitch.tsx +103 -0
- package/src/DateTimeInput/timePicker/components/TimePopover/TimeFieldInput.tsx +26 -0
- package/src/DateTimeInput/timePicker/components/TimePopover/TimePopover.tsx +84 -0
- package/src/DateTimeInput/timePicker/components/TimePopover/TimePopover.utils.ts +67 -0
- package/src/DateTimeInput/timePicker/components/TimePopover/TimePopoverActions.tsx +26 -0
- package/src/DateTimeInput/timePicker/index.ts +2 -0
- package/src/DateTimeInput/utils/getDisplayDate.ts +15 -0
- package/src/DateTimeInput/utils/getDisplayTime.ts +15 -0
- package/src/DateTimeInput/utils/index.ts +2 -0
- package/src/DateTimeInput/utils/parseTimeValue.ts +54 -0
- package/src/Drawer/Drawer.tsx +446 -0
- package/src/Drawer/atoms.ts +4 -0
- package/src/Drawer/components/DialogActions/DialogActions.tsx +33 -0
- package/src/Drawer/components/DialogContent/DialogContent.tsx +80 -0
- package/src/Drawer/components/DialogHeader/DialogHeader.tsx +68 -0
- package/src/EducationalPopover/EducationalPopover.tsx +174 -0
- package/src/FavoriteButton/FavoriteButton.tsx +64 -0
- package/src/FavoriteButton/components/IconOnlyFavoriteButton/IconOnlyFavoriteButton.tsx +80 -0
- package/src/FavoriteButton/components/LabeledAnimatedFavoriteButton/LabeledAnimatedFavoriteButton.tsx +179 -0
- package/src/FavoriteButton/components/LabeledFavoriteButton/LabeledFavoriteButton.tsx +71 -0
- package/src/FavoriteButton/components/SmallHeartStraightIcon/SmallHeartStraightIcon.tsx +14 -0
- package/src/FavoriteButton/hooks/useFavoriteButtonState.ts +30 -0
- package/src/FavoriteButton/index.ts +2 -0
- package/src/FavoriteButton/types/favoriteButton.ts +87 -0
- package/src/FeatureFlags/devTools/FeatureFlagDevToolsUI.tsx +226 -0
- package/src/FeatureFlags/devTools/getFeatureFlagCookieOverrides.ts +30 -0
- package/src/FeatureFlags/devTools/utils/cookies.ts +169 -0
- package/src/FeatureFlags/hooks/index.ts +2 -0
- package/src/FeatureFlags/hooks/useFeatureFlag.tsx +19 -0
- package/src/FeatureFlags/hooks/useFeatureFlags.tsx +15 -0
- package/src/FileUpload/components/FileCard/FileCard.tsx +50 -0
- package/src/FileUpload/components/FileDropzone/FileDropzone.tsx +221 -0
- package/src/FileUpload/components/FileDropzone/components/DropzoneContent/DropzoneContent.tsx +28 -0
- package/src/FileUpload/components/FileDropzone/components/DropzoneContent/DropzoneText.tsx +81 -0
- package/src/FileUpload/components/FileDropzone/components/FileDropzoneDebugger/FileDropzoneDebugger.tsx +40 -0
- package/src/FileUpload/components/FileDropzone/components/FileDropzoneDebugger/FileRejectionsDisplay.tsx +110 -0
- package/src/FileUpload/components/FileDropzoneOverlay/FileDropzoneOverlay.tsx +183 -0
- package/src/FileUpload/components/FileDropzoneOverlay/components/OverlayDropzoneContent.tsx +146 -0
- package/src/FileUpload/components/FileDropzoneOverlay/components/OverlayDropzoneDragText.tsx +42 -0
- package/src/FileUpload/components/FileDropzoneOverlay/styles.ts +79 -0
- package/src/FileUpload/components/FilePreviewList/FilePreviewList.tsx +251 -0
- package/src/FileUpload/components/FilePreviewList/virtualizerComponents/FilePreviewVirtualizedList/FilePreviewVirtualizedList.tsx +88 -0
- package/src/FileUpload/components/FileUpload/FileUpload.tsx +63 -0
- package/src/FileUpload/components/FileUploadCanvas/FileUploadCanvas.tsx +125 -0
- package/src/FileUpload/components/GridFileCard/GridFileCard.tsx +364 -0
- package/src/FileUpload/components/GridFileCard/utils/sortable.ts +48 -0
- package/src/FileUpload/components/ListFileCard/ListFileCard.tsx +259 -0
- package/src/FileUpload/components/types.ts +78 -0
- package/src/FileUpload/hooks/filePreview/useImageFilePreviewUrl.ts +62 -0
- package/src/FileUpload/hooks/index.ts +11 -0
- package/src/FileUpload/hooks/upload/useHandleDragEnter/useHandleDragEnter.ts +154 -0
- package/src/FileUpload/hooks/upload/useHandleDrop/createFileRejectionHelpers.ts +273 -0
- package/src/FileUpload/hooks/upload/useHandleDrop/useHandleDrop.ts +153 -0
- package/src/FileUpload/hooks/upload/useUploadAvailability/useUploadAvailability.ts +44 -0
- package/src/FileUpload/hooks/validation/createDropzoneValidator.ts +41 -0
- package/src/FileUpload/hooks/validation/useFileValidation.ts +25 -0
- package/src/FileUpload/hooks/validation/useFileValidationLogic.ts +107 -0
- package/src/FileUpload/hooks/validation/useValidationMessages.ts +92 -0
- package/src/FileUpload/hooks/validation/useValidationState.ts +171 -0
- package/src/FileUpload/index.ts +57 -0
- package/src/FileUpload/providers/FileUploadProvider.tsx +219 -0
- package/src/FileUpload/providers/UploadValidationProvider.tsx +159 -0
- package/src/FileUpload/testUtils/mockFilesAndImages.ts +64 -0
- package/src/FileUpload/testUtils/testUtils.ts +111 -0
- package/src/FileUpload/types/commonTypes.ts +267 -0
- package/src/FileUpload/types/index.ts +31 -0
- package/src/FileUpload/types/sharedTypes.ts +159 -0
- package/src/FileUpload/utils/constants.ts +79 -0
- package/src/FileUpload/utils/createMessageContext.ts +180 -0
- package/src/FileUpload/utils/getFileExtensionsFromAcceptedTypes.ts +73 -0
- package/src/FileUpload/utils/getFilePluralizationText.ts +68 -0
- package/src/FileUpload/utils/getMimeTypes.ts +26 -0
- package/src/FileUpload/utils/messageUtils.ts +41 -0
- package/src/FileUpload/utils/styles.ts +68 -0
- package/src/FormLabel/FormLabel.tsx +212 -0
- package/src/IconButton/IconButton.tsx +154 -0
- package/src/Icons/CreditCardIcon/CreditCardIcon.tsx +73 -0
- package/src/Icons/CreditCardIcon/cardIcons.tsx +270 -0
- package/src/Icons/IconBase.tsx +133 -0
- package/src/Icons/anyIcon.ts +3 -0
- package/src/Icons/generatedIcons/Archive.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowClockwise.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowDown.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowLeft.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowRight.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowSquareOut.tsx +51 -0
- package/src/Icons/generatedIcons/ArrowSquareRight.tsx +51 -0
- package/src/Icons/generatedIcons/ArrowUp.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowsCounterClockwise.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowsLeftRight.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowsOutCardinal.tsx +48 -0
- package/src/Icons/generatedIcons/Bank.tsx +48 -0
- package/src/Icons/generatedIcons/Bell.tsx +51 -0
- package/src/Icons/generatedIcons/BookBookmark.tsx +51 -0
- package/src/Icons/generatedIcons/BookmarksSimple.tsx +51 -0
- package/src/Icons/generatedIcons/Broadcast.tsx +48 -0
- package/src/Icons/generatedIcons/CalendarBlank.tsx +48 -0
- package/src/Icons/generatedIcons/CalendarStar.tsx +51 -0
- package/src/Icons/generatedIcons/Camera.tsx +51 -0
- package/src/Icons/generatedIcons/CaretDown.tsx +48 -0
- package/src/Icons/generatedIcons/CaretLeft.tsx +48 -0
- package/src/Icons/generatedIcons/CaretRight.tsx +48 -0
- package/src/Icons/generatedIcons/CaretUp.tsx +48 -0
- package/src/Icons/generatedIcons/Certificate.tsx +51 -0
- package/src/Icons/generatedIcons/ChartBar.tsx +48 -0
- package/src/Icons/generatedIcons/Check.tsx +51 -0
- package/src/Icons/generatedIcons/CheckCircle.tsx +48 -0
- package/src/Icons/generatedIcons/CirclesFour.tsx +51 -0
- package/src/Icons/generatedIcons/Clock.tsx +48 -0
- package/src/Icons/generatedIcons/ClockCountdown.tsx +48 -0
- package/src/Icons/generatedIcons/Close.tsx +51 -0
- package/src/Icons/generatedIcons/CloudArrowUp.tsx +51 -0
- package/src/Icons/generatedIcons/CloudWarning.tsx +51 -0
- package/src/Icons/generatedIcons/Code.tsx +48 -0
- package/src/Icons/generatedIcons/Compass.tsx +51 -0
- package/src/Icons/generatedIcons/Confetti.tsx +51 -0
- package/src/Icons/generatedIcons/Copy.tsx +48 -0
- package/src/Icons/generatedIcons/CornersOut.tsx +48 -0
- package/src/Icons/generatedIcons/CreditCard.tsx +48 -0
- package/src/Icons/generatedIcons/Crown.tsx +51 -0
- package/src/Icons/generatedIcons/CrownSimple.tsx +51 -0
- package/src/Icons/generatedIcons/CurrencyCircleDollar.tsx +48 -0
- package/src/Icons/generatedIcons/CurrencyDollarSimple.tsx +51 -0
- package/src/Icons/generatedIcons/Desktop.tsx +51 -0
- package/src/Icons/generatedIcons/Detective.tsx +51 -0
- package/src/Icons/generatedIcons/DotOutline.tsx +46 -0
- package/src/Icons/generatedIcons/DotsSixVertical.tsx +51 -0
- package/src/Icons/generatedIcons/DotsThreeOutline.tsx +51 -0
- package/src/Icons/generatedIcons/DotsThreeOutlineVertical.tsx +51 -0
- package/src/Icons/generatedIcons/DownloadSimple.tsx +51 -0
- package/src/Icons/generatedIcons/EnvelopeSimple.tsx +48 -0
- package/src/Icons/generatedIcons/Eraser.tsx +51 -0
- package/src/Icons/generatedIcons/Eye.tsx +51 -0
- package/src/Icons/generatedIcons/EyeSlash.tsx +51 -0
- package/src/Icons/generatedIcons/FacebookLogo.tsx +48 -0
- package/src/Icons/generatedIcons/FileArchive.tsx +48 -0
- package/src/Icons/generatedIcons/FileArrowDown.tsx +48 -0
- package/src/Icons/generatedIcons/FileCsv.tsx +48 -0
- package/src/Icons/generatedIcons/FilePdf.tsx +48 -0
- package/src/Icons/generatedIcons/FileText.tsx +48 -0
- package/src/Icons/generatedIcons/Files.tsx +51 -0
- package/src/Icons/generatedIcons/Fire.tsx +51 -0
- package/src/Icons/generatedIcons/Flag.tsx +51 -0
- package/src/Icons/generatedIcons/FlagBannerFold.tsx +48 -0
- package/src/Icons/generatedIcons/FloppyDisk.tsx +51 -0
- package/src/Icons/generatedIcons/Gauge.tsx +51 -0
- package/src/Icons/generatedIcons/Gavel.tsx +51 -0
- package/src/Icons/generatedIcons/Gear.tsx +51 -0
- package/src/Icons/generatedIcons/GlobeHemisphereWest.tsx +51 -0
- package/src/Icons/generatedIcons/GoogleLogo.tsx +48 -0
- package/src/Icons/generatedIcons/GridNine.tsx +51 -0
- package/src/Icons/generatedIcons/HandCoins.tsx +51 -0
- package/src/Icons/generatedIcons/HandbagSimple.tsx +51 -0
- package/src/Icons/generatedIcons/Headset.tsx +51 -0
- package/src/Icons/generatedIcons/HeartStraight.tsx +51 -0
- package/src/Icons/generatedIcons/HourglassLow.tsx +48 -0
- package/src/Icons/generatedIcons/House.tsx +51 -0
- package/src/Icons/generatedIcons/Image.tsx +51 -0
- package/src/Icons/generatedIcons/ImageSquare.tsx +51 -0
- package/src/Icons/generatedIcons/ImagesSquare.tsx +51 -0
- package/src/Icons/generatedIcons/Info.tsx +48 -0
- package/src/Icons/generatedIcons/InstagramLogo.tsx +51 -0
- package/src/Icons/generatedIcons/Lightning.tsx +48 -0
- package/src/Icons/generatedIcons/Link.tsx +51 -0
- package/src/Icons/generatedIcons/LinkedinLogo.tsx +51 -0
- package/src/Icons/generatedIcons/List.tsx +48 -0
- package/src/Icons/generatedIcons/Lock.tsx +51 -0
- package/src/Icons/generatedIcons/LockOpen.tsx +51 -0
- package/src/Icons/generatedIcons/MagnifyingGlass.tsx +48 -0
- package/src/Icons/generatedIcons/MapPin.tsx +51 -0
- package/src/Icons/generatedIcons/MapPinSimpleArea.tsx +48 -0
- package/src/Icons/generatedIcons/Medal.tsx +48 -0
- package/src/Icons/generatedIcons/Megaphone.tsx +48 -0
- package/src/Icons/generatedIcons/Minus.tsx +45 -0
- package/src/Icons/generatedIcons/Money.tsx +51 -0
- package/src/Icons/generatedIcons/Notches.tsx +48 -0
- package/src/Icons/generatedIcons/NotePencil.tsx +48 -0
- package/src/Icons/generatedIcons/Package.tsx +51 -0
- package/src/Icons/generatedIcons/PaintBrush.tsx +51 -0
- package/src/Icons/generatedIcons/PaperPlaneTilt.tsx +51 -0
- package/src/Icons/generatedIcons/Paperclip.tsx +51 -0
- package/src/Icons/generatedIcons/Pause.tsx +51 -0
- package/src/Icons/generatedIcons/PencilLine.tsx +51 -0
- package/src/Icons/generatedIcons/PencilRuler.tsx +51 -0
- package/src/Icons/generatedIcons/PencilSimple.tsx +51 -0
- package/src/Icons/generatedIcons/Phone.tsx +51 -0
- package/src/Icons/generatedIcons/PinterestLogo.tsx +51 -0
- package/src/Icons/generatedIcons/Play.tsx +51 -0
- package/src/Icons/generatedIcons/Plus.tsx +51 -0
- package/src/Icons/generatedIcons/PlusCircle.tsx +48 -0
- package/src/Icons/generatedIcons/Printer.tsx +51 -0
- package/src/Icons/generatedIcons/Question.tsx +48 -0
- package/src/Icons/generatedIcons/Receipt.tsx +51 -0
- package/src/Icons/generatedIcons/Rows.tsx +51 -0
- package/src/Icons/generatedIcons/SealCheck.tsx +51 -0
- package/src/Icons/generatedIcons/SelectionSlash.tsx +48 -0
- package/src/Icons/generatedIcons/ShareNetwork.tsx +51 -0
- package/src/Icons/generatedIcons/ShieldCheck.tsx +51 -0
- package/src/Icons/generatedIcons/ShieldStar.tsx +51 -0
- package/src/Icons/generatedIcons/ShoppingCart.tsx +48 -0
- package/src/Icons/generatedIcons/ShuffleAngular.tsx +48 -0
- package/src/Icons/generatedIcons/SidebarSimple.tsx +48 -0
- package/src/Icons/generatedIcons/SlidersHorizontal.tsx +51 -0
- package/src/Icons/generatedIcons/Smiley.tsx +48 -0
- package/src/Icons/generatedIcons/Sparkle.tsx +51 -0
- package/src/Icons/generatedIcons/SpinnerGap.tsx +48 -0
- package/src/Icons/generatedIcons/StackPlus.tsx +48 -0
- package/src/Icons/generatedIcons/Star.tsx +51 -0
- package/src/Icons/generatedIcons/Storefront.tsx +51 -0
- package/src/Icons/generatedIcons/Swap.tsx +51 -0
- package/src/Icons/generatedIcons/Tag.tsx +51 -0
- package/src/Icons/generatedIcons/ThumbsDown.tsx +48 -0
- package/src/Icons/generatedIcons/ThumbsUp.tsx +48 -0
- package/src/Icons/generatedIcons/Toolbox.tsx +48 -0
- package/src/Icons/generatedIcons/Trash.tsx +48 -0
- package/src/Icons/generatedIcons/TrendUp.tsx +48 -0
- package/src/Icons/generatedIcons/Trophy.tsx +51 -0
- package/src/Icons/generatedIcons/Truck.tsx +51 -0
- package/src/Icons/generatedIcons/UploadSimple.tsx +51 -0
- package/src/Icons/generatedIcons/User.tsx +48 -0
- package/src/Icons/generatedIcons/Users.tsx +48 -0
- package/src/Icons/generatedIcons/UsersThree.tsx +51 -0
- package/src/Icons/generatedIcons/VideoCamera.tsx +51 -0
- package/src/Icons/generatedIcons/Warning.tsx +51 -0
- package/src/Icons/generatedIcons/WarningCircle.tsx +48 -0
- package/src/Icons/generatedIcons/WifiHigh.tsx +51 -0
- package/src/Icons/generatedIcons/XCircle.tsx +48 -0
- package/src/Icons/generatedIcons/XLogo.tsx +48 -0
- package/src/Icons/generatedIcons/YoutubeLogo.tsx +51 -0
- package/src/Icons/importedIcons.ts +152 -0
- package/src/Icons/index.ts +149 -0
- package/src/Icons/socialIcons/appleSocialIcon.tsx +50 -0
- package/src/Icons/socialIcons/facebookSocialIcon.tsx +41 -0
- package/src/Icons/socialIcons/googleSocialIcon.tsx +134 -0
- package/src/ImageCluster/ImageCluster.tsx +125 -0
- package/src/ImageSlider/ImageSlider.tsx +582 -0
- package/src/ImageSlider/ImageSlider.types.ts +90 -0
- package/src/ImageSlider/components/IndexIndicator/IndexIndicator.tsx +21 -0
- package/src/ImageSlider/components/NavigationButtons/NavigationButtons.tsx +113 -0
- package/src/ImageSlider/components/ResponsiveImage/ResponsiveImage.tsx +114 -0
- package/src/ImageSlider/components/ResponsiveImage/index.ts +1 -0
- package/src/ImageSlider/components/Thumbnails/Thumbnails.tsx +184 -0
- package/src/ImageSlider/constants.ts +59 -0
- package/src/ImageSlider/hooks/index.ts +3 -0
- package/src/ImageSlider/hooks/useImageSlider.ts +57 -0
- package/src/ImageSlider/hooks/useImageSliderNavigation.ts +133 -0
- package/src/ImageSlider/hooks/useImageSliderScrollHandler.ts +171 -0
- package/src/ImageSlider/index.ts +3 -0
- package/src/ImageSlider/utils/imageOptimization.ts +97 -0
- package/src/ImageSlider/utils/index.ts +1 -0
- package/src/InlineNotification/InlineNotification.tsx +95 -0
- package/src/JumpMenu/JumpMenu.tsx +395 -0
- package/src/JumpMenu/components/JumpMenuItem/JumpMenuItem.tsx +62 -0
- package/src/JumpMenu/hooks/useContainerTracking.ts +171 -0
- package/src/JumpMenu/hooks/useIntersectionObserver.ts +77 -0
- package/src/JumpMenu/hooks/useKeyboardNavigation.ts +102 -0
- package/src/JumpMenu/hooks/useResizeObserver.ts +53 -0
- package/src/JumpMenu/hooks/useSectionObserver.ts +102 -0
- package/src/JumpMenu/index.ts +2 -0
- package/src/JumpMenu/types/index.ts +19 -0
- package/src/Loading/Loading.tsx +39 -0
- package/src/Loading/components/LoadingDot/LoadingDot.tsx +16 -0
- package/src/LoadingSpinner/LoadingSpinner.tsx +20 -0
- package/src/Menu/Menu.tsx +372 -0
- package/src/Menu/components/MenuDivider/MenuDivider.tsx +5 -0
- package/src/Menu/components/MenuItem/MenuItem.tsx +298 -0
- package/src/Menu/context/menuContext.tsx +20 -0
- package/src/Menu/hooks/useMenu.tsx +18 -0
- package/src/Menu/index.ts +3 -0
- package/src/Modal/ComposableModal.tsx +313 -0
- package/src/Modal/Modal.tsx +231 -0
- package/src/Modal/components/BackButton/BackButton.tsx +43 -0
- package/src/Modal/components/Backdrop/Backdrop.tsx +62 -0
- package/src/Modal/components/CloseButton/CloseButton.tsx +55 -0
- package/src/Modal/components/ModalActions/ModalActions.tsx +135 -0
- package/src/Modal/components/ModalContent/ModalContent.tsx +163 -0
- package/src/Modal/components/ModalHeader/ModalHeader.tsx +84 -0
- package/src/Modal/components/ModalHeader/hooks/useHeaderAnimation.tsx +49 -0
- package/src/Modal/components/ModalProgressSteps/ModalProgressSteps.tsx +26 -0
- package/src/Modal/components/ModalSubTitle/ModalSubTitle.tsx +29 -0
- package/src/Modal/components/ModalTitle/ModalTitle.tsx +22 -0
- package/src/Modal/components/PreventModalScroll/PreventModalScroll.tsx +106 -0
- package/src/Modal/components/index.ts +12 -0
- package/src/Modal/context.ts +33 -0
- package/src/Modal/hooks/useCloseModal.ts +133 -0
- package/src/NotificationBadge/NotificationBadge.tsx +34 -0
- package/src/Pagination/AdvancedPagination.tsx +48 -0
- package/src/Pagination/Pagination.tsx +216 -0
- package/src/Pagination/components/AdvancedPaginator/AdvancedPaginator.tsx +52 -0
- package/src/Pagination/components/AdvancedPaginator/components/PageSelect/PageSelect.tsx +43 -0
- package/src/Pagination/components/ItemCountDisplay/ItemCountDisplay.tsx +32 -0
- package/src/Pagination/components/ItemCountSelect/ItemCountSelect.tsx +33 -0
- package/src/Pagination/index.tsx +3 -0
- package/src/Pagination/paginationProvider.tsx +234 -0
- package/src/Pagination/utils.tsx +36 -0
- package/src/PhoneInput/PhoneInput.tsx +509 -0
- package/src/PhoneInput/useDropdownLogic.tsx +163 -0
- package/src/ProgressCircle/ProgressCircle.tsx +246 -0
- package/src/ProgressCircle/hooks/useProgressStatusTransitions.ts +49 -0
- package/src/ProgressCircle/utils/progressCircle.constants.ts +27 -0
- package/src/ProgressSteps/ProgressSteps.tsx +160 -0
- package/src/SaveConfetti/SaveConfetti.tsx +277 -0
- package/src/SaveConfetti/index.ts +2 -0
- package/src/SearchInput/SearchInput.tsx +236 -0
- package/src/SegmentedControl/SegmentedControl.tsx +111 -0
- package/src/SegmentedControl/SegmentedControlGroup.tsx +94 -0
- package/src/SegmentedControl/index.ts +4 -0
- package/src/Select/Select.tsx +154 -0
- package/src/Select/SelectAsync.tsx +13 -0
- package/src/Select/SelectAsyncCreatable.tsx +14 -0
- package/src/Select/SelectCreatable.tsx +12 -0
- package/src/Select/reexportedComponents.tsx +5 -0
- package/src/Select/selectComponents.tsx +306 -0
- package/src/Skeleton/Skeleton.tsx +13 -0
- package/src/SplitButton/SplitButton.tsx +298 -0
- package/src/SplitButton/SplitButtonTrigger.tsx +55 -0
- package/src/StarRating/StarRating.tsx +165 -0
- package/src/StarRating/components/StarComponent/StarComponent.tsx +44 -0
- package/src/Table/Table.tsx +474 -0
- package/src/Table/components/TableHeader/TableHeader.tsx +166 -0
- package/src/Table/components/TablePagination/TablePagination.tsx +18 -0
- package/src/Table/components/TablePagination/components/ItemCountDisplay/ItemCountDisplay.tsx +17 -0
- package/src/Table/components/TablePagination/components/ItemCountSelect/ItemCountSelect.tsx +31 -0
- package/src/Table/components/TablePagination/components/TablePaginator/TablePaginator.tsx +37 -0
- package/src/Table/components/TablePagination/components/TablePaginator/components/PageSelect/PageSelect.tsx +32 -0
- package/src/Table/components/TableRow/TableRows.tsx +147 -0
- package/src/Table/components/TableRow/components/TableRowCell/TableRowCell.tsx +49 -0
- package/src/Table/components/TableShadow/TableShadow.tsx +46 -0
- package/src/Table/index.ts +2 -0
- package/src/Table/sharedState.ts +30 -0
- package/src/Table/sharedStyles.ts +1 -0
- package/src/Table/types.ts +55 -0
- package/src/Tabs/Tabs.tsx +358 -0
- package/src/TextArea/TextArea.tsx +157 -0
- package/src/TextInput/TextInput.tsx +173 -0
- package/src/Toast/Toast.tsx +64 -0
- package/src/Toast/components/ToastContainer/ToastContainer.tsx +48 -0
- package/src/Toast/index.ts +2 -0
- package/src/Toast/types/role.ts +1 -0
- package/src/Toast/utils/getIcon.tsx +41 -0
- package/src/ToggleSwitch/ToggleSwitch.tsx +188 -0
- package/src/Tooltip/InfoIconTooltip.tsx +47 -0
- package/src/Tooltip/Tooltip.tsx +41 -0
- package/src/Typography/InlineButton/InlineButton.tsx +166 -0
- package/src/Typography/Links/Links.tsx +113 -0
- package/src/Typography/Text/Text.tsx +239 -0
- package/src/ViewMore/ViewMore.tsx +226 -0
- package/src/WebRTCPlayer/WebRTCPlayer.tsx +325 -0
- package/src/WebRTCPlayer/adaptor/NativeWebRTCAdaptor.ts +588 -0
- package/src/WebRTCPlayer/hooks/useWebRTCStream.ts +571 -0
- package/src/WebRTCPlayer/index.ts +22 -0
- package/src/WebRTCPlayer/types.ts +95 -0
- package/src/breakpoints/index.tsx +1 -0
- package/src/breakpoints/utils.tsx +50 -0
- package/src/declarations.d.ts +7 -0
- package/src/grid/gridHighlighter.tsx +83 -0
- package/src/grid/index.ts +3 -0
- package/src/grid/pageGrid.tsx +37 -0
- package/src/grid/useSubGridCSS.tsx +214 -0
- package/src/hooks/useHorizontalScrollFade.ts +44 -0
- package/src/hooks/usePrevious.ts +14 -0
- package/src/index.ts +351 -0
- package/src/intl/index.ts +4 -0
- package/src/intl/utils.ts +67 -0
- package/src/mixins/horizontalScrollFadeMixin.ts +56 -0
- package/src/mixins/index.ts +18 -0
- package/src/mixins/propMixins.ts +389 -0
- package/src/providers/createContextProvider.ts +22 -0
- package/src/providers/designSystemProvider.tsx +218 -0
- package/src/providers/errorBoundaryProvider.tsx +179 -0
- package/src/providers/featureFlagProvider.tsx +18 -0
- package/src/providers/gridSizeProvider.tsx +23 -0
- package/src/providers/index.ts +12 -0
- package/src/providers/linkProvider.tsx +32 -0
- package/src/providers/normalize.tsx +93 -0
- package/src/providers/targets/DatePickerTarget.tsx +10 -0
- package/src/providers/targets/ModalTarget.tsx +14 -0
- package/src/providers/targets/TimePickerTarget.tsx +10 -0
- package/src/providers/themeContext.tsx +24 -0
- package/src/providers/windowSizeProvider.tsx +125 -0
- package/src/spacing/index.ts +1 -0
- package/src/spacing/spacing.ts +11 -0
- package/src/utils/countriesWithISOCodes.ts +1419 -0
- package/src/utils/dateTimeFormat.ts +257 -0
- package/src/utils/effectEventListener.ts +11 -0
- package/src/utils/formatFileSize.ts +18 -0
- package/src/utils/isClientSide.ts +1 -0
- package/src/utils/keepTransition.ts +15 -0
- package/src/utils/nodeEnv.ts +9 -0
- package/src/utils/smoothScrollTo.ts +47 -0
- package/src/utils/utilityTypes.ts +13 -0
|
@@ -0,0 +1,571 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { NativeWebRTCAdaptor } from '../adaptor/NativeWebRTCAdaptor';
|
|
4
|
+
import {
|
|
5
|
+
DEFAULT_PATH,
|
|
6
|
+
DEFAULT_WS_PORT,
|
|
7
|
+
DEFAULT_WSS_PORT,
|
|
8
|
+
FETCH_STREAM_ID_TIMEOUT,
|
|
9
|
+
PING_INTERVAL,
|
|
10
|
+
RECONNECT_INTERVAL,
|
|
11
|
+
WebRTCConfig,
|
|
12
|
+
WebRTCConnectionState,
|
|
13
|
+
WebRTCErrorToken,
|
|
14
|
+
WebRTCPlayerState,
|
|
15
|
+
} from '../types';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Races a value/promise against a timeout, resolving to `undefined` if the
|
|
19
|
+
* timeout wins. Used to prevent a hung host-supplied fetchStreamId() from
|
|
20
|
+
* permanently blocking the reconnect loop.
|
|
21
|
+
*/
|
|
22
|
+
const withTimeout = async <T>(value: Promise<T> | T, ms: number): Promise<T | undefined> => {
|
|
23
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
24
|
+
const valuePromise = Promise.resolve(value);
|
|
25
|
+
// If the timeout wins the race, the value promise is left dangling. Attach a
|
|
26
|
+
// no-op catch so a late rejection doesn't surface as an unhandledRejection.
|
|
27
|
+
// (An early rejection still propagates through Promise.race to the caller.)
|
|
28
|
+
valuePromise.catch(() => undefined);
|
|
29
|
+
try {
|
|
30
|
+
return await Promise.race([
|
|
31
|
+
valuePromise,
|
|
32
|
+
new Promise<undefined>((resolve) => {
|
|
33
|
+
timer = setTimeout(() => {
|
|
34
|
+
resolve(undefined);
|
|
35
|
+
}, ms);
|
|
36
|
+
}),
|
|
37
|
+
]);
|
|
38
|
+
} finally {
|
|
39
|
+
if (timer) {
|
|
40
|
+
clearTimeout(timer);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Maps adaptor error tokens to user-facing copy so raw identifiers like
|
|
47
|
+
* `IceConnectionFailed` never reach the error overlay. Keyed off the shared
|
|
48
|
+
* WebRTCErrorToken constants so this map can't drift from what the adaptor emits.
|
|
49
|
+
*/
|
|
50
|
+
const FRIENDLY_ERROR_MESSAGES = new Map<string, string>([
|
|
51
|
+
[WebRTCErrorToken.failedToCreateAnswer, 'Connection lost'],
|
|
52
|
+
[WebRTCErrorToken.failedToSetLocalDescription, 'Connection lost'],
|
|
53
|
+
[WebRTCErrorToken.failedToSetRemoteDescription, 'Connection lost'],
|
|
54
|
+
[WebRTCErrorToken.iceConnectionFailed, 'Connection lost'],
|
|
55
|
+
[WebRTCErrorToken.peerConnectionFailed, 'Connection lost'],
|
|
56
|
+
[WebRTCErrorToken.webSocketError, 'Connection lost'],
|
|
57
|
+
[WebRTCErrorToken.webSocketNotConnected, 'Connection lost'],
|
|
58
|
+
[WebRTCErrorToken.webSocketNotSupported, 'Your browser does not support live streaming'],
|
|
59
|
+
]);
|
|
60
|
+
|
|
61
|
+
const toFriendlyError = (raw: string): string => FRIENDLY_ERROR_MESSAGES.get(raw) ?? raw;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Custom hook for managing WebRTC stream connections to Ant Media Server
|
|
65
|
+
*
|
|
66
|
+
* This hook handles the complete lifecycle of a WebRTC stream connection including:
|
|
67
|
+
* - WebSocket connection management
|
|
68
|
+
* - RTCPeerConnection setup and negotiation
|
|
69
|
+
* - Stream state management (loading, playing, error, reconnecting)
|
|
70
|
+
* - Automatic reconnection on connection failure
|
|
71
|
+
* - Proper cleanup on unmount
|
|
72
|
+
*
|
|
73
|
+
* @param config - Configuration object for the WebRTC connection
|
|
74
|
+
* @returns WebRTC player state including video ref, loading state, playing state, error, and mute controls
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```tsx
|
|
78
|
+
* const { videoRef, loading, playing, error } = useWebRTCStream({
|
|
79
|
+
* streamId: 'my-stream-id',
|
|
80
|
+
* hostname: 'media.example.com'
|
|
81
|
+
* });
|
|
82
|
+
*
|
|
83
|
+
* return (
|
|
84
|
+
* <video ref={videoRef} autoPlay playsInline />
|
|
85
|
+
* );
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export const useWebRTCStream = ({
|
|
89
|
+
debug = false,
|
|
90
|
+
fetchStreamId,
|
|
91
|
+
hostname,
|
|
92
|
+
streamId,
|
|
93
|
+
wsPort = DEFAULT_WS_PORT,
|
|
94
|
+
wssPort = DEFAULT_WSS_PORT,
|
|
95
|
+
}: WebRTCConfig): WebRTCPlayerState => {
|
|
96
|
+
const videoRef = useRef<HTMLVideoElement>(null);
|
|
97
|
+
const [loading, setLoading] = useState(true);
|
|
98
|
+
const [error, setError] = useState<string | null>(null);
|
|
99
|
+
const [connectionState, setConnectionState] = useState<WebRTCConnectionState>('idle');
|
|
100
|
+
|
|
101
|
+
const webRTCAdaptorRef = useRef<NativeWebRTCAdaptor | null>(null);
|
|
102
|
+
const reconnectIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
|
103
|
+
const pingIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
|
104
|
+
const isReconnectingRef = useRef(false);
|
|
105
|
+
// True while the component is mounted; lets async init bail after an await if
|
|
106
|
+
// the component has since unmounted (avoids setState/adaptor build post-teardown).
|
|
107
|
+
const isMountedRef = useRef(true);
|
|
108
|
+
// Monotonic token identifying the current connection attempt. Each
|
|
109
|
+
// initializeWebRTC() call claims a fresh token; if a newer attempt starts
|
|
110
|
+
// (reconnect tick, streamId prop change), the older one becomes stale and
|
|
111
|
+
// bails at the next checkpoint instead of building an adaptor or mutating
|
|
112
|
+
// shared state — preventing overlapping adaptors and stale-id connects.
|
|
113
|
+
const initTokenRef = useRef(0);
|
|
114
|
+
// Holds the latest initializeWebRTC so the reconnect loop never calls a stale
|
|
115
|
+
// closure (and so handleError/handleCallback don't need to depend on it).
|
|
116
|
+
/* istanbul ignore next -- @preserve: the default initializer is never invoked; an effect overwrites this ref on first commit, and no reconnect (the only caller) can fire before the mount effect creates an adaptor. */
|
|
117
|
+
const initializeWebRTCRef = useRef<() => void | Promise<void>>(() => undefined);
|
|
118
|
+
// The stream ID the adaptor is currently using. Defaults to the streamId prop
|
|
119
|
+
// and is refreshed by fetchStreamId() before each reconnect attempt.
|
|
120
|
+
const activeStreamIdRef = useRef(streamId);
|
|
121
|
+
// Latest fetchStreamId, held in a ref so the reconnect path always calls the
|
|
122
|
+
// current one without needing it in any dependency array.
|
|
123
|
+
const fetchStreamIdRef = useRef(fetchStreamId);
|
|
124
|
+
fetchStreamIdRef.current = fetchStreamId;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Generates the WebSocket URL based on the current page protocol
|
|
128
|
+
*/
|
|
129
|
+
const getWebSocketUrl = useCallback(() => {
|
|
130
|
+
const isSecure = window.location.protocol === 'https:';
|
|
131
|
+
const protocol = isSecure ? 'wss' : 'ws';
|
|
132
|
+
const port = isSecure ? wssPort : wsPort;
|
|
133
|
+
const url = `${protocol}://${hostname}:${port}${DEFAULT_PATH}`;
|
|
134
|
+
|
|
135
|
+
if (debug) {
|
|
136
|
+
// eslint-disable-next-line no-console
|
|
137
|
+
console.log('[WebRTC] Generated WebSocket URL:', {
|
|
138
|
+
hostname,
|
|
139
|
+
isSecure,
|
|
140
|
+
location: window.location.protocol,
|
|
141
|
+
port,
|
|
142
|
+
protocol,
|
|
143
|
+
url,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return url;
|
|
148
|
+
}, [hostname, wsPort, wssPort, debug]);
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Clears reconnection interval
|
|
152
|
+
*/
|
|
153
|
+
const stopReconnecting = useCallback(() => {
|
|
154
|
+
if (reconnectIntervalRef.current) {
|
|
155
|
+
clearInterval(reconnectIntervalRef.current);
|
|
156
|
+
reconnectIntervalRef.current = null;
|
|
157
|
+
}
|
|
158
|
+
isReconnectingRef.current = false;
|
|
159
|
+
}, []);
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Starts the reconnection loop if one is not already running.
|
|
163
|
+
*
|
|
164
|
+
* Any failure signal (WebSocket error, WebSocket close, or the stream
|
|
165
|
+
* finishing) funnels through here so that a dropped connection always
|
|
166
|
+
* triggers recovery. The loop is idempotent — guarded by isReconnectingRef —
|
|
167
|
+
* and is cleared by stopReconnecting() once the stream re-initializes or
|
|
168
|
+
* starts playing again.
|
|
169
|
+
*
|
|
170
|
+
* The loop retries indefinitely (no max-attempt cap) by design: a live stream
|
|
171
|
+
* can resume minutes after dropping, so we keep attempting every
|
|
172
|
+
* RECONNECT_INTERVAL until it returns or the component unmounts.
|
|
173
|
+
*/
|
|
174
|
+
const startReconnecting = useCallback(() => {
|
|
175
|
+
if (isReconnectingRef.current) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (debug) {
|
|
180
|
+
// eslint-disable-next-line no-console
|
|
181
|
+
console.log(`[WebRTC] Starting reconnection attempts (every ${RECONNECT_INTERVAL}ms)`);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
isReconnectingRef.current = true;
|
|
185
|
+
reconnectIntervalRef.current = setInterval(() => {
|
|
186
|
+
if (debug) {
|
|
187
|
+
// eslint-disable-next-line no-console
|
|
188
|
+
console.log('[WebRTC] 🔄 Attempting to reconnect...');
|
|
189
|
+
}
|
|
190
|
+
// initializeWebRTC sets the 'reconnecting' state while isReconnectingRef is true.
|
|
191
|
+
void initializeWebRTCRef.current();
|
|
192
|
+
}, RECONNECT_INTERVAL);
|
|
193
|
+
}, [debug]);
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Starts ping interval to keep connection alive
|
|
197
|
+
*/
|
|
198
|
+
const startPinging = useCallback(() => {
|
|
199
|
+
if (pingIntervalRef.current) {
|
|
200
|
+
clearInterval(pingIntervalRef.current);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
pingIntervalRef.current = setInterval(() => {
|
|
204
|
+
const activeStreamId = activeStreamIdRef.current;
|
|
205
|
+
if (webRTCAdaptorRef.current && activeStreamId) {
|
|
206
|
+
try {
|
|
207
|
+
webRTCAdaptorRef.current.ping(activeStreamId);
|
|
208
|
+
} catch (err) {
|
|
209
|
+
if (debug) {
|
|
210
|
+
// eslint-disable-next-line no-console
|
|
211
|
+
console.error('Error sending ping:', err);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}, PING_INTERVAL);
|
|
216
|
+
}, [debug]);
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Stops ping interval
|
|
220
|
+
*/
|
|
221
|
+
const stopPinging = useCallback(() => {
|
|
222
|
+
if (pingIntervalRef.current) {
|
|
223
|
+
clearInterval(pingIntervalRef.current);
|
|
224
|
+
pingIntervalRef.current = null;
|
|
225
|
+
}
|
|
226
|
+
}, []);
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Handles WebRTC adaptor callbacks
|
|
230
|
+
*/
|
|
231
|
+
const handleCallback = useCallback(
|
|
232
|
+
(info: string, obj?: unknown) => {
|
|
233
|
+
// A late callback can arrive after unmount (e.g. closeWebSocket() during
|
|
234
|
+
// cleanup triggers onclose). Ignore it so we don't setState or re-arm the
|
|
235
|
+
// reconnect interval on a torn-down component.
|
|
236
|
+
if (!isMountedRef.current) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (debug) {
|
|
241
|
+
// eslint-disable-next-line no-console
|
|
242
|
+
console.log(`[WebRTC] Callback: ${info}`, obj);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
switch (info) {
|
|
246
|
+
case 'initialized':
|
|
247
|
+
if (debug) {
|
|
248
|
+
// eslint-disable-next-line no-console
|
|
249
|
+
console.log('[WebRTC] ✅ Initialized - WebSocket connected, starting playback');
|
|
250
|
+
}
|
|
251
|
+
setConnectionState('connected');
|
|
252
|
+
setLoading(true);
|
|
253
|
+
stopReconnecting();
|
|
254
|
+
startPinging();
|
|
255
|
+
// Start playing the stream using the ID the adaptor connected with
|
|
256
|
+
if (webRTCAdaptorRef.current && activeStreamIdRef.current) {
|
|
257
|
+
if (debug) {
|
|
258
|
+
// eslint-disable-next-line no-console
|
|
259
|
+
console.log(`[WebRTC] Calling play() for streamId: ${activeStreamIdRef.current}`);
|
|
260
|
+
}
|
|
261
|
+
webRTCAdaptorRef.current.play(activeStreamIdRef.current);
|
|
262
|
+
}
|
|
263
|
+
break;
|
|
264
|
+
|
|
265
|
+
case 'play_started':
|
|
266
|
+
if (debug) {
|
|
267
|
+
// eslint-disable-next-line no-console
|
|
268
|
+
console.log('[WebRTC] ✅ Play started - Stream is now playing');
|
|
269
|
+
}
|
|
270
|
+
setConnectionState('playing');
|
|
271
|
+
setLoading(false);
|
|
272
|
+
// setPlaying(true);
|
|
273
|
+
setError(null);
|
|
274
|
+
stopReconnecting();
|
|
275
|
+
break;
|
|
276
|
+
|
|
277
|
+
case 'play_finished':
|
|
278
|
+
if (debug) {
|
|
279
|
+
// eslint-disable-next-line no-console
|
|
280
|
+
console.log('[WebRTC] ⚠️ Play finished - Stream ended');
|
|
281
|
+
}
|
|
282
|
+
setConnectionState('error');
|
|
283
|
+
setError('Stream ended');
|
|
284
|
+
// A finished stream is treated as a recoverable failure: the
|
|
285
|
+
// stream may simply have restarted on the server. Attempt to
|
|
286
|
+
// reconnect rather than leaving the player dead.
|
|
287
|
+
startReconnecting();
|
|
288
|
+
break;
|
|
289
|
+
|
|
290
|
+
case 'closed':
|
|
291
|
+
if (debug) {
|
|
292
|
+
// eslint-disable-next-line no-console
|
|
293
|
+
console.log('[WebRTC] ❌ Connection closed');
|
|
294
|
+
}
|
|
295
|
+
setConnectionState('error');
|
|
296
|
+
setError('Connection closed');
|
|
297
|
+
// A dropped WebSocket is reported via callback('closed'), NOT
|
|
298
|
+
// callbackError, so the reconnect loop must be started here too
|
|
299
|
+
// — otherwise a network failure leaves the player stuck.
|
|
300
|
+
startReconnecting();
|
|
301
|
+
break;
|
|
302
|
+
|
|
303
|
+
case 'publish_started':
|
|
304
|
+
case 'publish_finished':
|
|
305
|
+
case 'ice_connection_state_changed':
|
|
306
|
+
case 'updated_stats':
|
|
307
|
+
case 'data_received':
|
|
308
|
+
default:
|
|
309
|
+
if (debug) {
|
|
310
|
+
// eslint-disable-next-line no-console
|
|
311
|
+
console.log(`[WebRTC] Unhandled callback: ${info}`, obj);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
[debug, startPinging, stopReconnecting, startReconnecting]
|
|
316
|
+
);
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Handles WebRTC adaptor errors
|
|
320
|
+
*/
|
|
321
|
+
const handleError = useCallback(
|
|
322
|
+
(errorMessage: string, errorObject?: unknown) => {
|
|
323
|
+
// Ignore late errors from an adaptor that outlived the component.
|
|
324
|
+
if (!isMountedRef.current) {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// eslint-disable-next-line no-console
|
|
329
|
+
console.error('[WebRTC] ❌ Error:', errorMessage, errorObject);
|
|
330
|
+
setConnectionState('error');
|
|
331
|
+
setLoading(false);
|
|
332
|
+
setError(toFriendlyError(errorMessage));
|
|
333
|
+
|
|
334
|
+
// Start reconnection attempts if not already reconnecting
|
|
335
|
+
startReconnecting();
|
|
336
|
+
},
|
|
337
|
+
[startReconnecting]
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Initializes the WebRTC adaptor
|
|
342
|
+
*/
|
|
343
|
+
const initializeWebRTC = useCallback(async () => {
|
|
344
|
+
if (!activeStreamIdRef.current) {
|
|
345
|
+
// eslint-disable-next-line no-console
|
|
346
|
+
console.error('[WebRTC] ❌ No stream ID provided');
|
|
347
|
+
setError('No stream ID provided');
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Claim this attempt. Any later attempt bumps the token, marking this one
|
|
352
|
+
// stale. `isCurrent()` is checked after every await so a superseded or
|
|
353
|
+
// unmounted attempt bails before mutating shared state / building an adaptor.
|
|
354
|
+
const token = ++initTokenRef.current;
|
|
355
|
+
const isCurrent = () => token === initTokenRef.current && isMountedRef.current;
|
|
356
|
+
|
|
357
|
+
// Clean up existing adaptor (using the ID it was created with, before we
|
|
358
|
+
// potentially swap in a freshly fetched one below).
|
|
359
|
+
if (webRTCAdaptorRef.current) {
|
|
360
|
+
if (debug) {
|
|
361
|
+
// eslint-disable-next-line no-console
|
|
362
|
+
console.log('[WebRTC] Cleaning up existing adaptor');
|
|
363
|
+
}
|
|
364
|
+
try {
|
|
365
|
+
stopPinging();
|
|
366
|
+
webRTCAdaptorRef.current.stop(activeStreamIdRef.current);
|
|
367
|
+
webRTCAdaptorRef.current.closeWebSocket();
|
|
368
|
+
} catch (err) {
|
|
369
|
+
// eslint-disable-next-line no-console
|
|
370
|
+
console.error('[WebRTC] Error cleaning up previous adaptor:', err);
|
|
371
|
+
}
|
|
372
|
+
webRTCAdaptorRef.current = null;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Preserve the 'reconnecting' state across the rebuild so the UI can
|
|
376
|
+
// surface it; a first-time connect uses 'connecting'.
|
|
377
|
+
const reconnecting = isReconnectingRef.current;
|
|
378
|
+
setConnectionState(reconnecting ? 'reconnecting' : 'connecting');
|
|
379
|
+
// On a reconnect tick keep `loading` false: the error overlay (and its
|
|
380
|
+
// "Attempting to reconnect…" caption) is gated behind `!loading`, and the
|
|
381
|
+
// failure handler that started the loop has already set `error`, so leaving
|
|
382
|
+
// loading false is what makes the reconnecting UI visible. Only a first-time
|
|
383
|
+
// connect shows the loading spinner.
|
|
384
|
+
setLoading(!reconnecting);
|
|
385
|
+
|
|
386
|
+
// On reconnect, give the host a chance to supply a fresh stream ID — a
|
|
387
|
+
// restarted stream is usually issued a new ID, so reusing the old one
|
|
388
|
+
// would just reconnect to a dead stream. Bounded by a timeout so a hung
|
|
389
|
+
// callback can't wedge the reconnect loop.
|
|
390
|
+
if (isReconnectingRef.current && fetchStreamIdRef.current) {
|
|
391
|
+
try {
|
|
392
|
+
const freshStreamId = await withTimeout(fetchStreamIdRef.current(), FETCH_STREAM_ID_TIMEOUT);
|
|
393
|
+
// A newer attempt (e.g. a streamId prop change) may have superseded
|
|
394
|
+
// us during the await. Don't clobber its ID or continue this build.
|
|
395
|
+
if (!isCurrent()) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
if (freshStreamId) {
|
|
399
|
+
if (debug && freshStreamId !== activeStreamIdRef.current) {
|
|
400
|
+
// eslint-disable-next-line no-console
|
|
401
|
+
console.log(`[WebRTC] Refreshed stream ID: ${activeStreamIdRef.current} -> ${freshStreamId}`);
|
|
402
|
+
}
|
|
403
|
+
activeStreamIdRef.current = freshStreamId;
|
|
404
|
+
}
|
|
405
|
+
} catch (err) {
|
|
406
|
+
// eslint-disable-next-line no-console
|
|
407
|
+
console.error('[WebRTC] fetchStreamId failed, reusing current stream ID:', err);
|
|
408
|
+
if (!isCurrent()) {
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// Final checkpoint before building: bail if unmounted or superseded.
|
|
415
|
+
if (!isCurrent()) {
|
|
416
|
+
if (debug) {
|
|
417
|
+
// eslint-disable-next-line no-console
|
|
418
|
+
console.log('[WebRTC] Initialization superseded or unmounted, aborting');
|
|
419
|
+
}
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
const activeStreamId = activeStreamIdRef.current;
|
|
424
|
+
|
|
425
|
+
if (debug) {
|
|
426
|
+
// eslint-disable-next-line no-console
|
|
427
|
+
console.log(`[WebRTC] 🚀 Initializing WebRTC for streamId: ${activeStreamId}`);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
try {
|
|
431
|
+
const websocketUrl = getWebSocketUrl();
|
|
432
|
+
|
|
433
|
+
// Ensure video element has an ID before creating adaptor
|
|
434
|
+
if (videoRef.current && !videoRef.current.id) {
|
|
435
|
+
videoRef.current.id = 'webrtc-video-' + activeStreamId;
|
|
436
|
+
}
|
|
437
|
+
const videoId = videoRef.current?.id || 'webrtc-video';
|
|
438
|
+
|
|
439
|
+
if (debug) {
|
|
440
|
+
// eslint-disable-next-line no-console
|
|
441
|
+
console.log('[WebRTC] Creating WebRTCAdaptor with config:', {
|
|
442
|
+
isPlayMode: true,
|
|
443
|
+
remoteVideoId: videoId,
|
|
444
|
+
streamId: activeStreamId,
|
|
445
|
+
websocket_url: websocketUrl,
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
webRTCAdaptorRef.current = new NativeWebRTCAdaptor({
|
|
450
|
+
callback: handleCallback,
|
|
451
|
+
callbackError: handleError,
|
|
452
|
+
debug,
|
|
453
|
+
peerconnection_config: {
|
|
454
|
+
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
|
|
455
|
+
},
|
|
456
|
+
remoteVideoId: videoId,
|
|
457
|
+
sdp_constraints: {
|
|
458
|
+
offerToReceiveAudio: true,
|
|
459
|
+
offerToReceiveVideo: true,
|
|
460
|
+
},
|
|
461
|
+
websocket_url: websocketUrl,
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
if (debug) {
|
|
465
|
+
// eslint-disable-next-line no-console
|
|
466
|
+
console.log('[WebRTC] ✅ WebRTCAdaptor created, waiting for connection...');
|
|
467
|
+
}
|
|
468
|
+
} catch (err) {
|
|
469
|
+
// eslint-disable-next-line no-console
|
|
470
|
+
console.error('[WebRTC] ❌ Failed to initialize WebRTC:', err);
|
|
471
|
+
handleError('Failed to initialize WebRTC', err);
|
|
472
|
+
}
|
|
473
|
+
}, [debug, getWebSocketUrl, handleCallback, handleError, stopPinging]);
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Track mount status so async init can bail after an await once the component
|
|
477
|
+
* has unmounted. Kept separate from the streamId-scoped cleanup effect below
|
|
478
|
+
* so a prop change never flips this to unmounted.
|
|
479
|
+
*/
|
|
480
|
+
useEffect(() => {
|
|
481
|
+
isMountedRef.current = true;
|
|
482
|
+
return () => {
|
|
483
|
+
isMountedRef.current = false;
|
|
484
|
+
};
|
|
485
|
+
}, []);
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Keep the ref pointed at the latest initializeWebRTC so the reconnect loop
|
|
489
|
+
* always reconnects with the current streamId/config rather than a closure
|
|
490
|
+
* captured when the loop first started.
|
|
491
|
+
*/
|
|
492
|
+
useEffect(() => {
|
|
493
|
+
initializeWebRTCRef.current = initializeWebRTC;
|
|
494
|
+
}, [initializeWebRTC]);
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Initialize WebRTC connection on mount or when streamId changes
|
|
498
|
+
*/
|
|
499
|
+
useEffect(() => {
|
|
500
|
+
if (streamId) {
|
|
501
|
+
if (debug) {
|
|
502
|
+
// eslint-disable-next-line no-console
|
|
503
|
+
console.log('[WebRTC] StreamId changed or component mounted, scheduling initialization');
|
|
504
|
+
}
|
|
505
|
+
// A streamId prop change is authoritative and supersedes any ID
|
|
506
|
+
// previously fetched during reconnection.
|
|
507
|
+
activeStreamIdRef.current = streamId;
|
|
508
|
+
// Small delay to ensure video element is mounted
|
|
509
|
+
const timeoutId = setTimeout(() => {
|
|
510
|
+
void initializeWebRTC();
|
|
511
|
+
}, 100);
|
|
512
|
+
|
|
513
|
+
return () => {
|
|
514
|
+
clearTimeout(timeoutId);
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
return undefined;
|
|
518
|
+
}, [streamId, initializeWebRTC, debug]);
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Cleanup on unmount
|
|
522
|
+
*/
|
|
523
|
+
useEffect(() => {
|
|
524
|
+
return () => {
|
|
525
|
+
if (debug) {
|
|
526
|
+
// eslint-disable-next-line no-console
|
|
527
|
+
console.log('[WebRTC] 🧹 Cleaning up on unmount');
|
|
528
|
+
}
|
|
529
|
+
stopReconnecting();
|
|
530
|
+
stopPinging();
|
|
531
|
+
|
|
532
|
+
if (webRTCAdaptorRef.current && activeStreamIdRef.current) {
|
|
533
|
+
try {
|
|
534
|
+
webRTCAdaptorRef.current.stop(activeStreamIdRef.current);
|
|
535
|
+
webRTCAdaptorRef.current.closeWebSocket();
|
|
536
|
+
if (debug) {
|
|
537
|
+
// eslint-disable-next-line no-console
|
|
538
|
+
console.log('[WebRTC] ✅ Cleanup complete');
|
|
539
|
+
}
|
|
540
|
+
} catch (err) {
|
|
541
|
+
// eslint-disable-next-line no-console
|
|
542
|
+
console.error('[WebRTC] Error during cleanup:', err);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
webRTCAdaptorRef.current = null;
|
|
547
|
+
};
|
|
548
|
+
}, [streamId, debug, stopReconnecting, stopPinging]);
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Assign the stream to the video element when it's available
|
|
552
|
+
*/
|
|
553
|
+
useEffect(() => {
|
|
554
|
+
if (videoRef.current && webRTCAdaptorRef.current) {
|
|
555
|
+
const remoteVideo = videoRef.current;
|
|
556
|
+
|
|
557
|
+
// The Ant Media adaptor will set the srcObject automatically
|
|
558
|
+
// We just need to ensure the video element has the correct ID
|
|
559
|
+
if (!remoteVideo.id) {
|
|
560
|
+
remoteVideo.id = 'webrtc-video-' + streamId;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}, [streamId]);
|
|
564
|
+
|
|
565
|
+
return {
|
|
566
|
+
connectionState,
|
|
567
|
+
error,
|
|
568
|
+
loading,
|
|
569
|
+
videoRef: videoRef as React.RefObject<HTMLVideoElement>,
|
|
570
|
+
};
|
|
571
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebRTC video player for streaming from Ant Media Server
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
* Components:
|
|
6
|
+
* - WebRTCPlayer: Complete WebRTC video player with connection management and UI
|
|
7
|
+
*
|
|
8
|
+
* Hooks:
|
|
9
|
+
* - useWebRTCStream: Custom hook for managing WebRTC stream connections
|
|
10
|
+
*
|
|
11
|
+
* Types:
|
|
12
|
+
* - WebRTCPlayerProps: Props for the WebRTCPlayer component
|
|
13
|
+
* - WebRTCConfig: Configuration for WebRTC connections
|
|
14
|
+
* - WebRTCPlayerState: State returned by useWebRTCStream hook
|
|
15
|
+
* - WebRTCConnectionState: Connection state enum
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export { WebRTCPlayer } from './WebRTCPlayer';
|
|
19
|
+
export type { WebRTCPlayerProps } from './WebRTCPlayer';
|
|
20
|
+
export { useWebRTCStream } from './hooks/useWebRTCStream';
|
|
21
|
+
export type { WebRTCConfig, WebRTCPlayerState, WebRTCConnectionState } from './types';
|
|
22
|
+
export { DEFAULT_WS_PORT, DEFAULT_WSS_PORT, DEFAULT_PATH, RECONNECT_INTERVAL, PING_INTERVAL } from './types';
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration constants for WebRTC player
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_WS_PORT = 5080;
|
|
5
|
+
export const DEFAULT_WSS_PORT = 5443;
|
|
6
|
+
export const DEFAULT_PATH = '/WebRTCAppEE/websocket';
|
|
7
|
+
// Interval between reconnect attempts. The reconnect loop retries indefinitely
|
|
8
|
+
// (no max-attempt cap) by design: a live stream can resume minutes after
|
|
9
|
+
// dropping, so the player keeps attempting until the stream returns or the
|
|
10
|
+
// component unmounts.
|
|
11
|
+
export const RECONNECT_INTERVAL = 5000; // 5 seconds
|
|
12
|
+
export const PING_INTERVAL = 30000; // 30 seconds
|
|
13
|
+
// Cap on how long to wait for a host-supplied fetchStreamId() before falling back
|
|
14
|
+
// to the current ID, so a hung callback can't permanently block reconnection.
|
|
15
|
+
// INVARIANT: must stay strictly below RECONNECT_INTERVAL. The reconnect loop
|
|
16
|
+
// awaits fetchStreamId() on each tick, so a timeout >= the interval would let the
|
|
17
|
+
// next tick start while the previous one is still awaiting, producing overlapping
|
|
18
|
+
// reconnect attempts.
|
|
19
|
+
export const FETCH_STREAM_ID_TIMEOUT = 3000; // 3 seconds
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* WebRTC connection state
|
|
23
|
+
*/
|
|
24
|
+
export type WebRTCConnectionState = 'idle' | 'connecting' | 'connected' | 'playing' | 'error' | 'reconnecting';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Error tokens emitted by NativeWebRTCAdaptor via its callbackError channel.
|
|
28
|
+
* Exported so the adaptor (producer) and the hook's friendly-message map
|
|
29
|
+
* (consumer) reference the same literals and can't silently drift apart — a
|
|
30
|
+
* rename here is a compile error on both sides rather than a silent fallthrough.
|
|
31
|
+
*/
|
|
32
|
+
export const WebRTCErrorToken = {
|
|
33
|
+
failedToCreateAnswer: 'Failed to create answer',
|
|
34
|
+
failedToSetLocalDescription: 'Failed to set local description',
|
|
35
|
+
failedToSetRemoteDescription: 'Failed to set remote description',
|
|
36
|
+
iceConnectionFailed: 'IceConnectionFailed',
|
|
37
|
+
peerConnectionFailed: 'PeerConnectionFailed',
|
|
38
|
+
webSocketError: 'WebSocket error',
|
|
39
|
+
webSocketNotConnected: 'WebSocketNotConnected',
|
|
40
|
+
webSocketNotSupported: 'WebSocketNotSupported',
|
|
41
|
+
} as const;
|
|
42
|
+
|
|
43
|
+
export type WebRTCErrorToken = (typeof WebRTCErrorToken)[keyof typeof WebRTCErrorToken];
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* WebRTC adaptor callback information types
|
|
47
|
+
*/
|
|
48
|
+
export type WebRTCCallbackInfo =
|
|
49
|
+
| 'initialized'
|
|
50
|
+
| 'play_started'
|
|
51
|
+
| 'play_finished'
|
|
52
|
+
| 'publish_started'
|
|
53
|
+
| 'publish_finished'
|
|
54
|
+
| 'closed'
|
|
55
|
+
| 'ice_connection_state_changed'
|
|
56
|
+
| 'updated_stats'
|
|
57
|
+
| 'data_received';
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Configuration for WebRTC player
|
|
61
|
+
*/
|
|
62
|
+
export type WebRTCConfig = {
|
|
63
|
+
/** Whether to enable debug logging */
|
|
64
|
+
debug?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Optional callback invoked before each reconnect attempt to obtain a fresh
|
|
67
|
+
* stream ID. A stream that restarts on the server is often issued a new ID,
|
|
68
|
+
* so reconnecting with the original `streamId` would target a dead stream.
|
|
69
|
+
* Return the latest ID (sync or async); return a falsy value to keep the
|
|
70
|
+
* current one. Errors are swallowed and the current ID is reused.
|
|
71
|
+
*/
|
|
72
|
+
fetchStreamId?: () => string | Promise<string>;
|
|
73
|
+
/** WebRTC server hostname */
|
|
74
|
+
hostname: string;
|
|
75
|
+
/** Stream ID from Ant Media Server */
|
|
76
|
+
streamId: string;
|
|
77
|
+
/** WebSocket port for non-SSL connections */
|
|
78
|
+
wsPort?: number;
|
|
79
|
+
/** WebSocket port for SSL connections */
|
|
80
|
+
wssPort?: number;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* WebRTC player state returned by the hook
|
|
85
|
+
*/
|
|
86
|
+
export type WebRTCPlayerState = {
|
|
87
|
+
/** Current connection state */
|
|
88
|
+
connectionState: WebRTCConnectionState;
|
|
89
|
+
/** Error message if connection failed */
|
|
90
|
+
error: string | null;
|
|
91
|
+
/** Whether the stream is currently loading/connecting */
|
|
92
|
+
loading: boolean;
|
|
93
|
+
/** Reference to attach to video element */
|
|
94
|
+
videoRef: React.RefObject<HTMLVideoElement>;
|
|
95
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './utils';
|