@linktr.ee/messaging-react 4.4.8-rc-1788251276 → 4.5.0-rc-1788325575
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/dist/AttachmentCard-BbsjzdLJ.cjs +2 -0
- package/dist/AttachmentCard-BbsjzdLJ.cjs.map +1 -0
- package/dist/{AttachmentCard-BaZk77fe.js → AttachmentCard-DSekwIOA.js} +125 -136
- package/dist/AttachmentCard-DSekwIOA.js.map +1 -0
- package/dist/{Card-4irOjGaI.cjs → Card-BS6Fza2a.cjs} +2 -2
- package/dist/{Card-4irOjGaI.cjs.map → Card-BS6Fza2a.cjs.map} +1 -1
- package/dist/{Card-BdyQhysm.js → Card-BhwBkgxI.js} +2 -2
- package/dist/{Card-BdyQhysm.js.map → Card-BhwBkgxI.js.map} +1 -1
- package/dist/assets/index.css +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +58 -43
- package/dist/index.js +1366 -1240
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/AttachmentCard/MediaPlayer.tsx +5 -3
- package/src/components/ChannelActionsMenu/index.tsx +4 -13
- package/src/components/ChannelHeader.test.tsx +160 -0
- package/src/components/CustomMessage/StreamAttachmentMessage.test.tsx +33 -0
- package/src/components/CustomMessage/StreamAttachmentMessage.tsx +6 -0
- package/src/components/MessageAttachment/Audio/AudioAttachment.stories.tsx +165 -58
- package/src/components/MessageAttachment/Audio/WaveformAudioRow.test.tsx +155 -0
- package/src/components/MessageAttachment/Audio/WaveformAudioRow.tsx +455 -0
- package/src/components/MessageAttachment/Audio/audioRowRequester.test.ts +24 -0
- package/src/components/MessageAttachment/Audio/audioRowRequester.ts +16 -0
- package/src/components/MessageAttachment/Audio/index.tsx +83 -79
- package/src/components/MessageAttachment/MessageAttachment.test.tsx +169 -81
- package/src/components/MessageAttachment/_shared/DownloadAction.tsx +10 -4
- package/src/components/MessageAttachment/_shared/useIsClient.ts +23 -0
- package/src/components/MessageAttachment/index.tsx +25 -9
- package/src/components/MessageAttachment/types.ts +19 -9
- package/src/components/MessageBubble/components/_shared/BubbleShell.test.tsx +49 -0
- package/src/components/MessageBubble/components/_shared/bubbleTail.test.tsx +59 -0
- package/src/styles.css +120 -0
- package/dist/AttachmentCard-BaZk77fe.js.map +0 -1
- package/dist/AttachmentCard-ZpYg622K.cjs +0 -2
- package/dist/AttachmentCard-ZpYg622K.cjs.map +0 -1
- package/src/components/_shared/Spinner.test.tsx +0 -75
- package/src/components/_shared/Spinner.tsx +0 -51
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("./rolldown-runtime-BocRIvOZ.cjs");let t=require("react");t=e.t(t,1);let n=require("react/jsx-runtime"),r=require("classnames");r=e.t(r,1);let i=require("@phosphor-icons/react");var a=[`linktr.ee`],o=`messaging-attachment-v1_0`;function s(e){try{return new URL(e).hostname.toLowerCase()}catch{return null}}function c(e){return a.some(t=>e===t||e.endsWith(`.${t}`))}function l(e){let t=e?.trim();if(!t)return;let n=s(t);if(!n||!c(n))return t;let r=new URL(t);return r.searchParams.get(`io`)===`true`&&r.searchParams.get(`size`)===o?t:(r.searchParams.set(`io`,`true`),r.searchParams.set(`size`,o),r.toString())}var u=`data-mes-native-player`,d={[u]:``},f=e=>{typeof document>`u`||document.querySelectorAll(`[${u}]`).forEach(t=>{t!==e&&t.pause()})},p=[[/pdf/,`pdf`],[/wordprocessingml|msword|\.doc/,`doc`],[/spreadsheetml|ms-excel|\.xls/,`xls`],[/csv/,`csv`],[/presentationml|ms-powerpoint|\.ppt/,`ppt`],[/zip|x-rar|x-7z|x-tar|x-gzip/,`zip`],[/plain|rtf/,`text`],[/markdown/,`markdown`]];function m(e){return e.startsWith(`video/`)?`video`:e.startsWith(`audio/`)?`audio`:e.startsWith(`image/`)?`image`:`document`}function h(e){let t=p.find(([t])=>t.test(e));return t?t[1]:`generic`}var g={video:i.VideoCameraIcon,audio:i.SpeakerHighIcon,image:i.ImageIcon,document:i.FileIcon},_={pdf:i.FilePdfIcon,doc:i.FileDocIcon,xls:i.FileXlsIcon,csv:i.FileCsvIcon,ppt:i.FilePptIcon,zip:i.FileZipIcon,text:i.FileTextIcon,markdown:i.FileMdIcon,generic:i.FileIcon};function v(e){let t=m(e);return t===`document`?_[h(e)]:g[t]}function y(e){let t=m(e);return t===`document`?h(e):t}function b(e,n){return t.default.createElement(v(e),{"data-testid":`type-icon-${y(e)}`,...n})}function x(){return!1}var S=e=>`touches`in e?e.touches[0]?.clientX??e.changedTouches[0]?.clientX??0:e.clientX,C=({source:e,mimeType:r,poster:a,autoPlay:o=!1,playing:s,loop:c=!1,controls:l=!0,showProgress:u=!1,muted:f=!1,onContainerClick:p})=>{let h=m(r),g=(0,t.useRef)(null),_=(0,t.useRef)(null),v=(0,t.useRef)(null),y=(0,t.useRef)(s),[C,w]=(0,t.useState)(o),[T,E]=(0,t.useState)(0),[D,O]=(0,t.useState)(!1),[k,A]=(0,t.useState)(!1),[j,M]=(0,t.useState)(!1),[N,P]=(0,t.useState)(!1),[F,I]=(0,t.useState)(!0),[L,R]=(0,t.useState)(null),z=(0,t.useCallback)(()=>{M(!1),w(!0)},[]),B=(0,t.useCallback)(e=>{let t=_.current;if(!t)return 0;let n=t.getBoundingClientRect();return Math.max(0,Math.min(1,(S(e)-n.left)/n.width))},[]),V=(0,t.useCallback)(e=>{let t=g.current;t&&t.duration&&(t.currentTime=e*t.duration)},[]),H=e=>{e.stopPropagation(),O(!0);let t=B(e);E(t),V(t)},U=(0,t.useCallback)(e=>{e.key===`ArrowRight`&&V(Math.min(1,T+.05)),e.key===`ArrowLeft`&&V(Math.max(0,T-.05))},[V,T]);(0,t.useEffect)(()=>{s!==void 0&&s!==y.current&&(y.current=s,w(s))},[s]),(0,t.useEffect)(()=>{if(!C){v.current!==null&&(cancelAnimationFrame(v.current),v.current=null);return}let e=()=>{let t=g.current;t&&t.duration&&!D&&E(t.currentTime/t.duration),v.current=requestAnimationFrame(e)};return v.current=requestAnimationFrame(e),()=>{v.current!==null&&cancelAnimationFrame(v.current)}},[C,D]),(0,t.useEffect)(()=>{let e=g.current;e&&(C?e.play().catch(e=>{w(!1),M(!0),x()&&console.debug(`[MediaPlayer] play() failed`,e)}):e.pause())},[C]),(0,t.useEffect)(()=>{if(!D)return;let e=e=>E(B(e)),t=e=>{O(!1),V(B(e))};return window.addEventListener(`mousemove`,e),window.addEventListener(`mouseup`,t),window.addEventListener(`touchmove`,e,{passive:!0}),window.addEventListener(`touchend`,t),()=>{window.removeEventListener(`mousemove`,e),window.removeEventListener(`mouseup`,t),window.removeEventListener(`touchmove`,e),window.removeEventListener(`touchend`,t)}},[D,B,V]);let W=L?{aspectRatio:String(L)}:void 0,G=L?``:` aspect-video`,K=Math.round(T*100);return(0,n.jsxs)(`div`,{role:`button`,tabIndex:0,"data-testid":`media-player`,className:`relative cursor-pointer overflow-hidden bg-black ${G}`,style:W,onClick:e=>{if(p){p(e);return}j||l&&w(e=>!e)},onKeyDown:e=>{if(e.key===`Enter`||e.key===` `){if(e.preventDefault(),p){p(e);return}j||l&&w(e=>!e)}},children:[a&&(h===`audio`||F)&&(0,n.jsx)(`img`,{src:a,alt:``,"data-testid":`media-player-poster`,className:`absolute inset-0 h-full w-full object-cover`}),!a&&(h===`audio`||F)&&(0,n.jsx)(`div`,{"data-testid":`media-player-placeholder`,className:`absolute inset-0 flex items-center justify-center`,children:b(r,{className:`size-12 text-black/20`,weight:`regular`})}),(0,n.jsx)(`div`,{className:`absolute inset-0`,children:h===`audio`?(0,n.jsx)(`audio`,{...d,ref:g,"data-testid":`media-player-audio`,src:e,loop:c,muted:f,style:{width:`100%`,height:`100%`},onLoadStart:()=>P(!0),onCanPlay:()=>{P(!1),I(!1)},onWaiting:()=>P(!0),onPlay:()=>M(!1),onEnded:()=>{c||(w(!1),E(0))},children:(0,n.jsx)(`track`,{kind:`captions`})}):(0,n.jsx)(`video`,{ref:g,"data-testid":`media-player-video`,src:e,loop:c,muted:f,playsInline:!0,style:{width:`100%`,height:`100%`},onLoadStart:()=>P(!0),onCanPlay:()=>{P(!1),I(!1)},onWaiting:()=>P(!0),onPlay:()=>M(!1),onLoadedMetadata:()=>{let e=g.current;e instanceof HTMLVideoElement&&e.videoWidth&&e.videoHeight&&R(e.videoWidth/e.videoHeight)},onEnded:()=>{c||(w(!1),E(0))},children:(0,n.jsx)(`track`,{kind:`captions`})})}),N&&!j&&(0,n.jsx)(`div`,{role:`status`,"aria-label":`Loading media`,className:`absolute inset-0 z-10 flex items-center justify-center`,children:(0,n.jsx)(i.CircleNotchIcon,{className:`size-8 animate-spin text-white/80`,weight:`bold`})}),j&&!l&&(0,n.jsx)(`div`,{className:`absolute inset-0 z-30 flex cursor-pointer items-center justify-center bg-black/35`,role:`button`,tabIndex:0,"aria-label":`Play preview`,onClick:e=>{e.stopPropagation(),z()},onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),e.stopPropagation(),z())},children:(0,n.jsx)(`span`,{className:`flex size-16 items-center justify-center rounded-full bg-white/20 text-white backdrop-blur-sm`,children:(0,n.jsx)(i.PlayIcon,{className:`size-9 translate-x-0.5`,weight:`fill`})})}),u&&!l&&(0,n.jsx)(`div`,{className:`absolute inset-x-0 bottom-0 px-3 pb-2.5 pt-6 bg-gradient-to-t from-black/40 to-transparent`,children:(0,n.jsx)(`div`,{role:`slider`,"aria-label":`Playback position`,"aria-valuenow":K,"aria-valuemin":0,"aria-valuemax":100,tabIndex:0,ref:_,className:`relative flex h-4 w-full cursor-pointer items-center`,onMouseDown:H,onTouchStart:H,onClick:e=>e.stopPropagation(),onKeyDown:U,children:(0,n.jsx)(`div`,{className:`w-full overflow-hidden rounded-full bg-white/30 h-1`,children:(0,n.jsx)(`div`,{className:`h-full rounded-full bg-white`,style:{width:`${K}%`}})})})}),l&&(0,n.jsxs)(`div`,{className:`absolute inset-x-0 bottom-0 flex items-center gap-2 bg-gradient-to-t from-black/60 to-transparent px-3 pb-2.5 pt-6 transition-all duration-200`,children:[(0,n.jsx)(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),w(e=>!e)},className:`shrink-0 text-white`,"aria-label":C?`Pause`:`Play`,children:C?(0,n.jsx)(i.PauseIcon,{className:`size-5`,weight:`fill`}):(0,n.jsx)(i.PlayIcon,{className:`size-5 translate-x-px`,weight:`fill`})}),(0,n.jsxs)(`div`,{role:`slider`,"aria-label":`Playback position`,"aria-valuenow":K,"aria-valuemin":0,"aria-valuemax":100,tabIndex:0,ref:_,className:`relative flex h-4 w-full cursor-pointer items-center`,onMouseDown:H,onTouchStart:H,onClick:e=>e.stopPropagation(),onMouseEnter:()=>A(!0),onMouseLeave:()=>A(!1),onKeyDown:U,children:[(0,n.jsx)(`div`,{className:`w-full overflow-hidden rounded-full bg-white/30 transition-all duration-200 ${k||D?`h-1.5`:`h-1`}`,children:(0,n.jsx)(`div`,{className:`h-full rounded-full bg-white`,style:{width:`${K}%`}})}),(0,n.jsx)(`div`,{"data-testid":`media-player-scrubber-thumb`,className:`absolute size-3 -translate-x-1/2 rounded-full bg-white shadow transition-[opacity,transform] duration-200 ${k||D?`scale-100 opacity-100`:`scale-0 opacity-0`}`,style:{left:`${K}%`}})]})]})]})},w=e=>e===`dark`?`size-12 text-white/20`:`size-12 text-black/20`,T=e=>e===`dark`?`aspect-video overflow-hidden bg-white/10`:`aspect-video overflow-hidden bg-black/5`,E=({mimeType:e,sourceUrl:r,thumbnailUrl:i,title:a,variant:o,mediaPlayerProps:s,containedImage:c=!1})=>{let u=m(e),[d,f]=(0,t.useState)(!1),p=l(r),h=l(i);return r&&(u===`video`||u===`audio`)?(0,n.jsx)(C,{source:r,mimeType:e,poster:h,controls:!0,...s}):r&&u===`image`?c?(0,n.jsx)(`div`,{className:`relative ${T(o)}`,children:(0,n.jsx)(`img`,{src:p??r,alt:a??``,className:`absolute inset-0 h-full w-full object-contain transition-opacity duration-300 ${d?`opacity-100`:`opacity-0`}`,draggable:!1,onLoad:()=>f(!0)})}):(0,n.jsx)(`img`,{src:p??r,alt:a??``,className:`block w-full`,draggable:!1}):r&&u===`document`?i?c?(0,n.jsx)(`div`,{className:`relative ${T(o)}`,children:(0,n.jsx)(`img`,{src:h??i,alt:a??``,className:`absolute inset-0 h-full w-full object-contain transition-opacity duration-300 ${d?`opacity-100`:`opacity-0`}`,draggable:!1,onLoad:()=>f(!0)})}):(0,n.jsx)(`img`,{src:h??i,alt:``,className:`block w-full`,draggable:!1}):(0,n.jsx)(`div`,{className:`flex aspect-video w-full items-center justify-center ${o===`dark`?`bg-white/10`:`bg-black/5`}`,children:b(e,{className:w(o),weight:`regular`})}):i?(0,n.jsx)(`div`,{className:`relative ${T(o)}`,children:(0,n.jsx)(`img`,{src:h??i,alt:a??``,draggable:!1,className:`absolute inset-0 h-full w-full object-cover`})}):(0,n.jsx)(`div`,{className:`flex aspect-video w-full items-center justify-center ${o===`dark`?`bg-white/10`:`bg-black/5`}`,children:b(e,{className:w(o),weight:`regular`})})};Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return E}});
|
|
2
|
+
//# sourceMappingURL=AttachmentCard-BbsjzdLJ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AttachmentCard-BbsjzdLJ.cjs","names":[],"sources":["../src/utils/cdnImageUrl.ts","../src/utils/nativeMediaPlayers.ts","../src/components/AttachmentCard/utils/mimeType.ts","../src/components/AttachmentCard/utils/icons.ts","../src/utils/isDevBuild.ts","../src/components/AttachmentCard/MediaPlayer.tsx","../src/components/AttachmentCard/Thumbnail.tsx"],"sourcesContent":["const LINKTREE_CDN_HOSTS = ['linktr.ee']\n\nconst ATTACHMENT_IMAGE_SIZE_PRESET = 'messaging-attachment-v1_0'\n\nfunction hostnameFromUrl(url: string): string | null {\n try {\n return new URL(url).hostname.toLowerCase()\n } catch {\n return null\n }\n}\n\nfunction isLinktreeCdnHost(hostname: string): boolean {\n return LINKTREE_CDN_HOSTS.some(\n (host) => hostname === host || hostname.endsWith(`.${host}`)\n )\n}\n\nexport function optimizeMessagingAttachmentUrl(\n url: string | undefined | null\n): string | undefined {\n const trimmed = url?.trim()\n if (!trimmed) return undefined\n\n const hostname = hostnameFromUrl(trimmed)\n if (!hostname || !isLinktreeCdnHost(hostname)) return trimmed\n\n const parsedUrl = new URL(trimmed)\n const isAlreadyMessagingOptimized =\n parsedUrl.searchParams.get('io') === 'true' &&\n parsedUrl.searchParams.get('size') === ATTACHMENT_IMAGE_SIZE_PRESET\n\n if (isAlreadyMessagingOptimized) {\n return trimmed\n }\n\n parsedUrl.searchParams.set('io', 'true')\n parsedUrl.searchParams.set('size', ATTACHMENT_IMAGE_SIZE_PRESET)\n\n return parsedUrl.toString()\n}\n","/**\n * Attribute marking every native `<audio>` / `<video>` the toolkit\n * renders on a message surface, so opening one player can silence the\n * others.\n *\n * stream-chat-react's `AudioPlayerPool` — what `useActiveAudioPlayer()`\n * reads — only knows the players *it* mounts, i.e. voice recordings.\n * Everything the toolkit draws itself is a plain native element that\n * never registers there: `MessageAttachment.Audio`, a playable\n * `LinkAttachment` card, and `AttachmentCard`'s `MediaPlayer`. Pausing\n * the pool alone therefore left thread audio sounding underneath an\n * opened video viewer on the production `StreamAttachmentMessage` path,\n * which is exactly the surface the mutual exclusion exists for\n * (MES-1353).\n */\nexport const NATIVE_PLAYER_ATTRIBUTE = 'data-mes-native-player'\n\n/**\n * Spread onto a native player element to enrol it. Keyed off the\n * constant so the marker and the query below can't drift apart.\n */\nexport const nativePlayerProps = { [NATIVE_PLAYER_ATTRIBUTE]: '' } as const\n\n/**\n * Pauses every enrolled player except `except`.\n *\n * No `paused` check: pausing an already-paused element is a no-op per\n * spec, and reading `paused` first would only add a branch that jsdom\n * answers differently from a browser.\n */\nexport const pauseNativeMediaPlayers = (\n except?: HTMLMediaElement | null\n): void => {\n if (typeof document === 'undefined') return\n\n document\n .querySelectorAll<HTMLMediaElement>(`[${NATIVE_PLAYER_ATTRIBUTE}]`)\n .forEach((player) => {\n if (player !== except) player.pause()\n })\n}\n","export type AttachmentSourceType = 'image' | 'audio' | 'video' | 'document'\n\nexport type DocumentIconType =\n | 'pdf'\n | 'doc'\n | 'xls'\n | 'csv'\n | 'ppt'\n | 'zip'\n | 'text'\n | 'markdown'\n | 'generic'\n\nconst DOCUMENT_ICON_PATTERNS: Array<[RegExp, DocumentIconType]> = [\n [/pdf/, 'pdf'],\n [/wordprocessingml|msword|\\.doc/, 'doc'],\n [/spreadsheetml|ms-excel|\\.xls/, 'xls'],\n [/csv/, 'csv'],\n [/presentationml|ms-powerpoint|\\.ppt/, 'ppt'],\n [/zip|x-rar|x-7z|x-tar|x-gzip/, 'zip'],\n [/plain|rtf/, 'text'],\n [/markdown/, 'markdown'],\n]\n\nexport function getSourceType(mimeType: string): AttachmentSourceType {\n if (mimeType.startsWith('video/')) return 'video'\n if (mimeType.startsWith('audio/')) return 'audio'\n if (mimeType.startsWith('image/')) return 'image'\n return 'document'\n}\n\nexport function getDocumentIconType(mimeType: string): DocumentIconType {\n const match = DOCUMENT_ICON_PATTERNS.find(([pattern]) =>\n pattern.test(mimeType)\n )\n return match ? match[1] : 'generic'\n}\n","import {\n FileIcon,\n FileCsvIcon,\n FileDocIcon,\n FileMdIcon,\n FilePdfIcon,\n FilePptIcon,\n FileTextIcon,\n FileXlsIcon,\n FileZipIcon,\n ImageIcon,\n SpeakerHighIcon,\n VideoCameraIcon,\n IconProps,\n} from '@phosphor-icons/react'\nimport React from 'react'\n\nimport { getDocumentIconType, getSourceType } from './mimeType'\nimport type { AttachmentSourceType } from './mimeType'\n\nconst MEDIA_TYPE_ICON: Record<AttachmentSourceType, React.ElementType> = {\n video: VideoCameraIcon,\n audio: SpeakerHighIcon,\n image: ImageIcon,\n document: FileIcon,\n}\n\nconst DOCUMENT_ICON_COMPONENT = {\n pdf: FilePdfIcon,\n doc: FileDocIcon,\n xls: FileXlsIcon,\n csv: FileCsvIcon,\n ppt: FilePptIcon,\n zip: FileZipIcon,\n text: FileTextIcon,\n markdown: FileMdIcon,\n generic: FileIcon,\n} as const\n\nfunction getTypeIcon(mimeType: string): React.ElementType {\n const sourceType = getSourceType(mimeType)\n if (sourceType !== 'document') return MEDIA_TYPE_ICON[sourceType]\n return DOCUMENT_ICON_COMPONENT[getDocumentIconType(mimeType)]\n}\n\nfunction getTypeIconName(mimeType: string): string {\n const sourceType = getSourceType(mimeType)\n if (sourceType !== 'document') return sourceType\n return getDocumentIconType(mimeType)\n}\n\n/** Use instead of `<TypeIcon />` where TypeIcon = getTypeIcon(mime) to satisfy react-hooks/static-components. */\nexport function renderTypeIcon(\n mimeType: string,\n props: IconProps\n): React.ReactElement {\n // Decorative icons: which one was picked is otherwise only visible in a pixel diff.\n return React.createElement(getTypeIcon(mimeType), {\n 'data-testid': `type-icon-${getTypeIconName(mimeType)}`,\n ...props,\n })\n}\n","/**\n * True in Vite dev builds (`import.meta.env.DEV`). Uses a type assertion so\n * `tsc` does not rely on ambient `ImportMeta` merging (vite/client).\n */\nexport function isDevBuild(): boolean {\n return (\n typeof import.meta !== 'undefined' &&\n (import.meta as unknown as { env?: { DEV?: boolean } }).env?.DEV === true\n )\n}\n","import { CircleNotchIcon, PauseIcon, PlayIcon } from '@phosphor-icons/react'\nimport React, { useCallback, useEffect, useRef, useState } from 'react'\n\nimport { isDevBuild } from '../../utils/isDevBuild'\nimport { nativePlayerProps } from '../../utils/nativeMediaPlayers'\n\nimport { renderTypeIcon } from './utils/icons'\nimport { getSourceType } from './utils/mimeType'\n\ntype TouchEventUnion =\n MouseEvent | TouchEvent | React.MouseEvent | React.TouchEvent\n\nconst getClientXFromEvent = (e: TouchEventUnion): number => {\n if ('touches' in e) {\n return e.touches[0]?.clientX ?? e.changedTouches[0]?.clientX ?? 0\n }\n return e.clientX\n}\n\nexport interface MediaPlayerProps {\n source: string\n mimeType: string\n poster?: string\n autoPlay?: boolean\n /** Controlled playing state. When provided, syncs to internal play/pause. */\n playing?: boolean\n loop?: boolean\n controls?: boolean\n showProgress?: boolean\n /** When true, requests muted playback (helps autoplay policies on video). */\n muted?: boolean\n /**\n * When provided, overrides the default click-to-play-toggle behaviour on the\n * player container. The play/pause button (which calls stopPropagation) is\n * unaffected, so inline playback still works.\n */\n onContainerClick?: (e: React.MouseEvent) => void\n}\n\nconst MediaPlayer: React.FC<MediaPlayerProps> = ({\n source,\n mimeType,\n poster,\n autoPlay = false,\n playing: playingProp,\n loop = false,\n controls = true,\n showProgress = false,\n muted = false,\n onContainerClick,\n}) => {\n // --- Derived ---\n const sourceType = getSourceType(mimeType)\n\n // --- Refs ---\n const playerRef = useRef<HTMLMediaElement>(null)\n const trackRef = useRef<HTMLDivElement>(null)\n const rafRef = useRef<number | null>(null)\n const prevPlayingPropRef = useRef(playingProp)\n\n // --- State: playback ---\n const [playing, setPlaying] = useState(autoPlay)\n const [played, setPlayed] = useState(0)\n const [seeking, setSeeking] = useState(false)\n\n // --- State: UI ---\n const [scrubberHovered, setScrubberHovered] = useState(false)\n /** Set when autoplay/play() was rejected so user can start via gesture (no controls UI). */\n const [manualPlayRequired, setManualPlayRequired] = useState(false)\n\n // --- State: loading ---\n const [buffering, setBuffering] = useState(false)\n /** True until the first canPlay fires for the current source — hides controls/spinner behind poster. */\n const [initialLoad, setInitialLoad] = useState(true)\n const [videoAspect, setVideoAspect] = useState<number | null>(null)\n\n // --- Callbacks ---\n const startPlaybackFromGesture = useCallback(() => {\n setManualPlayRequired(false)\n setPlaying(true)\n }, [])\n\n const getFraction = useCallback((e: TouchEventUnion) => {\n const track = trackRef.current\n if (!track) return 0\n const rect = track.getBoundingClientRect()\n return Math.max(\n 0,\n Math.min(1, (getClientXFromEvent(e) - rect.left) / rect.width)\n )\n }, [])\n\n const seekTo = useCallback((fraction: number) => {\n const el = playerRef.current\n if (el && el.duration) el.currentTime = fraction * el.duration\n }, [])\n\n const handleTrackPointerDown = (\n e: React.MouseEvent<HTMLDivElement> | React.TouchEvent<HTMLDivElement>\n ) => {\n e.stopPropagation()\n setSeeking(true)\n const fraction = getFraction(e)\n setPlayed(fraction)\n seekTo(fraction)\n }\n\n const handleScrubberKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.key === 'ArrowRight') seekTo(Math.min(1, played + 0.05))\n if (e.key === 'ArrowLeft') seekTo(Math.max(0, played - 0.05))\n },\n [seekTo, played]\n )\n\n // --- Effects ---\n\n // Sync controlled playing prop to internal state\n useEffect(() => {\n if (\n playingProp !== undefined &&\n playingProp !== prevPlayingPropRef.current\n ) {\n prevPlayingPropRef.current = playingProp\n setPlaying(playingProp)\n }\n }, [playingProp])\n\n // RAF-driven progress updates\n useEffect(() => {\n if (!playing) {\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n }\n return\n }\n const tick = () => {\n const el = playerRef.current\n if (el && el.duration && !seeking) setPlayed(el.currentTime / el.duration)\n rafRef.current = requestAnimationFrame(tick)\n }\n rafRef.current = requestAnimationFrame(tick)\n return () => {\n if (rafRef.current !== null) cancelAnimationFrame(rafRef.current)\n }\n }, [playing, seeking])\n\n // ReactPlayer v3 uses native HTML media elements and does not support a\n // declarative `playing` prop — playback must be driven imperatively.\n useEffect(() => {\n const el = playerRef.current\n if (!el) return\n if (playing) {\n void el.play().catch((err) => {\n setPlaying(false)\n setManualPlayRequired(true)\n if (isDevBuild()) {\n console.debug('[MediaPlayer] play() failed', err)\n }\n })\n } else {\n el.pause()\n }\n }, [playing])\n\n // Global seeking listeners\n useEffect(() => {\n if (!seeking) return\n const onMove = (e: MouseEvent | TouchEvent) => setPlayed(getFraction(e))\n const onUp = (e: MouseEvent | TouchEvent) => {\n setSeeking(false)\n seekTo(getFraction(e))\n }\n window.addEventListener('mousemove', onMove)\n window.addEventListener('mouseup', onUp)\n window.addEventListener('touchmove', onMove, { passive: true })\n window.addEventListener('touchend', onUp)\n return () => {\n window.removeEventListener('mousemove', onMove)\n window.removeEventListener('mouseup', onUp)\n window.removeEventListener('touchmove', onMove)\n window.removeEventListener('touchend', onUp)\n }\n }, [seeking, getFraction, seekTo])\n\n // --- Derived render values ---\n // Use natural aspect ratio once metadata loads, fall back to 16:9 before then.\n const aspectStyle = videoAspect\n ? { aspectRatio: String(videoAspect) }\n : undefined\n const aspectClass = !videoAspect ? ' aspect-video' : ''\n const scrubberPercent = Math.round(played * 100)\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n data-testid=\"media-player\"\n className={`relative cursor-pointer overflow-hidden bg-black ${aspectClass}`}\n style={aspectStyle}\n onClick={(e) => {\n if (onContainerClick) {\n onContainerClick(e)\n return\n }\n if (manualPlayRequired) return\n if (controls) setPlaying((p) => !p)\n }}\n onKeyDown={(e) => {\n if (e.key !== 'Enter' && e.key !== ' ') return\n e.preventDefault()\n if (onContainerClick) {\n onContainerClick(e as unknown as React.MouseEvent)\n return\n }\n if (manualPlayRequired) return\n if (controls) setPlaying((p) => !p)\n }}\n >\n {/* For audio, poster persists as a visual background. For video, hide once loaded. */}\n {poster && (sourceType === 'audio' || initialLoad) && (\n <img\n src={poster}\n alt=\"\"\n data-testid=\"media-player-poster\"\n className=\"absolute inset-0 h-full w-full object-cover\"\n />\n )}\n {!poster && (sourceType === 'audio' || initialLoad) && (\n <div\n data-testid=\"media-player-placeholder\"\n className=\"absolute inset-0 flex items-center justify-center\"\n >\n {renderTypeIcon(mimeType, {\n className: 'size-12 text-black/20',\n weight: 'regular',\n })}\n </div>\n )}\n <div className=\"absolute inset-0\">\n {sourceType === 'audio' ? (\n <audio\n {...nativePlayerProps}\n ref={playerRef as React.RefObject<HTMLAudioElement>}\n data-testid=\"media-player-audio\"\n src={source}\n loop={loop}\n muted={muted}\n style={{ width: '100%', height: '100%' }}\n onLoadStart={() => setBuffering(true)}\n onCanPlay={() => {\n setBuffering(false)\n setInitialLoad(false)\n }}\n onWaiting={() => setBuffering(true)}\n onPlay={() => setManualPlayRequired(false)}\n onEnded={() => {\n if (!loop) {\n setPlaying(false)\n setPlayed(0)\n }\n }}\n >\n <track kind=\"captions\" />\n </audio>\n ) : (\n <video\n ref={playerRef as React.RefObject<HTMLVideoElement>}\n data-testid=\"media-player-video\"\n src={source}\n loop={loop}\n muted={muted}\n playsInline\n style={{ width: '100%', height: '100%' }}\n onLoadStart={() => setBuffering(true)}\n onCanPlay={() => {\n setBuffering(false)\n setInitialLoad(false)\n }}\n onWaiting={() => setBuffering(true)}\n onPlay={() => setManualPlayRequired(false)}\n onLoadedMetadata={() => {\n const el = playerRef.current\n if (\n el instanceof HTMLVideoElement &&\n el.videoWidth &&\n el.videoHeight\n ) {\n setVideoAspect(el.videoWidth / el.videoHeight)\n }\n }}\n onEnded={() => {\n if (!loop) {\n setPlaying(false)\n setPlayed(0)\n }\n }}\n >\n <track kind=\"captions\" />\n </video>\n )}\n </div>\n\n {buffering && !manualPlayRequired && (\n <div\n role=\"status\"\n aria-label=\"Loading media\"\n className=\"absolute inset-0 z-10 flex items-center justify-center\"\n >\n <CircleNotchIcon\n className=\"size-8 animate-spin text-white/80\"\n weight=\"bold\"\n />\n </div>\n )}\n\n {manualPlayRequired && !controls && (\n <div\n className=\"absolute inset-0 z-30 flex cursor-pointer items-center justify-center bg-black/35\"\n role=\"button\"\n tabIndex={0}\n aria-label=\"Play preview\"\n onClick={(e) => {\n e.stopPropagation()\n startPlaybackFromGesture()\n }}\n onKeyDown={(e) => {\n if (e.key !== 'Enter' && e.key !== ' ') return\n e.preventDefault()\n e.stopPropagation()\n startPlaybackFromGesture()\n }}\n >\n <span className=\"flex size-16 items-center justify-center rounded-full bg-white/20 text-white backdrop-blur-sm\">\n <PlayIcon className=\"size-9 translate-x-0.5\" weight=\"fill\" />\n </span>\n </div>\n )}\n\n {showProgress && !controls && (\n <div className=\"absolute inset-x-0 bottom-0 px-3 pb-2.5 pt-6 bg-gradient-to-t from-black/40 to-transparent\">\n <div\n role=\"slider\"\n aria-label=\"Playback position\"\n aria-valuenow={scrubberPercent}\n aria-valuemin={0}\n aria-valuemax={100}\n tabIndex={0}\n ref={trackRef}\n className=\"relative flex h-4 w-full cursor-pointer items-center\"\n onMouseDown={handleTrackPointerDown}\n onTouchStart={handleTrackPointerDown}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={handleScrubberKeyDown}\n >\n <div className=\"w-full overflow-hidden rounded-full bg-white/30 h-1\">\n <div\n className=\"h-full rounded-full bg-white\"\n style={{ width: `${scrubberPercent}%` }}\n />\n </div>\n </div>\n </div>\n )}\n\n {controls && (\n <div className=\"absolute inset-x-0 bottom-0 flex items-center gap-2 bg-gradient-to-t from-black/60 to-transparent px-3 pb-2.5 pt-6 transition-all duration-200\">\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n setPlaying((p) => !p)\n }}\n className=\"shrink-0 text-white\"\n aria-label={playing ? 'Pause' : 'Play'}\n >\n {playing ? (\n <PauseIcon className=\"size-5\" weight=\"fill\" />\n ) : (\n <PlayIcon className=\"size-5 translate-x-px\" weight=\"fill\" />\n )}\n </button>\n\n <div\n role=\"slider\"\n aria-label=\"Playback position\"\n aria-valuenow={scrubberPercent}\n aria-valuemin={0}\n aria-valuemax={100}\n tabIndex={0}\n ref={trackRef}\n className=\"relative flex h-4 w-full cursor-pointer items-center\"\n onMouseDown={handleTrackPointerDown}\n onTouchStart={handleTrackPointerDown}\n onClick={(e) => e.stopPropagation()}\n onMouseEnter={() => setScrubberHovered(true)}\n onMouseLeave={() => setScrubberHovered(false)}\n onKeyDown={handleScrubberKeyDown}\n >\n <div\n className={`w-full overflow-hidden rounded-full bg-white/30 transition-all duration-200 ${scrubberHovered || seeking ? 'h-1.5' : 'h-1'}`}\n >\n <div\n className=\"h-full rounded-full bg-white\"\n style={{ width: `${scrubberPercent}%` }}\n />\n </div>\n <div\n data-testid=\"media-player-scrubber-thumb\"\n className={`absolute size-3 -translate-x-1/2 rounded-full bg-white shadow transition-[opacity,transform] duration-200 ${scrubberHovered || seeking ? 'scale-100 opacity-100' : 'scale-0 opacity-0'}`}\n style={{ left: `${scrubberPercent}%` }}\n />\n </div>\n </div>\n )}\n </div>\n )\n}\n\nexport default MediaPlayer\n","import React, { useState } from 'react'\n\nimport { optimizeMessagingAttachmentUrl } from '../../utils/cdnImageUrl'\n\nimport MediaPlayer, { type MediaPlayerProps } from './MediaPlayer'\nimport { renderTypeIcon } from './utils/icons'\nimport { getSourceType } from './utils/mimeType'\n\nexport type AttachmentThumbnailVariant = 'light' | 'dark'\n\nexport interface AttachmentThumbnailProps {\n mimeType: string\n sourceUrl?: string\n thumbnailUrl?: string\n title?: string\n variant: AttachmentThumbnailVariant\n /** Extra props passed to MediaPlayer when source is video or audio. */\n mediaPlayerProps?: Partial<\n Pick<\n MediaPlayerProps,\n 'autoPlay' | 'loop' | 'muted' | 'controls' | 'onContainerClick'\n >\n >\n /**\n * When true (Visitor unlocked image/document), use aspect-video + object-contain fade-in.\n */\n containedImage?: boolean\n}\n\nconst placeholderIconClass = (variant: AttachmentThumbnailVariant) =>\n variant === 'dark' ? 'size-12 text-white/20' : 'size-12 text-black/20'\n\nconst posterShellClass = (variant: AttachmentThumbnailVariant) =>\n variant === 'dark'\n ? 'aspect-video overflow-hidden bg-white/10'\n : 'aspect-video overflow-hidden bg-black/5'\n\n/**\n * Renders the media preview area for attachment cards (LockedAttachment, MediaMessage).\n * Overlays (dim, lock, eye toggle) are composed by the parent.\n */\nconst AttachmentThumbnail: React.FC<AttachmentThumbnailProps> = ({\n mimeType,\n sourceUrl,\n thumbnailUrl,\n title,\n variant,\n mediaPlayerProps,\n containedImage = false,\n}) => {\n const sourceType = getSourceType(mimeType)\n const [sourceReady, setSourceReady] = useState(false)\n const optimizedSourceUrl = optimizeMessagingAttachmentUrl(sourceUrl)\n const optimizedThumbnailUrl = optimizeMessagingAttachmentUrl(thumbnailUrl)\n\n if (sourceUrl && (sourceType === 'video' || sourceType === 'audio')) {\n return (\n <MediaPlayer\n source={sourceUrl}\n mimeType={mimeType}\n poster={optimizedThumbnailUrl}\n controls\n {...mediaPlayerProps}\n />\n )\n }\n\n if (sourceUrl && sourceType === 'image') {\n if (containedImage) {\n return (\n <div className={`relative ${posterShellClass(variant)}`}>\n <img\n src={optimizedSourceUrl ?? sourceUrl}\n alt={title ?? ''}\n className={`absolute inset-0 h-full w-full object-contain transition-opacity duration-300 ${sourceReady ? 'opacity-100' : 'opacity-0'}`}\n draggable={false}\n onLoad={() => setSourceReady(true)}\n />\n </div>\n )\n }\n return (\n <img\n src={optimizedSourceUrl ?? sourceUrl}\n alt={title ?? ''}\n className=\"block w-full\"\n draggable={false}\n />\n )\n }\n\n if (sourceUrl && sourceType === 'document') {\n if (thumbnailUrl) {\n if (containedImage) {\n return (\n <div className={`relative ${posterShellClass(variant)}`}>\n <img\n src={optimizedThumbnailUrl ?? thumbnailUrl}\n alt={title ?? ''}\n className={`absolute inset-0 h-full w-full object-contain transition-opacity duration-300 ${sourceReady ? 'opacity-100' : 'opacity-0'}`}\n draggable={false}\n onLoad={() => setSourceReady(true)}\n />\n </div>\n )\n }\n return (\n <img\n src={optimizedThumbnailUrl ?? thumbnailUrl}\n alt=\"\"\n className=\"block w-full\"\n draggable={false}\n />\n )\n }\n return (\n <div\n className={`flex aspect-video w-full items-center justify-center ${variant === 'dark' ? 'bg-white/10' : 'bg-black/5'}`}\n >\n {renderTypeIcon(mimeType, {\n className: placeholderIconClass(variant),\n weight: 'regular',\n })}\n </div>\n )\n }\n\n // Poster-only or empty (no sourceUrl)\n if (thumbnailUrl) {\n return (\n <div className={`relative ${posterShellClass(variant)}`}>\n <img\n src={optimizedThumbnailUrl ?? thumbnailUrl}\n alt={title ?? ''}\n draggable={false}\n className=\"absolute inset-0 h-full w-full object-cover\"\n />\n </div>\n )\n }\n\n return (\n <div\n className={`flex aspect-video w-full items-center justify-center ${variant === 'dark' ? 'bg-white/10' : 'bg-black/5'}`}\n >\n {renderTypeIcon(mimeType, {\n className: placeholderIconClass(variant),\n weight: 'regular',\n })}\n </div>\n )\n}\n\nexport default AttachmentThumbnail\n"],"mappings":"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"}
|
|
@@ -1,45 +1,34 @@
|
|
|
1
1
|
import e, { useCallback as t, useEffect as n, useRef as r, useState as i } from "react";
|
|
2
2
|
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
3
|
-
import
|
|
4
|
-
import { CircleNotchIcon as
|
|
5
|
-
//#region src/
|
|
6
|
-
var C =
|
|
7
|
-
|
|
8
|
-
md: "size-5",
|
|
9
|
-
lg: "size-8"
|
|
10
|
-
}, w = {
|
|
11
|
-
inherit: void 0,
|
|
12
|
-
"on-media": "text-white/80"
|
|
13
|
-
}, T = ({ size: e = "sm", tone: t = "inherit", icon: n = c, weight: r = "bold", "aria-hidden": i, className: o }) => /* @__PURE__ */ a(n, {
|
|
14
|
-
className: s("animate-spin", C[e], w[t], o),
|
|
15
|
-
weight: r,
|
|
16
|
-
"aria-hidden": i
|
|
17
|
-
}), E = ["linktr.ee"], D = "messaging-attachment-v1_0";
|
|
18
|
-
function O(e) {
|
|
3
|
+
import "classnames";
|
|
4
|
+
import { CircleNotchIcon as s, FileCsvIcon as c, FileDocIcon as l, FileIcon as u, FileMdIcon as d, FilePdfIcon as f, FilePptIcon as p, FileTextIcon as m, FileXlsIcon as h, FileZipIcon as g, ImageIcon as _, PauseIcon as v, PlayIcon as y, SpeakerHighIcon as b, VideoCameraIcon as x } from "@phosphor-icons/react";
|
|
5
|
+
//#region src/utils/cdnImageUrl.ts
|
|
6
|
+
var S = ["linktr.ee"], C = "messaging-attachment-v1_0";
|
|
7
|
+
function w(e) {
|
|
19
8
|
try {
|
|
20
9
|
return new URL(e).hostname.toLowerCase();
|
|
21
10
|
} catch {
|
|
22
11
|
return null;
|
|
23
12
|
}
|
|
24
13
|
}
|
|
25
|
-
function
|
|
26
|
-
return
|
|
14
|
+
function T(e) {
|
|
15
|
+
return S.some((t) => e === t || e.endsWith(`.${t}`));
|
|
27
16
|
}
|
|
28
|
-
function
|
|
17
|
+
function E(e) {
|
|
29
18
|
let t = e?.trim();
|
|
30
19
|
if (!t) return;
|
|
31
|
-
let n =
|
|
32
|
-
if (!n || !
|
|
20
|
+
let n = w(t);
|
|
21
|
+
if (!n || !T(n)) return t;
|
|
33
22
|
let r = new URL(t);
|
|
34
|
-
return r.searchParams.get("io") === "true" && r.searchParams.get("size") ===
|
|
23
|
+
return r.searchParams.get("io") === "true" && r.searchParams.get("size") === C ? t : (r.searchParams.set("io", "true"), r.searchParams.set("size", C), r.toString());
|
|
35
24
|
}
|
|
36
25
|
//#endregion
|
|
37
26
|
//#region src/utils/nativeMediaPlayers.ts
|
|
38
|
-
var
|
|
39
|
-
typeof document > "u" || document.querySelectorAll(`[${
|
|
27
|
+
var D = "data-mes-native-player", O = { [D]: "" }, k = (e) => {
|
|
28
|
+
typeof document > "u" || document.querySelectorAll(`[${D}]`).forEach((t) => {
|
|
40
29
|
t !== e && t.pause();
|
|
41
30
|
});
|
|
42
|
-
},
|
|
31
|
+
}, A = [
|
|
43
32
|
[/pdf/, "pdf"],
|
|
44
33
|
[/wordprocessingml|msword|\.doc/, "doc"],
|
|
45
34
|
[/spreadsheetml|ms-excel|\.xls/, "xls"],
|
|
@@ -49,103 +38,103 @@ var j = "data-mes-native-player", M = { [j]: "" }, N = (e) => {
|
|
|
49
38
|
[/plain|rtf/, "text"],
|
|
50
39
|
[/markdown/, "markdown"]
|
|
51
40
|
];
|
|
52
|
-
function
|
|
41
|
+
function j(e) {
|
|
53
42
|
return e.startsWith("video/") ? "video" : e.startsWith("audio/") ? "audio" : e.startsWith("image/") ? "image" : "document";
|
|
54
43
|
}
|
|
55
|
-
function
|
|
56
|
-
let t =
|
|
44
|
+
function M(e) {
|
|
45
|
+
let t = A.find(([t]) => t.test(e));
|
|
57
46
|
return t ? t[1] : "generic";
|
|
58
47
|
}
|
|
59
48
|
//#endregion
|
|
60
49
|
//#region src/components/AttachmentCard/utils/icons.ts
|
|
61
|
-
var
|
|
62
|
-
video:
|
|
63
|
-
audio:
|
|
64
|
-
image:
|
|
65
|
-
document:
|
|
66
|
-
},
|
|
67
|
-
pdf:
|
|
68
|
-
doc:
|
|
69
|
-
xls:
|
|
70
|
-
csv:
|
|
71
|
-
ppt:
|
|
72
|
-
zip:
|
|
73
|
-
text:
|
|
74
|
-
markdown:
|
|
75
|
-
generic:
|
|
50
|
+
var N = {
|
|
51
|
+
video: x,
|
|
52
|
+
audio: b,
|
|
53
|
+
image: _,
|
|
54
|
+
document: u
|
|
55
|
+
}, P = {
|
|
56
|
+
pdf: f,
|
|
57
|
+
doc: l,
|
|
58
|
+
xls: h,
|
|
59
|
+
csv: c,
|
|
60
|
+
ppt: p,
|
|
61
|
+
zip: g,
|
|
62
|
+
text: m,
|
|
63
|
+
markdown: d,
|
|
64
|
+
generic: u
|
|
76
65
|
};
|
|
77
|
-
function
|
|
78
|
-
let t =
|
|
79
|
-
return t === "document" ?
|
|
66
|
+
function F(e) {
|
|
67
|
+
let t = j(e);
|
|
68
|
+
return t === "document" ? P[M(e)] : N[t];
|
|
80
69
|
}
|
|
81
|
-
function
|
|
82
|
-
let t =
|
|
83
|
-
return t === "document" ?
|
|
70
|
+
function I(e) {
|
|
71
|
+
let t = j(e);
|
|
72
|
+
return t === "document" ? M(e) : t;
|
|
84
73
|
}
|
|
85
|
-
function
|
|
86
|
-
return e.createElement(
|
|
87
|
-
"data-testid": `type-icon-${
|
|
74
|
+
function L(t, n) {
|
|
75
|
+
return e.createElement(F(t), {
|
|
76
|
+
"data-testid": `type-icon-${I(t)}`,
|
|
88
77
|
...n
|
|
89
78
|
});
|
|
90
79
|
}
|
|
91
80
|
//#endregion
|
|
92
81
|
//#region src/utils/isDevBuild.ts
|
|
93
|
-
function
|
|
82
|
+
function R() {
|
|
94
83
|
return !1;
|
|
95
84
|
}
|
|
96
85
|
//#endregion
|
|
97
86
|
//#region src/components/AttachmentCard/MediaPlayer.tsx
|
|
98
|
-
var
|
|
99
|
-
let
|
|
100
|
-
|
|
87
|
+
var z = (e) => "touches" in e ? e.touches[0]?.clientX ?? e.changedTouches[0]?.clientX ?? 0 : e.clientX, B = ({ source: e, mimeType: c, poster: l, autoPlay: u = !1, playing: d, loop: f = !1, controls: p = !0, showProgress: m = !1, muted: h = !1, onContainerClick: g }) => {
|
|
88
|
+
let _ = j(c), b = r(null), x = r(null), S = r(null), C = r(d), [w, T] = i(u), [E, D] = i(0), [k, A] = i(!1), [M, N] = i(!1), [P, F] = i(!1), [I, B] = i(!1), [V, H] = i(!0), [U, W] = i(null), G = t(() => {
|
|
89
|
+
F(!1), T(!0);
|
|
101
90
|
}, []), K = t((e) => {
|
|
102
|
-
let t =
|
|
91
|
+
let t = x.current;
|
|
103
92
|
if (!t) return 0;
|
|
104
93
|
let n = t.getBoundingClientRect();
|
|
105
|
-
return Math.max(0, Math.min(1, (
|
|
94
|
+
return Math.max(0, Math.min(1, (z(e) - n.left) / n.width));
|
|
106
95
|
}, []), q = t((e) => {
|
|
107
|
-
let t =
|
|
96
|
+
let t = b.current;
|
|
108
97
|
t && t.duration && (t.currentTime = e * t.duration);
|
|
109
98
|
}, []), J = (e) => {
|
|
110
|
-
e.stopPropagation(),
|
|
99
|
+
e.stopPropagation(), A(!0);
|
|
111
100
|
let t = K(e);
|
|
112
101
|
D(t), q(t);
|
|
113
102
|
}, Y = t((e) => {
|
|
114
103
|
e.key === "ArrowRight" && q(Math.min(1, E + .05)), e.key === "ArrowLeft" && q(Math.max(0, E - .05));
|
|
115
104
|
}, [q, E]);
|
|
116
105
|
n(() => {
|
|
117
|
-
|
|
118
|
-
}, [
|
|
119
|
-
if (!
|
|
120
|
-
|
|
106
|
+
d !== void 0 && d !== C.current && (C.current = d, T(d));
|
|
107
|
+
}, [d]), n(() => {
|
|
108
|
+
if (!w) {
|
|
109
|
+
S.current !== null && (cancelAnimationFrame(S.current), S.current = null);
|
|
121
110
|
return;
|
|
122
111
|
}
|
|
123
112
|
let e = () => {
|
|
124
|
-
let t =
|
|
125
|
-
t && t.duration && !
|
|
113
|
+
let t = b.current;
|
|
114
|
+
t && t.duration && !k && D(t.currentTime / t.duration), S.current = requestAnimationFrame(e);
|
|
126
115
|
};
|
|
127
|
-
return
|
|
128
|
-
|
|
116
|
+
return S.current = requestAnimationFrame(e), () => {
|
|
117
|
+
S.current !== null && cancelAnimationFrame(S.current);
|
|
129
118
|
};
|
|
130
|
-
}, [
|
|
131
|
-
let e =
|
|
132
|
-
e && (
|
|
133
|
-
|
|
119
|
+
}, [w, k]), n(() => {
|
|
120
|
+
let e = b.current;
|
|
121
|
+
e && (w ? e.play().catch((e) => {
|
|
122
|
+
T(!1), F(!0), R() && console.debug("[MediaPlayer] play() failed", e);
|
|
134
123
|
}) : e.pause());
|
|
135
|
-
}, [
|
|
136
|
-
if (!
|
|
124
|
+
}, [w]), n(() => {
|
|
125
|
+
if (!k) return;
|
|
137
126
|
let e = (e) => D(K(e)), t = (e) => {
|
|
138
|
-
|
|
127
|
+
A(!1), q(K(e));
|
|
139
128
|
};
|
|
140
129
|
return window.addEventListener("mousemove", e), window.addEventListener("mouseup", t), window.addEventListener("touchmove", e, { passive: !0 }), window.addEventListener("touchend", t), () => {
|
|
141
130
|
window.removeEventListener("mousemove", e), window.removeEventListener("mouseup", t), window.removeEventListener("touchmove", e), window.removeEventListener("touchend", t);
|
|
142
131
|
};
|
|
143
132
|
}, [
|
|
144
|
-
|
|
133
|
+
k,
|
|
145
134
|
K,
|
|
146
135
|
q
|
|
147
136
|
]);
|
|
148
|
-
let X =
|
|
137
|
+
let X = U ? { aspectRatio: String(U) } : void 0, Z = U ? "" : " aspect-video", Q = Math.round(E * 100);
|
|
149
138
|
return /* @__PURE__ */ o("div", {
|
|
150
139
|
role: "button",
|
|
151
140
|
tabIndex: 0,
|
|
@@ -153,96 +142,96 @@ var U = (e) => "touches" in e ? e.touches[0]?.clientX ?? e.changedTouches[0]?.cl
|
|
|
153
142
|
className: `relative cursor-pointer overflow-hidden bg-black ${Z}`,
|
|
154
143
|
style: X,
|
|
155
144
|
onClick: (e) => {
|
|
156
|
-
if (
|
|
157
|
-
|
|
145
|
+
if (g) {
|
|
146
|
+
g(e);
|
|
158
147
|
return;
|
|
159
148
|
}
|
|
160
|
-
|
|
149
|
+
P || p && T((e) => !e);
|
|
161
150
|
},
|
|
162
151
|
onKeyDown: (e) => {
|
|
163
152
|
if (e.key === "Enter" || e.key === " ") {
|
|
164
|
-
if (e.preventDefault(),
|
|
165
|
-
|
|
153
|
+
if (e.preventDefault(), g) {
|
|
154
|
+
g(e);
|
|
166
155
|
return;
|
|
167
156
|
}
|
|
168
|
-
|
|
157
|
+
P || p && T((e) => !e);
|
|
169
158
|
}
|
|
170
159
|
},
|
|
171
160
|
children: [
|
|
172
|
-
|
|
173
|
-
src:
|
|
161
|
+
l && (_ === "audio" || V) && /* @__PURE__ */ a("img", {
|
|
162
|
+
src: l,
|
|
174
163
|
alt: "",
|
|
175
164
|
"data-testid": "media-player-poster",
|
|
176
165
|
className: "absolute inset-0 h-full w-full object-cover"
|
|
177
166
|
}),
|
|
178
|
-
!
|
|
167
|
+
!l && (_ === "audio" || V) && /* @__PURE__ */ a("div", {
|
|
179
168
|
"data-testid": "media-player-placeholder",
|
|
180
169
|
className: "absolute inset-0 flex items-center justify-center",
|
|
181
|
-
children:
|
|
170
|
+
children: L(c, {
|
|
182
171
|
className: "size-12 text-black/20",
|
|
183
172
|
weight: "regular"
|
|
184
173
|
})
|
|
185
174
|
}),
|
|
186
175
|
/* @__PURE__ */ a("div", {
|
|
187
176
|
className: "absolute inset-0",
|
|
188
|
-
children:
|
|
189
|
-
...
|
|
190
|
-
ref:
|
|
177
|
+
children: _ === "audio" ? /* @__PURE__ */ a("audio", {
|
|
178
|
+
...O,
|
|
179
|
+
ref: b,
|
|
191
180
|
"data-testid": "media-player-audio",
|
|
192
181
|
src: e,
|
|
193
|
-
loop:
|
|
194
|
-
muted:
|
|
182
|
+
loop: f,
|
|
183
|
+
muted: h,
|
|
195
184
|
style: {
|
|
196
185
|
width: "100%",
|
|
197
186
|
height: "100%"
|
|
198
187
|
},
|
|
199
|
-
onLoadStart: () =>
|
|
188
|
+
onLoadStart: () => B(!0),
|
|
200
189
|
onCanPlay: () => {
|
|
201
|
-
|
|
190
|
+
B(!1), H(!1);
|
|
202
191
|
},
|
|
203
|
-
onWaiting: () =>
|
|
204
|
-
onPlay: () =>
|
|
192
|
+
onWaiting: () => B(!0),
|
|
193
|
+
onPlay: () => F(!1),
|
|
205
194
|
onEnded: () => {
|
|
206
|
-
|
|
195
|
+
f || (T(!1), D(0));
|
|
207
196
|
},
|
|
208
197
|
children: /* @__PURE__ */ a("track", { kind: "captions" })
|
|
209
198
|
}) : /* @__PURE__ */ a("video", {
|
|
210
|
-
ref:
|
|
199
|
+
ref: b,
|
|
211
200
|
"data-testid": "media-player-video",
|
|
212
201
|
src: e,
|
|
213
|
-
loop:
|
|
214
|
-
muted:
|
|
202
|
+
loop: f,
|
|
203
|
+
muted: h,
|
|
215
204
|
playsInline: !0,
|
|
216
205
|
style: {
|
|
217
206
|
width: "100%",
|
|
218
207
|
height: "100%"
|
|
219
208
|
},
|
|
220
|
-
onLoadStart: () =>
|
|
209
|
+
onLoadStart: () => B(!0),
|
|
221
210
|
onCanPlay: () => {
|
|
222
|
-
|
|
211
|
+
B(!1), H(!1);
|
|
223
212
|
},
|
|
224
|
-
onWaiting: () =>
|
|
225
|
-
onPlay: () =>
|
|
213
|
+
onWaiting: () => B(!0),
|
|
214
|
+
onPlay: () => F(!1),
|
|
226
215
|
onLoadedMetadata: () => {
|
|
227
|
-
let e =
|
|
216
|
+
let e = b.current;
|
|
228
217
|
e instanceof HTMLVideoElement && e.videoWidth && e.videoHeight && W(e.videoWidth / e.videoHeight);
|
|
229
218
|
},
|
|
230
219
|
onEnded: () => {
|
|
231
|
-
|
|
220
|
+
f || (T(!1), D(0));
|
|
232
221
|
},
|
|
233
222
|
children: /* @__PURE__ */ a("track", { kind: "captions" })
|
|
234
223
|
})
|
|
235
224
|
}),
|
|
236
|
-
I && !
|
|
225
|
+
I && !P && /* @__PURE__ */ a("div", {
|
|
237
226
|
role: "status",
|
|
238
227
|
"aria-label": "Loading media",
|
|
239
228
|
className: "absolute inset-0 z-10 flex items-center justify-center",
|
|
240
|
-
children: /* @__PURE__ */ a(
|
|
241
|
-
|
|
242
|
-
|
|
229
|
+
children: /* @__PURE__ */ a(s, {
|
|
230
|
+
className: "size-8 animate-spin text-white/80",
|
|
231
|
+
weight: "bold"
|
|
243
232
|
})
|
|
244
233
|
}),
|
|
245
|
-
|
|
234
|
+
P && !p && /* @__PURE__ */ a("div", {
|
|
246
235
|
className: "absolute inset-0 z-30 flex cursor-pointer items-center justify-center bg-black/35",
|
|
247
236
|
role: "button",
|
|
248
237
|
tabIndex: 0,
|
|
@@ -255,13 +244,13 @@ var U = (e) => "touches" in e ? e.touches[0]?.clientX ?? e.changedTouches[0]?.cl
|
|
|
255
244
|
},
|
|
256
245
|
children: /* @__PURE__ */ a("span", {
|
|
257
246
|
className: "flex size-16 items-center justify-center rounded-full bg-white/20 text-white backdrop-blur-sm",
|
|
258
|
-
children: /* @__PURE__ */ a(
|
|
247
|
+
children: /* @__PURE__ */ a(y, {
|
|
259
248
|
className: "size-9 translate-x-0.5",
|
|
260
249
|
weight: "fill"
|
|
261
250
|
})
|
|
262
251
|
})
|
|
263
252
|
}),
|
|
264
|
-
|
|
253
|
+
m && !p && /* @__PURE__ */ a("div", {
|
|
265
254
|
className: "absolute inset-x-0 bottom-0 px-3 pb-2.5 pt-6 bg-gradient-to-t from-black/40 to-transparent",
|
|
266
255
|
children: /* @__PURE__ */ a("div", {
|
|
267
256
|
role: "slider",
|
|
@@ -270,7 +259,7 @@ var U = (e) => "touches" in e ? e.touches[0]?.clientX ?? e.changedTouches[0]?.cl
|
|
|
270
259
|
"aria-valuemin": 0,
|
|
271
260
|
"aria-valuemax": 100,
|
|
272
261
|
tabIndex: 0,
|
|
273
|
-
ref:
|
|
262
|
+
ref: x,
|
|
274
263
|
className: "relative flex h-4 w-full cursor-pointer items-center",
|
|
275
264
|
onMouseDown: J,
|
|
276
265
|
onTouchStart: J,
|
|
@@ -285,19 +274,19 @@ var U = (e) => "touches" in e ? e.touches[0]?.clientX ?? e.changedTouches[0]?.cl
|
|
|
285
274
|
})
|
|
286
275
|
})
|
|
287
276
|
}),
|
|
288
|
-
|
|
277
|
+
p && /* @__PURE__ */ o("div", {
|
|
289
278
|
className: "absolute inset-x-0 bottom-0 flex items-center gap-2 bg-gradient-to-t from-black/60 to-transparent px-3 pb-2.5 pt-6 transition-all duration-200",
|
|
290
279
|
children: [/* @__PURE__ */ a("button", {
|
|
291
280
|
type: "button",
|
|
292
281
|
onClick: (e) => {
|
|
293
|
-
e.stopPropagation(),
|
|
282
|
+
e.stopPropagation(), T((e) => !e);
|
|
294
283
|
},
|
|
295
284
|
className: "shrink-0 text-white",
|
|
296
|
-
"aria-label":
|
|
297
|
-
children:
|
|
285
|
+
"aria-label": w ? "Pause" : "Play",
|
|
286
|
+
children: w ? /* @__PURE__ */ a(v, {
|
|
298
287
|
className: "size-5",
|
|
299
288
|
weight: "fill"
|
|
300
|
-
}) : /* @__PURE__ */ a(
|
|
289
|
+
}) : /* @__PURE__ */ a(y, {
|
|
301
290
|
className: "size-5 translate-x-px",
|
|
302
291
|
weight: "fill"
|
|
303
292
|
})
|
|
@@ -308,39 +297,39 @@ var U = (e) => "touches" in e ? e.touches[0]?.clientX ?? e.changedTouches[0]?.cl
|
|
|
308
297
|
"aria-valuemin": 0,
|
|
309
298
|
"aria-valuemax": 100,
|
|
310
299
|
tabIndex: 0,
|
|
311
|
-
ref:
|
|
300
|
+
ref: x,
|
|
312
301
|
className: "relative flex h-4 w-full cursor-pointer items-center",
|
|
313
302
|
onMouseDown: J,
|
|
314
303
|
onTouchStart: J,
|
|
315
304
|
onClick: (e) => e.stopPropagation(),
|
|
316
|
-
onMouseEnter: () =>
|
|
317
|
-
onMouseLeave: () =>
|
|
305
|
+
onMouseEnter: () => N(!0),
|
|
306
|
+
onMouseLeave: () => N(!1),
|
|
318
307
|
onKeyDown: Y,
|
|
319
308
|
children: [/* @__PURE__ */ a("div", {
|
|
320
|
-
className: `w-full overflow-hidden rounded-full bg-white/30 transition-all duration-200 ${
|
|
309
|
+
className: `w-full overflow-hidden rounded-full bg-white/30 transition-all duration-200 ${M || k ? "h-1.5" : "h-1"}`,
|
|
321
310
|
children: /* @__PURE__ */ a("div", {
|
|
322
311
|
className: "h-full rounded-full bg-white",
|
|
323
312
|
style: { width: `${Q}%` }
|
|
324
313
|
})
|
|
325
314
|
}), /* @__PURE__ */ a("div", {
|
|
326
315
|
"data-testid": "media-player-scrubber-thumb",
|
|
327
|
-
className: `absolute size-3 -translate-x-1/2 rounded-full bg-white shadow transition-[opacity,transform] duration-200 ${
|
|
316
|
+
className: `absolute size-3 -translate-x-1/2 rounded-full bg-white shadow transition-[opacity,transform] duration-200 ${M || k ? "scale-100 opacity-100" : "scale-0 opacity-0"}`,
|
|
328
317
|
style: { left: `${Q}%` }
|
|
329
318
|
})]
|
|
330
319
|
})]
|
|
331
320
|
})
|
|
332
321
|
]
|
|
333
322
|
});
|
|
334
|
-
},
|
|
335
|
-
let l =
|
|
336
|
-
return t && (l === "video" || l === "audio") ? /* @__PURE__ */ a(
|
|
323
|
+
}, V = (e) => e === "dark" ? "size-12 text-white/20" : "size-12 text-black/20", H = (e) => e === "dark" ? "aspect-video overflow-hidden bg-white/10" : "aspect-video overflow-hidden bg-black/5", U = ({ mimeType: e, sourceUrl: t, thumbnailUrl: n, title: r, variant: o, mediaPlayerProps: s, containedImage: c = !1 }) => {
|
|
324
|
+
let l = j(e), [u, d] = i(!1), f = E(t), p = E(n);
|
|
325
|
+
return t && (l === "video" || l === "audio") ? /* @__PURE__ */ a(B, {
|
|
337
326
|
source: t,
|
|
338
327
|
mimeType: e,
|
|
339
328
|
poster: p,
|
|
340
329
|
controls: !0,
|
|
341
330
|
...s
|
|
342
331
|
}) : t && l === "image" ? c ? /* @__PURE__ */ a("div", {
|
|
343
|
-
className: `relative ${
|
|
332
|
+
className: `relative ${H(o)}`,
|
|
344
333
|
children: /* @__PURE__ */ a("img", {
|
|
345
334
|
src: f ?? t,
|
|
346
335
|
alt: r ?? "",
|
|
@@ -354,7 +343,7 @@ var U = (e) => "touches" in e ? e.touches[0]?.clientX ?? e.changedTouches[0]?.cl
|
|
|
354
343
|
className: "block w-full",
|
|
355
344
|
draggable: !1
|
|
356
345
|
}) : t && l === "document" ? n ? c ? /* @__PURE__ */ a("div", {
|
|
357
|
-
className: `relative ${
|
|
346
|
+
className: `relative ${H(o)}`,
|
|
358
347
|
children: /* @__PURE__ */ a("img", {
|
|
359
348
|
src: p ?? n,
|
|
360
349
|
alt: r ?? "",
|
|
@@ -369,12 +358,12 @@ var U = (e) => "touches" in e ? e.touches[0]?.clientX ?? e.changedTouches[0]?.cl
|
|
|
369
358
|
draggable: !1
|
|
370
359
|
}) : /* @__PURE__ */ a("div", {
|
|
371
360
|
className: `flex aspect-video w-full items-center justify-center ${o === "dark" ? "bg-white/10" : "bg-black/5"}`,
|
|
372
|
-
children:
|
|
373
|
-
className:
|
|
361
|
+
children: L(e, {
|
|
362
|
+
className: V(o),
|
|
374
363
|
weight: "regular"
|
|
375
364
|
})
|
|
376
365
|
}) : n ? /* @__PURE__ */ a("div", {
|
|
377
|
-
className: `relative ${
|
|
366
|
+
className: `relative ${H(o)}`,
|
|
378
367
|
children: /* @__PURE__ */ a("img", {
|
|
379
368
|
src: p ?? n,
|
|
380
369
|
alt: r ?? "",
|
|
@@ -383,13 +372,13 @@ var U = (e) => "touches" in e ? e.touches[0]?.clientX ?? e.changedTouches[0]?.cl
|
|
|
383
372
|
})
|
|
384
373
|
}) : /* @__PURE__ */ a("div", {
|
|
385
374
|
className: `flex aspect-video w-full items-center justify-center ${o === "dark" ? "bg-white/10" : "bg-black/5"}`,
|
|
386
|
-
children:
|
|
387
|
-
className:
|
|
375
|
+
children: L(e, {
|
|
376
|
+
className: V(o),
|
|
388
377
|
weight: "regular"
|
|
389
378
|
})
|
|
390
379
|
});
|
|
391
380
|
};
|
|
392
381
|
//#endregion
|
|
393
|
-
export {
|
|
382
|
+
export { O as a, j as i, L as n, k as o, M as r, E as s, U as t };
|
|
394
383
|
|
|
395
|
-
//# sourceMappingURL=AttachmentCard-
|
|
384
|
+
//# sourceMappingURL=AttachmentCard-DSekwIOA.js.map
|