@nethesis/phone-island 0.18.13 → 1.0.0-dev.2
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/App.js +1 -1
- package/dist/App.js.map +1 -1
- package/dist/components/SideView/hooks/useSideViewLogic.js +1 -1
- package/dist/components/SideView/hooks/useSideViewLogic.js.map +1 -1
- package/dist/components/Socket.js +1 -1
- package/dist/components/Socket.js.map +1 -1
- package/dist/components/TranscriptionView/TranscriptionView.js +1 -1
- package/dist/components/TranscriptionView/TranscriptionView.js.map +1 -1
- package/dist/package.json.js +1 -1
- package/dist/services/user.js +1 -1
- package/dist/services/user.js.map +1 -1
- package/package.json +6 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TranscriptionView.js","sources":["../../../src/components/TranscriptionView/TranscriptionView.tsx"],"sourcesContent":["// Copyright (C) 2025 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { FC, memo, useState, useEffect, useRef } from 'react'\nimport { useSelector } from 'react-redux'\nimport { RootState } from '../../store'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { useTranslation } from 'react-i18next'\nimport { useEventListener, eventDispatch } from '../../utils'\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome'\nimport { faAngleUp, faArrowDown } from '@fortawesome/free-solid-svg-icons'\n\nconst ANIMATION_CONFIG = {\n initial: { height: 0, opacity: 0 },\n animate: { height: '360px', opacity: 1 },\n exit: { height: 0, opacity: 0 },\n transition: {\n duration: 0.1,\n ease: 'easeOut',\n },\n}\n\nconst STYLE_CONFIG = {\n borderBottomLeftRadius: '20px',\n borderBottomRightRadius: '20px',\n transformOrigin: 'top',\n overflow: 'hidden',\n} as const\n\ninterface TranscriptionViewProps {\n isVisible: boolean\n}\n\ninterface TranscriptionMessage {\n id: string\n timestamp: number\n speaker: string\n speakerNumber: string\n counterpart: string\n counterpartNumber: string\n text: string\n isFinal: boolean\n}\n\nconst TypewriterText: FC<{ text: string; isFinal: boolean; speed?: number }> = ({\n text,\n isFinal,\n speed = 50,\n}) => {\n const [displayText, setDisplayText] = useState('')\n\n useEffect(() => {\n if (isFinal) {\n setDisplayText(text)\n return\n }\n\n setDisplayText('')\n let currentIndex = 0\n\n const typeInterval = setInterval(() => {\n if (currentIndex < text.length) {\n setDisplayText(text.slice(0, currentIndex + 1))\n currentIndex++\n } else {\n clearInterval(typeInterval)\n }\n }, speed)\n\n return () => clearInterval(typeInterval)\n }, [text, isFinal, speed])\n\n return (\n <div className='pi-inline-flex pi-items-center pi-flex-wrap'>\n <span>{displayText}</span>\n </div>\n )\n}\n\nconst TranscriptionView: FC<TranscriptionViewProps> = memo(({ isVisible }) => {\n const { actionsExpanded, view } = useSelector((state: RootState) => state.island)\n const currentUser = useSelector((state: RootState) => state.currentUser)\n const { t } = useTranslation()\n\n const [allMessages, setAllMessages] = useState<TranscriptionMessage[]>([])\n const [visibleMessages, setVisibleMessages] = useState<TranscriptionMessage[]>([])\n const [hasNewContent, setHasNewContent] = useState(false)\n const [userScrolled, setUserScrolled] = useState(false)\n const [lastSeenMessageIndex, setLastSeenMessageIndex] = useState(0)\n const messagesEndRef = useRef<HTMLDivElement>(null)\n const scrollContainerRef = useRef<HTMLDivElement>(null)\n const [autoScroll, setAutoScroll] = useState(true)\n\n const MAX_VISIBLE_MESSAGES = 100\n const BUFFER_MESSAGES = 10\n const SCROLL_DEBOUNCE_MS = 100\n\n // Function to check if a speaker number belongs to current user\n const isMyNumber = (speakerNumber: string): boolean => {\n if (!currentUser || !speakerNumber) return false\n\n // Check main extension from endpoints\n if (currentUser.endpoints?.mainextension?.[0]?.id === speakerNumber) return true\n\n // Check other extensions in endpoints\n if (currentUser.endpoints?.extension) {\n return Object.values(currentUser.endpoints.extension).some(\n (ext: any) => ext.id === speakerNumber || ext.exten === speakerNumber,\n )\n }\n\n return false\n }\n\n // Update visible messages when all messages change\n useEffect(() => {\n const startIndex = Math.max(0, allMessages.length - MAX_VISIBLE_MESSAGES)\n const newVisibleMessages = allMessages.slice(startIndex)\n setVisibleMessages(newVisibleMessages)\n }, [allMessages])\n\n // Handle incoming transcription messages\n const addTranscriptionMessage = (data: any) => {\n const uniqueId = `${data.uniqueid}_${data.timestamp}`\n\n const message: TranscriptionMessage = {\n id: uniqueId,\n timestamp: data.timestamp || 0,\n speaker: data.speaker_name || 'Unknown',\n speakerNumber: data.speaker_number || '',\n counterpart: data.speaker_counterpart_name || '',\n counterpartNumber: data.speaker_counterpart_number || '',\n text: data.transcription || '',\n isFinal: data.is_final || false,\n }\n\n setAllMessages((prevMessages) => {\n // Check if message with same unique ID already exists\n const existingMessageIndex = prevMessages.findIndex((msg) => msg.id === uniqueId)\n\n if (existingMessageIndex !== -1) {\n // Update existing message (same uniqueid + timestamp)\n const updatedMessages = [...prevMessages]\n updatedMessages[existingMessageIndex] = message\n return updatedMessages\n } else {\n // Add new message - each uniqueid + timestamp combination is a separate message\n return [...prevMessages, message]\n }\n })\n }\n\n // Check if user is at the bottom of the scroll area\n const isAtBottom = () => {\n if (!scrollContainerRef.current) return true\n const { scrollTop, scrollHeight, clientHeight } = scrollContainerRef.current\n return scrollHeight - scrollTop <= clientHeight + 10 // 10px tolerance\n }\n\n // Handle scroll events to detect user scrolling\n const handleScroll = () => {\n if (!scrollContainerRef.current) return\n\n const atBottom = isAtBottom()\n const { scrollTop, scrollHeight, clientHeight } = scrollContainerRef.current\n\n if (atBottom) {\n // User is at bottom, clear indicators and enable auto-scroll\n setHasNewContent(false)\n setUserScrolled(false)\n setAutoScroll(true)\n setLastSeenMessageIndex(allMessages.length)\n } else {\n setUserScrolled(true)\n setAutoScroll(false)\n }\n }\n\n // Scroll to bottom function\n const scrollToBottom = () => {\n if (scrollContainerRef.current) {\n scrollContainerRef.current.scrollTop = scrollContainerRef.current.scrollHeight\n\n // Update state\n setHasNewContent(false)\n setUserScrolled(false)\n setAutoScroll(true)\n setLastSeenMessageIndex(allMessages.length)\n }\n }\n\n // Calculate unseen messages count\n const unseenMessagesCount = Math.max(0, allMessages.length - lastSeenMessageIndex)\n\n // Auto-scroll to bottom when new messages arrive\n useEffect(() => {\n if (allMessages.length === 0) return\n\n if (autoScroll && scrollContainerRef.current) {\n // Auto-scroll to bottom immediately for new messages\n setTimeout(() => {\n if (scrollContainerRef.current) {\n scrollContainerRef.current.scrollTop = scrollContainerRef.current.scrollHeight\n }\n }, 100)\n } else if (userScrolled && !autoScroll) {\n // If user has scrolled up and there's a new message, show the indicator\n setHasNewContent(true)\n }\n }, [allMessages])\n\n useEffect(() => {\n if (isVisible && allMessages.length > 0) {\n setAutoScroll(true)\n setUserScrolled(false)\n setHasNewContent(false)\n }\n }, [isVisible])\n\n // Listen for transcription events\n useEventListener('phone-island-conversation-transcription', (transcriptionData: any) => {\n addTranscriptionMessage(transcriptionData)\n })\n\n // Format timestamp - converts seconds from call start to MM:SS format\n const formatTimestamp = (timestamp: number) => {\n const minutes = Math.floor(timestamp / 60)\n const seconds = Math.floor(timestamp % 60)\n return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`\n }\n\n // Skeleton component for loading state\n const TranscriptionSkeleton: FC = () => (\n <div className='pi-space-y-2 pi-animate-pulse'>\n {/* First shorter bar */}\n <div className='pi-h-4 pi-bg-gray-200 dark:pi-bg-gray-700 pi-rounded pi-w-2/5'></div>\n {/* Second longer bar */}\n <div className='pi-h-4 pi-bg-gray-200 dark:pi-bg-gray-700 pi-rounded pi-w-4/5'></div>\n {/* First shorter bar */}\n <div className='pi-h-4 pi-bg-gray-200 dark:pi-bg-gray-700 pi-rounded pi-w-2/5'></div>\n {/* Third medium bar */}\n <div className='pi-h-4 pi-bg-gray-200 dark:pi-bg-gray-700 pi-rounded pi-w-4/5'></div>\n </div>\n )\n\n const containerClassName = `pi-absolute pi-w-full pi-bg-elevationL2 pi-flex pi-flex-col pi-text-iconWhite dark:pi-text-iconWhiteDark pi-left-0 -pi-z-10 pi-pointer-events-auto ${\n view === 'settings' || actionsExpanded ? 'pi-top-[17rem]' : 'pi-top-[13rem]'\n }`\n\n return (\n <>\n <AnimatePresence>\n {isVisible && (\n <motion.div className={containerClassName} style={STYLE_CONFIG} {...ANIMATION_CONFIG}>\n <div className='pi-h-full pi-rounded-lg pi-overflow-hidden pi-bg-elevationL2 dark:pi-bg-elevationL2Dark pi-relative pi-flex pi-flex-col pi-border-2 pi-border-gray-100 dark:pi-border-gray-600 pi-shadow-lg'>\n {/* Main Content Card */}\n <div className='pi-flex-1 pi-pt-4 pi-px-4 pi-mt-8'>\n <div className='pi-h-60 pi-bg-gray-100 dark:pi-bg-gray-800 pi-rounded-lg pi-border pi-border-gray-200 dark:pi-border-gray-700 pi-overflow-hidden pi-flex pi-flex-col'>\n <AnimatePresence>\n {hasNewContent && userScrolled && (\n <motion.div\n initial={{ opacity: 0, y: -10, scale: 0.9 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: -10, scale: 0.9 }}\n className='pi-absolute pi-top-16 pi-left-0 pi-right-0 pi-flex pi-justify-center pi-z-20'\n >\n <button\n onClick={scrollToBottom}\n className='pi-bg-phoneIslandActive dark:pi-bg-phoneIslandActiveDark hover:pi-bg-gray-500 dark:hover:pi-bg-gray-50 focus:pi-ring-emerald-500 dark:focus:pi-ring-emerald-300 pi-text-primaryInvert dark:pi-text-primaryInvertDark pi-px-4 pi-py-2 pi-rounded-full pi-text-sm pi-shadow-lg pi-flex pi-items-center pi-gap-2 pi-transition-all pi-duration-200 pi-border pi-backdrop-blur-sm'\n >\n <FontAwesomeIcon icon={faArrowDown} className='pi-w-4 pi-h-4' />\n {unseenMessagesCount > 1\n ? t('TranscriptionView.New messages')\n : t('TranscriptionView.New message')}\n </button>\n </motion.div>\n )}\n </AnimatePresence>\n\n <div\n ref={scrollContainerRef}\n onScroll={handleScroll}\n className={`pi-flex-1 pi-p-4 ${\n visibleMessages.length > 0\n ? 'pi-overflow-y-auto pi-scrollbar-thin pi-scrollbar-thumb-gray-400 pi-scrollbar-thumb-rounded-full pi-scrollbar-thumb-opacity-50 pi-scrollbar-track-gray-200 dark:pi-scrollbar-track-gray-900 pi-scrollbar-track-rounded-full pi-scrollbar-track-opacity-25'\n : 'pi-overflow-hidden'\n }`}\n >\n {visibleMessages.length === 0 ? (\n <TranscriptionSkeleton />\n ) : (\n <div className='pi-space-y-4'>\n {/* Show indicator if there are more messages than displayed */}\n {allMessages.length > MAX_VISIBLE_MESSAGES && (\n <div className='pi-text-center pi-py-2 pi-text-xs pi-text-gray-500 dark:pi-text-gray-400 pi-border-b pi-border-gray-200 dark:pi-border-gray-700'>\n {t('TranscriptionView.Showing messages', {\n visible: visibleMessages.length,\n total: allMessages.length,\n })}\n </div>\n )}\n\n {visibleMessages.map((message, index) => (\n <motion.div\n key={message.id}\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.3 }}\n className='pi-mb-4'\n >\n {/* Speaker Name */}\n <div className='pi-mb-2'>\n <span className='pi-font-medium pi-text-xs pi-text-secondaryNeutral dark:pi-text-secondaryNeutralDark'>\n {isMyNumber(message.speakerNumber)\n ? t('Common.Me', 'Me')\n : message.speaker}\n </span>\n </div>\n\n {/* Message Bubble with Background */}\n <div\n className={`pi-relative pi-p-3 pi-rounded-lg pi-text-xs pi-font-regular ${\n isMyNumber(message.speakerNumber)\n ? 'pi-text-gray-800 dark:pi-text-gray-100 pi-bg-gray-200 dark:pi-bg-gray-600'\n : 'pi-text-indigo-800 dark:pi-text-indigo-100 pi-bg-indigo-100 dark:pi-bg-indigo-700'\n }`}\n >\n <div className='pi-flex pi-items-start pi-justify-between pi-gap-3'>\n <div className='pi-flex-1'>\n <TypewriterText\n text={message.text}\n isFinal={message.isFinal}\n speed={30}\n />\n </div>\n {/* Timestamp on the right */}\n <div\n className={`pi-flex-shrink-0 pi-mt-1 pi-text-xs pi-font-regular ${\n isMyNumber(message.speakerNumber)\n ? 'pi-text-gray-800 dark:pi-text-gray-100 pi-bg-gray-200 dark:pi-bg-gray-600'\n : 'pi-text-indigo-800 dark:pi-text-indigo-100 pi-bg-indigo-100 dark:pi-bg-indigo-700'\n }`}\n >\n {formatTimestamp(message.timestamp)}\n </div>\n </div>\n </div>\n\n {!message.isFinal && message.text.trim() !== '' && (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n className='pi-mt-1 pi-ml-3 pi-flex pi-items-center pi-gap-1'\n >\n <span className='pi-text-xs pi-text-gray-400 dark:pi-text-gray-500 pi-italic'>\n {t('TranscriptionView.Is speaking', '')}\n </span>\n <div className='pi-inline-flex pi-items-center pi-gap-1'>\n <motion.div\n className='pi-w-1 pi-h-1 pi-bg-gray-400 dark:pi-bg-gray-500 pi-rounded-full'\n animate={{ opacity: [0.3, 1, 0.3] }}\n transition={{ duration: 1.5, repeat: Infinity, delay: 0 }}\n />\n <motion.div\n className='pi-w-1 pi-h-1 pi-bg-gray-400 dark:pi-bg-gray-500 pi-rounded-full'\n animate={{ opacity: [0.3, 1, 0.3] }}\n transition={{ duration: 1.5, repeat: Infinity, delay: 0.2 }}\n />\n <motion.div\n className='pi-w-1 pi-h-1 pi-bg-gray-400 dark:pi-bg-gray-500 pi-rounded-full'\n animate={{ opacity: [0.3, 1, 0.3] }}\n transition={{ duration: 1.5, repeat: Infinity, delay: 0.4 }}\n />\n </div>\n </motion.div>\n )}\n </motion.div>\n ))}\n <div ref={messagesEndRef} className='pi-pb-4' />\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Footer with Close Button */}\n <div className='pi-flex pi-items-center pi-justify-center pi-py-2'>\n <button\n onClick={() => eventDispatch('phone-island-transcription-close', {})}\n className='pi-bg-transparent dark:enabled:hover:pi-bg-gray-700/30 enabled:hover:pi-bg-gray-300/70 focus:pi-ring-offset-gray-200 dark:focus:pi-ring-gray-500 focus:pi-ring-gray-400 pi-text-secondaryNeutral pi-outline-none pi-border-transparent dark:pi-text-secondaryNeutralDark pi-h-12 pi-w-24 pi-rounded-fullpi-px-4 pi-py-2 pi-rounded-full pi-text-lg pi-flex pi-items-center pi-gap-2 pi-transition-all pi-duration-200 pi-border pi-backdrop-blur-sm'\n >\n <FontAwesomeIcon icon={faAngleUp} className='pi-w-4 pi-h-4 pi-ml-1' />\n {t('Common.Close')}\n </button>\n </div>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </>\n )\n})\n\nTranscriptionView.displayName = 'TranscriptionView'\n\nexport default TranscriptionView\n"],"names":["ANIMATION_CONFIG","initial","height","opacity","animate","exit","transition","duration","ease","STYLE_CONFIG","borderBottomLeftRadius","borderBottomRightRadius","transformOrigin","overflow","TypewriterText","_a","text","isFinal","_b","speed","_c","useState","displayText","setDisplayText","useEffect","currentIndex","typeInterval","setInterval","length","slice","clearInterval","React","createElement","className","TranscriptionView","memo","isVisible","useSelector","state","island","actionsExpanded","view","currentUser","t","useTranslation","allMessages","setAllMessages","_d","visibleMessages","setVisibleMessages","_e","hasNewContent","setHasNewContent","_f","userScrolled","setUserScrolled","_g","lastSeenMessageIndex","setLastSeenMessageIndex","messagesEndRef","useRef","scrollContainerRef","_h","autoScroll","setAutoScroll","isMyNumber","speakerNumber","endpoints","mainextension","id","extension","Object","values","some","ext","exten","startIndex","Math","max","newVisibleMessages","unseenMessagesCount","current","setTimeout","scrollTop","scrollHeight","useEventListener","transcriptionData","data","uniqueId","message","concat","uniqueid","timestamp","speaker","speaker_name","speaker_number","counterpart","speaker_counterpart_name","counterpartNumber","speaker_counterpart_number","transcription","is_final","prevMessages","existingMessageIndex","findIndex","msg","updatedMessages","__spreadArray","containerClassName","Fragment","AnimatePresence","motion","div","__assign","style","y","scale","onClick","FontAwesomeIcon","icon","faArrowDown","ref","onScroll","atBottom","isAtBottom","visible","total","map","index","key","minutes","floor","seconds","toString","padStart","trim","repeat","Infinity","delay","eventDispatch","faAngleUp","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TranscriptionView.js","sources":["../../../src/components/TranscriptionView/TranscriptionView.tsx"],"sourcesContent":["// Copyright (C) 2025 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { FC, memo, useState, useEffect, useRef } from 'react'\nimport { useSelector } from 'react-redux'\nimport { RootState } from '../../store'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { useTranslation } from 'react-i18next'\nimport { useEventListener, eventDispatch } from '../../utils'\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome'\nimport { faAngleUp, faArrowDown } from '@fortawesome/free-solid-svg-icons'\n\nconst ANIMATION_CONFIG = {\n initial: { height: 0, opacity: 0 },\n animate: { height: '360px', opacity: 1 },\n exit: { height: 0, opacity: 0 },\n transition: {\n duration: 0.1,\n ease: 'easeOut',\n },\n}\n\nconst STYLE_CONFIG = {\n borderBottomLeftRadius: '20px',\n borderBottomRightRadius: '20px',\n transformOrigin: 'top',\n overflow: 'hidden',\n} as const\n\ninterface TranscriptionViewProps {\n isVisible: boolean\n}\n\ninterface TranscriptionMessage {\n id: string\n timestamp: number\n channelIndex: number\n segmentStart: number\n speaker: string\n speakerNumber: string\n counterpart: string\n counterpartNumber: string\n text: string\n isFinal: boolean\n}\n\nconst TypewriterText: FC<{ text: string; isFinal: boolean; speed?: number }> = ({\n text,\n isFinal,\n speed = 50,\n}) => {\n const [displayText, setDisplayText] = useState('')\n\n useEffect(() => {\n if (isFinal) {\n setDisplayText(text)\n return\n }\n\n setDisplayText('')\n let currentIndex = 0\n\n const typeInterval = setInterval(() => {\n if (currentIndex < text.length) {\n setDisplayText(text.slice(0, currentIndex + 1))\n currentIndex++\n } else {\n clearInterval(typeInterval)\n }\n }, speed)\n\n return () => clearInterval(typeInterval)\n }, [text, isFinal, speed])\n\n return (\n <div className='pi-inline-flex pi-items-center pi-flex-wrap'>\n <span>{displayText}</span>\n </div>\n )\n}\n\nconst TranscriptionView: FC<TranscriptionViewProps> = memo(({ isVisible }) => {\n const { actionsExpanded, view } = useSelector((state: RootState) => state.island)\n const currentUser = useSelector((state: RootState) => state.currentUser)\n const currentCallStartTime = useSelector((state: RootState) => state.currentCall.startTime)\n const { t } = useTranslation()\n\n const [allMessages, setAllMessages] = useState<TranscriptionMessage[]>([])\n const [visibleMessages, setVisibleMessages] = useState<TranscriptionMessage[]>([])\n const [hasNewContent, setHasNewContent] = useState(false)\n const [userScrolled, setUserScrolled] = useState(false)\n const [lastSeenMessageIndex, setLastSeenMessageIndex] = useState(0)\n const messagesEndRef = useRef<HTMLDivElement>(null)\n const scrollContainerRef = useRef<HTMLDivElement>(null)\n const timestampCorrectionRef = useRef<number | null>(null)\n const [autoScroll, setAutoScroll] = useState(true)\n\n const MAX_VISIBLE_MESSAGES = 100\n const BUFFER_MESSAGES = 10\n const SCROLL_DEBOUNCE_MS = 100\n\n const resetTranscriptionState = () => {\n timestampCorrectionRef.current = null\n setAllMessages([])\n setVisibleMessages([])\n setHasNewContent(false)\n setUserScrolled(false)\n setLastSeenMessageIndex(0)\n setAutoScroll(true)\n }\n\n const getLocalCallElapsedSeconds = () => {\n const start = Number(currentCallStartTime)\n if (!Number.isFinite(start) || start <= 0) {\n return null\n }\n return Math.max(0, Math.floor(Date.now() / 1000) - start)\n }\n\n\n // Function to check if a speaker number belongs to current user\n const isMyNumber = (speakerNumber: string): boolean => {\n if (!currentUser || !speakerNumber) return false\n\n // Check main extension from endpoints\n if (currentUser.endpoints?.mainextension?.[0]?.id === speakerNumber) return true\n\n // Check other extensions in endpoints\n if (currentUser.endpoints?.extension) {\n return Object.values(currentUser.endpoints.extension).some(\n (ext: any) => ext.id === speakerNumber || ext.exten === speakerNumber,\n )\n }\n\n return false\n }\n\n // Update visible messages when all messages change\n useEffect(() => {\n const startIndex = Math.max(0, allMessages.length - MAX_VISIBLE_MESSAGES)\n const newVisibleMessages = allMessages.slice(startIndex)\n setVisibleMessages(newVisibleMessages)\n }, [allMessages])\n\n // Handle incoming transcription messages\n const addTranscriptionMessage = (data: any) => {\n const rawTimestamp = Number(data.timestamp) || 0\n const channelIndex = Number.isFinite(Number(data.channel_index)) ? Number(data.channel_index) : -1\n const segmentStart = Number.isFinite(Number(data.segment_start))\n ? Number(data.segment_start)\n : rawTimestamp\n const uniqueId =\n data.uniqueid && channelIndex >= 0\n ? `${data.uniqueid}_${channelIndex}_${segmentStart.toFixed(3)}`\n : `${data.uniqueid}_${rawTimestamp}`\n const localElapsed = getLocalCallElapsedSeconds()\n let correctedTimestamp = rawTimestamp\n\n // Keep transcription timestamps aligned to local call timer, avoiding progressive drift.\n if (localElapsed !== null) {\n if (timestampCorrectionRef.current === null) {\n timestampCorrectionRef.current = localElapsed - rawTimestamp\n } else {\n const predicted = rawTimestamp + timestampCorrectionRef.current\n const error = localElapsed - predicted\n const boundedError = Math.max(-2, Math.min(2, error))\n timestampCorrectionRef.current += boundedError * 0.2\n }\n\n correctedTimestamp = rawTimestamp + (timestampCorrectionRef.current || 0)\n correctedTimestamp = Math.max(0, Math.min(localElapsed, correctedTimestamp))\n }\n\n const message: TranscriptionMessage = {\n id: uniqueId,\n timestamp: correctedTimestamp,\n channelIndex,\n segmentStart,\n speaker: data.speaker_name || 'Unknown',\n speakerNumber: data.speaker_number || '',\n counterpart: data.speaker_counterpart_name || '',\n counterpartNumber: data.speaker_counterpart_number || '',\n text: data.transcription || '',\n isFinal: data.is_final || false,\n }\n\n setAllMessages((prevMessages) => {\n const findLastIndex = (predicate: (message: TranscriptionMessage) => boolean) => {\n for (let index = prevMessages.length - 1; index >= 0; index -= 1) {\n if (predicate(prevMessages[index])) {\n return index\n }\n }\n return -1\n }\n\n const isSameSpeakerStream = (existingMessage: TranscriptionMessage) => {\n if (message.channelIndex >= 0 && existingMessage.channelIndex >= 0) {\n return existingMessage.channelIndex === message.channelIndex\n }\n\n if (message.speakerNumber && existingMessage.speakerNumber) {\n return existingMessage.speakerNumber === message.speakerNumber\n }\n\n return existingMessage.speaker === message.speaker\n }\n\n // Prefer exact match when the backend gives us a stable segment identity.\n const existingMessageIndex = prevMessages.findIndex((msg) => msg.id === uniqueId)\n const activeInterimIndex = findLastIndex(\n (existingMessage) => !existingMessage.isFinal && isSameSpeakerStream(existingMessage),\n )\n const similarFinalIndex = findLastIndex(\n (existingMessage) =>\n existingMessage.isFinal &&\n isSameSpeakerStream(existingMessage) &&\n existingMessage.text.trim() === message.text.trim() &&\n Math.abs(existingMessage.timestamp - message.timestamp) <= 1,\n )\n\n if (existingMessageIndex !== -1) {\n // Update existing message when the segment identity already exists.\n const updatedMessages = [...prevMessages]\n updatedMessages[existingMessageIndex] = message\n return updatedMessages\n }\n\n if (activeInterimIndex !== -1) {\n // Keep at most one active interim bubble per speaker/channel. This prevents\n // duplicated \"speaking...\" rows when Deepgram emits multiple partial updates.\n const updatedMessages = [...prevMessages]\n updatedMessages[activeInterimIndex] = {\n ...message,\n id: prevMessages[activeInterimIndex].id,\n }\n return updatedMessages\n }\n\n if (similarFinalIndex !== -1) {\n const updatedMessages = [...prevMessages]\n updatedMessages[similarFinalIndex] = {\n ...message,\n id: prevMessages[similarFinalIndex].id,\n }\n return updatedMessages\n }\n\n return [...prevMessages, message]\n })\n }\n\n // Check if user is at the bottom of the scroll area\n const isAtBottom = () => {\n if (!scrollContainerRef.current) return true\n const { scrollTop, scrollHeight, clientHeight } = scrollContainerRef.current\n return scrollHeight - scrollTop <= clientHeight + 10 // 10px tolerance\n }\n\n // Handle scroll events to detect user scrolling\n const handleScroll = () => {\n if (!scrollContainerRef.current) return\n\n const atBottom = isAtBottom()\n const { scrollTop, scrollHeight, clientHeight } = scrollContainerRef.current\n\n if (atBottom) {\n // User is at bottom, clear indicators and enable auto-scroll\n setHasNewContent(false)\n setUserScrolled(false)\n setAutoScroll(true)\n setLastSeenMessageIndex(allMessages.length)\n } else {\n setUserScrolled(true)\n setAutoScroll(false)\n }\n }\n\n // Scroll to bottom function\n const scrollToBottom = () => {\n if (scrollContainerRef.current) {\n scrollContainerRef.current.scrollTop = scrollContainerRef.current.scrollHeight\n\n // Update state\n setHasNewContent(false)\n setUserScrolled(false)\n setAutoScroll(true)\n setLastSeenMessageIndex(allMessages.length)\n }\n }\n\n // Calculate unseen messages count\n const unseenMessagesCount = Math.max(0, allMessages.length - lastSeenMessageIndex)\n\n // Auto-scroll to bottom when new messages arrive\n useEffect(() => {\n if (allMessages.length === 0) return\n\n if (autoScroll && scrollContainerRef.current) {\n // Auto-scroll to bottom immediately for new messages\n setTimeout(() => {\n if (scrollContainerRef.current) {\n scrollContainerRef.current.scrollTop = scrollContainerRef.current.scrollHeight\n }\n }, 100)\n } else if (userScrolled && !autoScroll) {\n // If user has scrolled up and there's a new message, show the indicator\n setHasNewContent(true)\n }\n }, [allMessages])\n\n useEffect(() => {\n if (isVisible && allMessages.length > 0) {\n setAutoScroll(true)\n setUserScrolled(false)\n setHasNewContent(false)\n }\n }, [isVisible])\n\n // Listen for transcription events\n useEventListener('phone-island-conversation-transcription', (transcriptionData: any) => {\n addTranscriptionMessage(transcriptionData)\n })\n\n useEventListener('phone-island-transcription-opened', () => {\n resetTranscriptionState()\n })\n\n useEventListener('phone-island-transcription-closed', () => {\n resetTranscriptionState()\n })\n\n\n // Format timestamp - converts seconds from call start to MM:SS format\n const formatTimestamp = (timestamp: number) => {\n const minutes = Math.floor(timestamp / 60)\n const seconds = Math.floor(timestamp % 60)\n return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`\n }\n\n // Skeleton component for loading state\n const TranscriptionSkeleton: FC = () => (\n <div className='pi-space-y-2 pi-animate-pulse'>\n {/* First shorter bar */}\n <div className='pi-h-4 pi-bg-gray-200 dark:pi-bg-gray-700 pi-rounded pi-w-2/5'></div>\n {/* Second longer bar */}\n <div className='pi-h-4 pi-bg-gray-200 dark:pi-bg-gray-700 pi-rounded pi-w-4/5'></div>\n {/* First shorter bar */}\n <div className='pi-h-4 pi-bg-gray-200 dark:pi-bg-gray-700 pi-rounded pi-w-2/5'></div>\n {/* Third medium bar */}\n <div className='pi-h-4 pi-bg-gray-200 dark:pi-bg-gray-700 pi-rounded pi-w-4/5'></div>\n </div>\n )\n\n const containerClassName = `pi-absolute pi-w-full pi-bg-elevationL2 pi-flex pi-flex-col pi-text-iconWhite dark:pi-text-iconWhiteDark pi-left-0 -pi-z-10 pi-pointer-events-auto ${\n view === 'settings' || actionsExpanded ? 'pi-top-[17rem]' : 'pi-top-[13rem]'\n }`\n\n return (\n <>\n <AnimatePresence>\n {isVisible && (\n <motion.div className={containerClassName} style={STYLE_CONFIG} {...ANIMATION_CONFIG}>\n <div className='pi-h-full pi-rounded-lg pi-overflow-hidden pi-bg-elevationL2 dark:pi-bg-elevationL2Dark pi-relative pi-flex pi-flex-col pi-border-2 pi-border-gray-100 dark:pi-border-gray-600 pi-shadow-lg'>\n {/* Main Content Card */}\n <div className='pi-flex-1 pi-pt-4 pi-px-4 pi-mt-8'>\n <div className='pi-h-60 pi-bg-gray-100 dark:pi-bg-gray-800 pi-rounded-lg pi-border pi-border-gray-200 dark:pi-border-gray-700 pi-overflow-hidden pi-flex pi-flex-col'>\n <AnimatePresence>\n {hasNewContent && userScrolled && (\n <motion.div\n initial={{ opacity: 0, y: -10, scale: 0.9 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: -10, scale: 0.9 }}\n className='pi-absolute pi-top-16 pi-left-0 pi-right-0 pi-flex pi-justify-center pi-z-20'\n >\n <button\n onClick={scrollToBottom}\n className='pi-bg-phoneIslandActive dark:pi-bg-phoneIslandActiveDark hover:pi-bg-gray-500 dark:hover:pi-bg-gray-50 focus:pi-ring-emerald-500 dark:focus:pi-ring-emerald-300 pi-text-primaryInvert dark:pi-text-primaryInvertDark pi-px-4 pi-py-2 pi-rounded-full pi-text-sm pi-shadow-lg pi-flex pi-items-center pi-gap-2 pi-transition-all pi-duration-200 pi-border pi-backdrop-blur-sm'\n >\n <FontAwesomeIcon icon={faArrowDown} className='pi-w-4 pi-h-4' />\n {unseenMessagesCount > 1\n ? t('TranscriptionView.New messages')\n : t('TranscriptionView.New message')}\n </button>\n </motion.div>\n )}\n </AnimatePresence>\n\n <div\n ref={scrollContainerRef}\n onScroll={handleScroll}\n className={`pi-flex-1 pi-p-4 ${\n visibleMessages.length > 0\n ? 'pi-overflow-y-auto pi-scrollbar-thin pi-scrollbar-thumb-gray-400 pi-scrollbar-thumb-rounded-full pi-scrollbar-thumb-opacity-50 pi-scrollbar-track-gray-200 dark:pi-scrollbar-track-gray-900 pi-scrollbar-track-rounded-full pi-scrollbar-track-opacity-25'\n : 'pi-overflow-hidden'\n }`}\n >\n {visibleMessages.length === 0 ? (\n <TranscriptionSkeleton />\n ) : (\n <div className='pi-space-y-4'>\n {/* Show indicator if there are more messages than displayed */}\n {allMessages.length > MAX_VISIBLE_MESSAGES && (\n <div className='pi-text-center pi-py-2 pi-text-xs pi-text-gray-500 dark:pi-text-gray-400 pi-border-b pi-border-gray-200 dark:pi-border-gray-700'>\n {t('TranscriptionView.Showing messages', {\n visible: visibleMessages.length,\n total: allMessages.length,\n })}\n </div>\n )}\n\n {visibleMessages.map((message, index) => (\n <motion.div\n key={message.id}\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.3 }}\n className='pi-mb-4'\n >\n {/* Speaker Name */}\n <div className='pi-mb-2'>\n <span className='pi-font-medium pi-text-xs pi-text-secondaryNeutral dark:pi-text-secondaryNeutralDark'>\n {isMyNumber(message.speakerNumber)\n ? t('Common.Me', 'Me')\n : message.speaker}\n </span>\n </div>\n\n {/* Message Bubble with Background */}\n <div\n className={`pi-relative pi-p-3 pi-rounded-lg pi-text-xs pi-font-regular ${\n isMyNumber(message.speakerNumber)\n ? 'pi-text-gray-800 dark:pi-text-gray-100 pi-bg-gray-200 dark:pi-bg-gray-600'\n : 'pi-text-indigo-800 dark:pi-text-indigo-100 pi-bg-indigo-100 dark:pi-bg-indigo-700'\n }`}\n >\n <div className='pi-flex pi-items-start pi-justify-between pi-gap-3'>\n <div className='pi-flex-1'>\n <TypewriterText\n text={message.text}\n isFinal={message.isFinal}\n speed={30}\n />\n </div>\n {/* Timestamp on the right */}\n <div\n className={`pi-flex-shrink-0 pi-mt-1 pi-text-xs pi-font-regular ${\n isMyNumber(message.speakerNumber)\n ? 'pi-text-gray-800 dark:pi-text-gray-100 pi-bg-gray-200 dark:pi-bg-gray-600'\n : 'pi-text-indigo-800 dark:pi-text-indigo-100 pi-bg-indigo-100 dark:pi-bg-indigo-700'\n }`}\n >\n {formatTimestamp(message.timestamp)}\n </div>\n </div>\n </div>\n\n {!message.isFinal && message.text.trim() !== '' && (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n className='pi-mt-1 pi-ml-3 pi-flex pi-items-center pi-gap-1'\n >\n <span className='pi-text-xs pi-text-gray-400 dark:pi-text-gray-500 pi-italic'>\n {t('TranscriptionView.Is speaking', '')}\n </span>\n <div className='pi-inline-flex pi-items-center pi-gap-1'>\n <motion.div\n className='pi-w-1 pi-h-1 pi-bg-gray-400 dark:pi-bg-gray-500 pi-rounded-full'\n animate={{ opacity: [0.3, 1, 0.3] }}\n transition={{ duration: 1.5, repeat: Infinity, delay: 0 }}\n />\n <motion.div\n className='pi-w-1 pi-h-1 pi-bg-gray-400 dark:pi-bg-gray-500 pi-rounded-full'\n animate={{ opacity: [0.3, 1, 0.3] }}\n transition={{ duration: 1.5, repeat: Infinity, delay: 0.2 }}\n />\n <motion.div\n className='pi-w-1 pi-h-1 pi-bg-gray-400 dark:pi-bg-gray-500 pi-rounded-full'\n animate={{ opacity: [0.3, 1, 0.3] }}\n transition={{ duration: 1.5, repeat: Infinity, delay: 0.4 }}\n />\n </div>\n </motion.div>\n )}\n </motion.div>\n ))}\n <div ref={messagesEndRef} className='pi-pb-4' />\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Footer with Close Button */}\n <div className='pi-flex pi-items-center pi-justify-center pi-py-2'>\n <button\n onClick={() => eventDispatch('phone-island-transcription-close', {})}\n className='pi-bg-transparent dark:enabled:hover:pi-bg-gray-700/30 enabled:hover:pi-bg-gray-300/70 focus:pi-ring-offset-gray-200 dark:focus:pi-ring-gray-500 focus:pi-ring-gray-400 pi-text-secondaryNeutral pi-outline-none pi-border-transparent dark:pi-text-secondaryNeutralDark pi-h-12 pi-w-24 pi-rounded-fullpi-px-4 pi-py-2 pi-rounded-full pi-text-lg pi-flex pi-items-center pi-gap-2 pi-transition-all pi-duration-200 pi-border pi-backdrop-blur-sm'\n >\n <FontAwesomeIcon icon={faAngleUp} className='pi-w-4 pi-h-4 pi-ml-1' />\n {t('Common.Close')}\n </button>\n </div>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </>\n )\n})\n\nTranscriptionView.displayName = 'TranscriptionView'\n\nexport default TranscriptionView\n"],"names":["ANIMATION_CONFIG","initial","height","opacity","animate","exit","transition","duration","ease","STYLE_CONFIG","borderBottomLeftRadius","borderBottomRightRadius","transformOrigin","overflow","TypewriterText","_a","text","isFinal","_b","speed","_c","useState","displayText","setDisplayText","useEffect","currentIndex","typeInterval","setInterval","length","slice","clearInterval","React","createElement","className","TranscriptionView","memo","isVisible","useSelector","state","island","actionsExpanded","view","currentUser","currentCallStartTime","currentCall","startTime","t","useTranslation","allMessages","setAllMessages","_d","visibleMessages","setVisibleMessages","_e","hasNewContent","setHasNewContent","_f","userScrolled","setUserScrolled","_g","lastSeenMessageIndex","setLastSeenMessageIndex","messagesEndRef","useRef","scrollContainerRef","timestampCorrectionRef","_h","autoScroll","setAutoScroll","resetTranscriptionState","current","isMyNumber","speakerNumber","endpoints","mainextension","id","extension","Object","values","some","ext","exten","startIndex","Math","max","newVisibleMessages","addTranscriptionMessage","data","start","rawTimestamp","Number","timestamp","channelIndex","isFinite","channel_index","segmentStart","segment_start","uniqueId","uniqueid","concat","toFixed","localElapsed","floor","Date","now","correctedTimestamp","error","boundedError","min","message","speaker","speaker_name","speaker_number","counterpart","speaker_counterpart_name","counterpartNumber","speaker_counterpart_number","transcription","is_final","prevMessages","updatedMessages","findLastIndex","predicate","index","isSameSpeakerStream","existingMessage","existingMessageIndex","findIndex","msg","activeInterimIndex","similarFinalIndex","trim","abs","__spreadArray","__assign","unseenMessagesCount","setTimeout","scrollTop","scrollHeight","useEventListener","transcriptionData","containerClassName","Fragment","AnimatePresence","motion","div","style","y","scale","onClick","FontAwesomeIcon","icon","faArrowDown","ref","onScroll","atBottom","isAtBottom","visible","total","map","key","minutes","seconds","toString","padStart","repeat","Infinity","delay","eventDispatch","faAngleUp","displayName"],"mappings":"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"}
|
package/dist/package.json.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e="@nethesis/phone-island",s="Nethesis",t="0.
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e="@nethesis/phone-island",s="Nethesis",t="1.0.0-dev.2",i="NethVoice CTI Phone Island",r=["nethserver","nethesis","nethvoice","phone","island"],o="https://github.com/nethesis/phone-island#readme",n="https://github.com/nethesis/dev/issues",p={type:"git",url:"https://github.com/nethesis/phone-island.git"},l=["dist"],a="dist/index.js",d="dist/index.d.ts",c={access:"public"},u={main:!1,types:!1,default:{distDir:"./dist-widget"}},m={"@fortawesome/free-solid-svg-icons":"^6.2.1","@fortawesome/react-fontawesome":"^0.2.0","@headlessui/react":"^2.2.8","@nethesis/nethesis-light-svg-icons":"github:nethesis/Font-Awesome#ns-light","@nethesis/nethesis-solid-svg-icons":"github:nethesis/Font-Awesome#ns-solid","@rematch/core":"^2.2.0","@rematch/immer":"^2.1.3","@rematch/select":"^3.1.2","@swc/helpers":"^0.4.12","@testing-library/jest-dom":"^5.11.4","@testing-library/user-event":"^12.1.10","framer-motion":"^12.0.0",i18next:"^22.4.9","i18next-browser-languagedetector":"^7.0.1","i18next-http-backend":"^2.1.1","js-base64":"^3.7.3",lodash:"^4.17.21","mic-check":"^1.1.0",react:"^18.2.0","react-dom":"^18.2.0","react-i18next":"^12.1.5","react-moment":"^1.1.2","react-redux":"^8.0.5","react-scripts":"^5.0.1","react-tooltip":"^5.28.0","socket.io-client":"^4.5.3","styled-components":"^5.3.6","webrtc-adapter":"^9.0.1"},b={start:"react-scripts start",dev:"storybook dev -p 6006",test:"react-scripts test",watch:"rollup -w -c","watch:css":"npx tailwindcss -o ./dist/index.css --watch",build:"rm -rf ./dist && npm run build:css && rollup -c","build:css":"NODE_ENV=production npx tailwindcss -o ./dist/index.css --minify","build:win":"del /s /q dist && npm run build:wincss && rollup -c --configPlugin typescript","build:wincss":"set NODE_ENV=production npx tailwindcss -o ./dist/index.css --minify","build:widget":"rm -rf ./dist-widget && parcel build ./src/index.widget.tsx --no-source-maps","serve:widget":"rm -rf ./widget-example/static/* && cp -rf ./dist-widget/* ./widget-example/static && npx http-server ./widget-example -o -c-1","build-storybook":"storybook build -s public",release:"npm publish","release:widget":"np patch",format:"prettier --write './**/*.{js,jsx,ts,tsx,css,md,json}' --config ./.prettierrc",bump:"node bump-version.js","build-pack":"npm run bump && npm run build && npm pack","build-pack:win":"npm run bump && npm run build:win && npm pack","publish:minor":"node check-publish.js minor && npm version minor --allow-same-version -m v%s --force","publish:major":"node check-publish.js major && npm version major --allow-same-version -m v%s --force","publish:patch":"node check-publish.js patch && npm version patch --allow-same-version -m v%s --force","publish:dev":"node publish-dev.js",preversion:"rm -rf dist-widget && npm run build:widget && git add dist-widget/index.widget.js dist-widget/index.widget.css && git commit -m 'chore(widget): release for jsDelivr'",postversion:"git push origin main --tags","revert-bump":"node revert-bump.js"},h={production:[">0.2%","not dead","not op_mini all"],development:["last 1 chrome version","last 1 firefox version","last 1 safari version"]},g={"@babel/core":"^7.20.2","@babel/preset-env":"^7.20.2","@parcel/transformer-typescript-types":"^2.8.0","@rollup/plugin-babel":"^6.0.2","@rollup/plugin-commonjs":"^23.0.2","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^15.0.1","@rollup/plugin-terser":"^0.4.4","@rollup/plugin-typescript":"^9.0.2","@storybook/addon-actions":"7.6.24","@storybook/addon-essentials":"7.6.24","@storybook/addon-interactions":"7.6.24","@storybook/addon-links":"7.6.24","@storybook/node-logger":"7.6.23","@storybook/preset-create-react-app":"7.6.21","@storybook/react":"7.6.20","@storybook/react-webpack5":"^7.6.20","@storybook/testing-library":"^0.0.13","@testing-library/react":"^13.4.0","@types/audioworklet":"^0.0.95","@types/jest":"^29.2.2","@types/react":"^18.0.26","@types/react-dom":"^18.0.9","@types/styled-components":"^5.1.26",autoprefixer:"^10.4.20",babel:"^6.23.0","babel-plugin-named-exports-order":"^0.0.2",buffer:"^5.7.1","css-loader":"^7.1.2","eslint-plugin-storybook":"^0.9.0",np:"^7.6.2",parcel:"^2.0.0",postcss:"^8.4.49","postcss-loader":"^8.1.1",prettier:"^2.8.0","prop-types":"^15.8.1",rollup:"^2.79.1","rollup-plugin-generate-package-json":"^3.2.0","rollup-plugin-postcss":"^4.0.2",storybook:"^7.6.20","style-loader":"^4.0.0","tailwind-scrollbar":"^3.1.0",tailwindcss:"^3.4.16",typescript:"^4.8.4","webm-duration-fix":"^1.0.4",webpack:"^5.74.0"},w={"nth-check":"^2.0.1"},x="GPL-3.0-or-later",v={name:e,author:s,version:t,description:i,keywords:r,homepage:o,bugs:n,repository:p,private:!1,files:l,main:a,types:d,publishConfig:c,targets:u,dependencies:m,scripts:b,browserslist:h,devDependencies:g,overrides:w,license:x};exports.author=s,exports.browserslist=h,exports.bugs=n,exports.default=v,exports.dependencies=m,exports.description=i,exports.devDependencies=g,exports.files=l,exports.homepage=o,exports.keywords=r,exports.license=x,exports.main=a,exports.name=e,exports.overrides=w,exports.publishConfig=c,exports.repository=p,exports.scripts=b,exports.targets=u,exports.types=d,exports.version=t;
|
|
2
2
|
//# sourceMappingURL=package.json.js.map
|
package/dist/services/user.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../node_modules/tslib/tslib.es6.js"),t=require("../store/index.js");exports.changeDefaultDevice=function(r){return e.__awaiter(this,void 0,void 0,(function(){var s,n,a,o;return e.__generator(this,(function(
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../node_modules/tslib/tslib.es6.js"),t=require("../store/index.js");exports.changeDefaultDevice=function(r){return e.__awaiter(this,void 0,void 0,(function(){var s,n,a,o;return e.__generator(this,(function(c){switch(c.label){case 0:return c.trys.push([0,2,,3]),s=t.store.getState().fetchDefaults,n=s.baseURL,a=s.headers,[4,fetch("".concat(n,"/user/default_device"),{method:"POST",headers:e.__assign({},a),body:JSON.stringify(r)})];case 1:if(!(o=c.sent()).ok)throw new Error(o.statusText);return[2,!0];case 2:throw c.sent();case 3:return[2]}}))}))},exports.changeOperatorStatus=function(r){return e.__awaiter(this,void 0,void 0,(function(){var s,n,a,o;return e.__generator(this,(function(c){switch(c.label){case 0:return c.trys.push([0,2,,3]),s=t.store.getState().fetchDefaults,n=s.baseURL,a=s.headers,[4,fetch("".concat(n,"/user/presence"),{method:"POST",headers:e.__assign({},a),body:JSON.stringify(r)})];case 1:if(!(o=c.sent()).ok)throw new Error(o.statusText);return[2,!0];case 2:throw c.sent();case 3:return[2]}}))}))},exports.checkSummaryCall=function(r){return e.__awaiter(this,void 0,void 0,(function(){var s,n,a,o,c,i;return e.__generator(this,(function(u){switch(u.label){case 0:return s=t.store.getState().fetchDefaults,n=s.baseURL,a=s.headers,[4,fetch("".concat(n,"/summary/").concat(r),{method:"HEAD",headers:e.__assign({},a)})];case 1:if(200===(o=u.sent()).status)return[2,{uniqueid:r,has_summary:!0}];if(204===o.status)throw(c=new Error("Summary not ready")).status=204,c;throw(i=new Error("Failed to check summary: ".concat(o.statusText))).status=o.status,i}}))}))},exports.getAllAvatars=function(){return e.__awaiter(this,void 0,void 0,(function(){var r,s,n,a,o;return e.__generator(this,(function(c){switch(c.label){case 0:return c.trys.push([0,3,,4]),r=t.store.getState().fetchDefaults,s=r.baseURL,n=r.headers,[4,fetch("".concat(s,"/user/all_avatars"),{headers:e.__assign({},n)})];case 1:if(!(a=c.sent()).ok)throw new Error(a.statusText);return[4,a.json()];case 2:return[2,c.sent()];case 3:throw o=c.sent(),new Error(o);case 4:return[2]}}))}))},exports.getAllUsersEndpoints=function(){return e.__awaiter(this,void 0,void 0,(function(){var r,s,n,a,o;return e.__generator(this,(function(c){switch(c.label){case 0:return c.trys.push([0,3,,4]),r=t.store.getState().fetchDefaults,s=r.baseURL,n=r.headers,[4,fetch("".concat(s,"/user/endpoints/all"),{headers:e.__assign({},n)})];case 1:if(!(a=c.sent()).ok)throw new Error(a.statusText);return[4,a.json()];case 2:return[2,c.sent()];case 3:throw o=c.sent(),new Error(o);case 4:return[2]}}))}))},exports.getCurrentUserInfo=function(){return e.__awaiter(this,void 0,void 0,(function(){var r,s,n,a,o;return e.__generator(this,(function(c){switch(c.label){case 0:return c.trys.push([0,3,,4]),r=t.store.getState().fetchDefaults,s=r.baseURL,n=r.headers,[4,fetch("".concat(s,"/user/me"),{headers:e.__assign({},n)})];case 1:if(!(a=c.sent()).ok)throw new Error(a.statusText);return[4,a.json()];case 2:return[2,c.sent()];case 3:throw o=c.sent(),new Error(o);case 4:return[2]}}))}))},exports.getFeatureCodes=function(){return e.__awaiter(this,void 0,void 0,(function(){var r,s,n,a,o;return e.__generator(this,(function(c){switch(c.label){case 0:return c.trys.push([0,3,,4]),r=t.store.getState().fetchDefaults,s=r.baseURL,n=r.headers,[4,fetch("".concat(s,"/astproxy/feature_codes"),{headers:e.__assign({},n)})];case 1:if(!(a=c.sent()).ok)throw new Error(a.statusText);return[4,a.json()];case 2:return[2,c.sent()];case 3:throw o=c.sent(),new Error(o);case 4:return[2]}}))}))},exports.getParamUrl=function(){return e.__awaiter(this,void 0,void 0,(function(){var r,s,n,a,o;return e.__generator(this,(function(c){switch(c.label){case 0:return c.trys.push([0,3,,4]),r=t.store.getState().fetchDefaults,s=r.baseURL,n=r.headers,[4,fetch("".concat(s,"/user/paramurl"),{headers:e.__assign({},n)})];case 1:if(!(a=c.sent()).ok)throw new Error(a.statusText);return[4,a.json()];case 2:return[2,c.sent()];case 3:throw o=c.sent(),new Error(o);case 4:return[2]}}))}))},exports.getVideoSources=function(){return e.__awaiter(this,void 0,void 0,(function(){var r,s,n,a,o;return e.__generator(this,(function(c){switch(c.label){case 0:return c.trys.push([0,3,,4]),r=t.store.getState().fetchDefaults,s=r.baseURL,n=r.headers,[4,fetch("".concat(s,"/streaming/sources"),{headers:e.__assign({},n)})];case 1:if(!(a=c.sent()).ok)throw new Error(a.statusText);return[4,a.json()];case 2:return[2,c.sent()];case 3:throw o=c.sent(),new Error(o);case 4:return[2]}}))}))},exports.openVideoSource=function(r){return e.__awaiter(this,void 0,void 0,(function(){var s,n,a,o;return e.__generator(this,(function(c){switch(c.label){case 0:return c.trys.push([0,2,,3]),s=t.store.getState().fetchDefaults,n=s.baseURL,a=s.headers,[4,fetch("".concat(n,"/streaming/open"),{method:"POST",headers:e.__assign({},a),body:JSON.stringify(r)})];case 1:if(!(o=c.sent()).ok)throw new Error(o.statusText);return[2,!0];case 2:throw c.sent();case 3:return[2]}}))}))},exports.setDefaultDevice=function(r,s){return e.__awaiter(this,void 0,void 0,(function(){var n,a,o,c,i,u,h;return e.__generator(this,(function(f){switch(f.label){case 0:return f.trys.push([0,2,,3]),n=t.store.getState().fetchDefaults,a=n.baseURL,o=n.headers,c={id:s},i={id:s},[4,fetch("".concat(a,"/user/default_device"),{method:"POST",headers:e.__assign({},o),body:"physical"===r?JSON.stringify(i):JSON.stringify(c)})];case 1:if(!(u=f.sent()).ok)throw new Error(u.statusText);return[3,3];case 2:throw h=f.sent(),new Error(h);case 3:return[2]}}))}))},exports.setIncomingCallsPreference=function(r){return e.__awaiter(this,void 0,void 0,(function(){var s,n,a,o,c,i,u;return e.__generator(this,(function(h){switch(h.label){case 0:return h.trys.push([0,4,,5]),s=t.store.getState().fetchDefaults,n=s.baseURL,a=s.headers,[4,fetch("".concat(n,"/user/settings"),{method:"POST",headers:e.__assign({},a),body:JSON.stringify(r)})];case 1:if(!(o=h.sent()).ok)throw new Error(o.statusText);return(c=o.headers.get("content-type"))&&c.includes("application/json")?[4,o.text()]:[3,3];case 2:return[2,(i=h.sent())?JSON.parse(i):{}];case 3:return[2,{success:!0}];case 4:throw u=h.sent(),console.error("Error updating user settings:",u),u;case 5:return[2]}}))}))},exports.setMainDevice=function(r){return e.__awaiter(this,void 0,void 0,(function(){var s,n,a,o;return e.__generator(this,(function(c){switch(c.label){case 0:return c.trys.push([0,2,,3]),s=t.store.getState().fetchDefaults,n=s.baseURL,a=s.headers,[4,fetch("".concat(n,"/user/default_device"),{method:"POST",headers:e.__assign({},a),body:JSON.stringify(r)})];case 1:if(!(o=c.sent()).ok)throw new Error(o.statusText);return[2,!0];case 2:throw c.sent();case 3:return[2]}}))}))},exports.subscribe=function(r){return e.__awaiter(this,void 0,void 0,(function(){var s,n,a,o;return e.__generator(this,(function(c){switch(c.label){case 0:return c.trys.push([0,2,,3]),s=t.store.getState().fetchDefaults,n=s.baseURL,a=s.headers,[4,fetch("".concat(n,"/streaming/subscribe"),{method:"POST",headers:e.__assign({},a),body:JSON.stringify(r)})];case 1:if(!(o=c.sent()).ok)throw new Error(o.statusText);return[2,!0];case 2:throw c.sent();case 3:return[2]}}))}))},exports.unsubscribe=function(r){return e.__awaiter(this,void 0,void 0,(function(){var s,n,a,o;return e.__generator(this,(function(c){switch(c.label){case 0:return c.trys.push([0,2,,3]),s=t.store.getState().fetchDefaults,n=s.baseURL,a=s.headers,[4,fetch("".concat(n,"/streaming/unsubscribe"),{method:"POST",headers:e.__assign({},a),body:JSON.stringify(r)})];case 1:if(!(o=c.sent()).ok)throw new Error(o.statusText);return[2,!0];case 2:throw c.sent();case 3:return[2]}}))}))},exports.watchSummaryCall=function(r){return e.__awaiter(this,void 0,void 0,(function(){var s,n,a,o,c;return e.__generator(this,(function(i){switch(i.label){case 0:return i.trys.push([0,2,,3]),s=t.store.getState().fetchDefaults,n=s.baseURL,a=s.headers,[4,fetch("".concat(n,"/summary/watch"),{method:"POST",headers:e.__assign({},a),body:JSON.stringify({uniqueid:r})})];case 1:if(!(o=i.sent()).ok)throw new Error("Failed to watch summary call: ".concat(o.status," ").concat(o.statusText));return[3,3];case 2:throw c=i.sent(),console.error("Error watching summary call:",c),c;case 3:return[2]}}))}))};
|
|
2
2
|
//# sourceMappingURL=user.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.js","sources":["../../src/services/user.ts"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport { store } from '../store'\nimport type { UserInfoTypes, AvatarsTypes, UsersEndpointsTypes } from '../types'\n\n/**\n * Get current user info\n */\nexport async function getCurrentUserInfo(): Promise<UserInfoTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/me`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function setDefaultDevice(\n default_type: string,\n extensionNumber: string,\n): Promise<any> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n\n let webrtcId: any = { id: extensionNumber }\n let physicalId: any = { id: extensionNumber }\n const response = await fetch(`${baseURL}/user/default_device`, {\n method: 'POST',\n headers: { ...headers },\n body: default_type === 'physical' ? JSON.stringify(physicalId) : JSON.stringify(webrtcId),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\n/**\n * Get all avatars\n */\nexport async function getAllAvatars(): Promise<AvatarsTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n\n const response = await fetch(`${baseURL}/user/all_avatars`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\n/**\n * Get all users endpoints\n */\nexport async function getAllUsersEndpoints(): Promise<UsersEndpointsTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/endpoints/all`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function changeOperatorStatus(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/presence`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function changeDefaultDevice(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/default_device`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function setMainDevice(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/default_device`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\n/**\n * Get parameter URL information\n */\nexport async function getParamUrl(): Promise<UserInfoTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/paramurl`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function getVideoSources(): Promise<UserInfoTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/sources`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function openVideoSource(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/open`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function subscribe(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/subscribe`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function unsubscribe(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/unsubscribe`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function setIncomingCallsPreference(settingsStatus: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/settings`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(settingsStatus),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n\n const contentType = response.headers.get('content-type')\n if (contentType && contentType.includes('application/json')) {\n const text = await response.text()\n return text ? JSON.parse(text) : {}\n }\n\n return { success: true }\n } catch (error: any) {\n console.error('Error updating user settings:', error)\n throw error\n }\n}\n\n/**\n * Get feature codes\n */\nexport async function getFeatureCodes(): Promise<any> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/astproxy/feature_codes`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n"],"names":["obj","_a","store","getState","fetchDefaults","baseURL","headers","fetch","concat","method","__assign","body","JSON","stringify","response","_b","sent","ok","Error","statusText","json","error_3","error_4","error_1","error_14","error_8","error_9"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"user.js","sources":["../../src/services/user.ts"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport { store } from '../store'\nimport type { UserInfoTypes, AvatarsTypes, UsersEndpointsTypes } from '../types'\n\n/**\n * Get current user info\n */\nexport async function getCurrentUserInfo(): Promise<UserInfoTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/me`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function setDefaultDevice(\n default_type: string,\n extensionNumber: string,\n): Promise<any> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n\n let webrtcId: any = { id: extensionNumber }\n let physicalId: any = { id: extensionNumber }\n const response = await fetch(`${baseURL}/user/default_device`, {\n method: 'POST',\n headers: { ...headers },\n body: default_type === 'physical' ? JSON.stringify(physicalId) : JSON.stringify(webrtcId),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\n/**\n * Get all avatars\n */\nexport async function getAllAvatars(): Promise<AvatarsTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n\n const response = await fetch(`${baseURL}/user/all_avatars`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\n/**\n * Get all users endpoints\n */\nexport async function getAllUsersEndpoints(): Promise<UsersEndpointsTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/endpoints/all`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function changeOperatorStatus(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/presence`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function changeDefaultDevice(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/default_device`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function setMainDevice(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/default_device`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\n/**\n * Get parameter URL information\n */\nexport async function getParamUrl(): Promise<UserInfoTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/paramurl`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function getVideoSources(): Promise<UserInfoTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/sources`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function openVideoSource(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/open`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function subscribe(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/subscribe`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function unsubscribe(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/unsubscribe`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function setIncomingCallsPreference(settingsStatus: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/settings`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(settingsStatus),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n\n const contentType = response.headers.get('content-type')\n if (contentType && contentType.includes('application/json')) {\n const text = await response.text()\n return text ? JSON.parse(text) : {}\n }\n\n return { success: true }\n } catch (error: any) {\n console.error('Error updating user settings:', error)\n throw error\n }\n}\n\n/**\n * Get feature codes\n */\nexport async function getFeatureCodes(): Promise<any> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/astproxy/feature_codes`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\n/**\n * Check if a call summary/transcription exists for a given uniqueId\n * Returns: { uniqueid: string, has_summary: boolean }\n * Throws:\n * - Error with status 204 when the summary is not ready yet.\n * - Error with the corresponding HTTP status code for any other non-200 response\n * (including, but not limited to, 401, 403, 404, 503).\n */\nexport async function checkSummaryCall(uniqueId: string): Promise<{ uniqueid: string; has_summary: boolean }> {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/summary/${uniqueId}`, {\n method: 'HEAD',\n headers: { ...headers },\n })\n\n // 200 - Summary exists\n if (response.status === 200) {\n return { uniqueid: uniqueId, has_summary: true }\n }\n\n // 204 - Summary not present yet (not an error, just not ready)\n if (response.status === 204) {\n const error: any = new Error('Summary not ready')\n error.status = 204\n throw error\n }\n\n // 401, 403, 404, 503 - Real errors\n const error: any = new Error(`Failed to check summary: ${response.statusText}`)\n error.status = response.status\n throw error\n}\n\n/**\n * Watch for call summary/transcription for a given linkedId (uniqueid)\n */\nexport async function watchSummaryCall(uniqueid: string): Promise<void> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/summary/watch`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify({ uniqueid }),\n })\n if (!response.ok) {\n throw new Error(`Failed to watch summary call: ${response.status} ${response.statusText}`)\n }\n } catch (error: any) {\n console.error('Error watching summary call:', error)\n throw error\n }\n}\n"],"names":["obj","_a","store","getState","fetchDefaults","baseURL","headers","fetch","concat","method","__assign","body","JSON","stringify","response","_b","sent","ok","Error","statusText","uniqueId","status","uniqueid","has_summary","error_15","error","json","error_3","error_4","error_1","error_14","error_8","error_9","default_type","extensionNumber","webrtcId","id","physicalId","error_2","settingsStatus","contentType","get","includes","text","parse","success","console","error_13","error_16"],"mappings":"mLAuGM,SAAoCA,+HAGrB,6BADXC,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QACP,CAAA,EAAMC,MAAM,GAAGC,OAAAH,0BAA+B,CAC7DI,OAAQ,OACRH,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,GACdK,KAAMC,KAAKC,UAAUb,aAEvB,KALMc,EAAWC,EAIfC,QACYC,GACZ,MAAM,IAAIC,MAAMJ,EAASK,YAE3B,MAAA,CAAA,GAAO,UAEP,sCAEH,+BAhCK,SAAqCnB,+HAGtB,6BADXC,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QACP,CAAA,EAAMC,MAAM,GAAGC,OAAAH,oBAAyB,CACvDI,OAAQ,OACRH,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,GACdK,KAAMC,KAAKC,UAAUb,aAEvB,KALMc,EAAWC,EAIfC,QACYC,GACZ,MAAM,IAAIC,MAAMJ,EAASK,YAE3B,MAAA,CAAA,GAAO,UAEP,sCAEH,2BA8KK,SAAiCC,mIAEpB,OADXnB,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QACP,CAAA,EAAMC,MAAM,GAAAC,OAAGH,EAAmB,aAAAG,OAAAY,GAAY,CAC7DX,OAAQ,OACRH,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,aAIhB,GAAwB,OANlBQ,EAAWC,EAGfC,QAGWK,OACX,MAAO,CAAA,EAAA,CAAEC,SAAUF,EAAUG,aAAa,IAI5C,GAAwB,MAApBT,EAASO,OAGX,MAFMG,EAAa,IAAIN,MAAM,sBACvBG,OAAS,IACTG,EAMR,MAFMC,EAAa,IAAIP,MAAM,4BAAAV,OAA4BM,EAASK,cAC5DE,OAASP,EAASO,OAClBI,QACP,iKApPoB,6BAFXxB,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QAEP,CAAA,EAAMC,MAAM,GAAGC,OAAAH,uBAA4B,CAC1DC,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,aAEhB,KAHMQ,EAAWC,EAEfC,QACYC,GACZ,MAAM,IAAIC,MAAMJ,EAASK,YAEd,MAAA,CAAA,EAAML,EAASY,eAC5B,MAAA,CAAA,EADaX,EAAqBC,eAGlC,iBAAM,IAAIE,MAAMS,0BAEnB,wKAQoB,6BADX1B,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QACP,CAAA,EAAMC,MAAM,GAAGC,OAAAH,yBAA8B,CAC5DC,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,aAEhB,KAHMQ,EAAWC,EAEfC,QACYC,GACZ,MAAM,IAAIC,MAAMJ,EAASK,YAEd,MAAA,CAAA,EAAML,EAASY,eAC5B,MAAA,CAAA,EADaX,EAAqBC,eAGlC,iBAAM,IAAIE,MAAMU,0BAEnB,sKAxEoB,6BADX3B,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QACP,CAAA,EAAMC,MAAM,GAAGC,OAAAH,cAAmB,CACjDC,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,aAEhB,KAHMQ,EAAWC,EAEfC,QACYC,GACZ,MAAM,IAAIC,MAAMJ,EAASK,YAEd,MAAA,CAAA,EAAML,EAASY,eAC5B,MAAA,CAAA,EADaX,EAAqBC,eAGlC,iBAAM,IAAIE,MAAMW,0BAEnB,mKAuOoB,6BADX5B,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QACP,CAAA,EAAMC,MAAM,GAAGC,OAAAH,6BAAkC,CAChEC,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,aAEhB,KAHMQ,EAAWC,EAEfC,QACYC,GACZ,MAAM,IAAIC,MAAMJ,EAASK,YAEd,MAAA,CAAA,EAAML,EAASY,eAC5B,MAAA,CAAA,EADaX,EAAqBC,eAGlC,iBAAM,IAAIE,MAAMY,0BAEnB,+JA1HoB,6BADX7B,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QACP,CAAA,EAAMC,MAAM,GAAGC,OAAAH,oBAAyB,CACvDC,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,aAEhB,KAHMQ,EAAWC,EAEfC,QACYC,GACZ,MAAM,IAAIC,MAAMJ,EAASK,YAEd,MAAA,CAAA,EAAML,EAASY,eAC5B,MAAA,CAAA,EADaX,EAAqBC,eAGlC,iBAAM,IAAIE,MAAMa,0BAEnB,mKAKoB,6BADX9B,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QACP,CAAA,EAAMC,MAAM,GAAGC,OAAAH,wBAA6B,CAC3DC,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,aAEhB,KAHMQ,EAAWC,EAEfC,QACYC,GACZ,MAAM,IAAIC,MAAMJ,EAASK,YAEd,MAAA,CAAA,EAAML,EAASY,eAC5B,MAAA,CAAA,EADaX,EAAqBC,eAGlC,iBAAM,IAAIE,MAAMc,0BAEnB,0BAEK,SAAgChC,+HAGjB,6BADXC,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QACP,CAAA,EAAMC,MAAM,GAAGC,OAAAH,qBAA0B,CACxDI,OAAQ,OACRH,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,GACdK,KAAMC,KAAKC,UAAUb,aAEvB,KALMc,EAAWC,EAIfC,QACYC,GACZ,MAAM,IAAIC,MAAMJ,EAASK,YAE3B,MAAA,CAAA,GAAO,UAEP,sCAEH,2BAlKqB,SACpBc,EACAC,qIAOmB,6BAJXjC,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QAEpB6B,EAAgB,CAAEC,GAAIF,GACtBG,EAAkB,CAAED,GAAIF,GACX,CAAA,EAAM3B,MAAM,GAAGC,OAAAH,0BAA+B,CAC7DI,OAAQ,OACRH,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,GACdK,KAAuB,aAAjBsB,EAA8BrB,KAAKC,UAAUwB,GAAczB,KAAKC,UAAUsB,aAElF,KALMrB,EAAWC,EAIfC,QACYC,GACZ,MAAM,IAAIC,MAAMJ,EAASK,+BAG3B,iBAAM,IAAID,MAAMoB,0BAEnB,qCAkLK,SAA2CC,qIAG5B,6BADXtC,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QACP,CAAA,EAAMC,MAAM,GAAGC,OAAAH,oBAAyB,CACvDI,OAAQ,OACRH,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,GACdK,KAAMC,KAAKC,UAAU0B,aAEvB,KALMzB,EAAWC,EAIfC,QACYC,GACZ,MAAM,IAAIC,MAAMJ,EAASK,mBAGrBqB,EAAc1B,EAASR,QAAQmC,IAAI,kBACtBD,EAAYE,SAAS,oBACzB,CAAA,EAAM5B,EAAS6B,QAD6B,CAAA,EAAA,UAEzD,MAAA,CAAA,GADMA,EAAO5B,EAAqBC,QACpBJ,KAAKgC,MAAMD,GAAQ,CAAA,GAGnC,KAAA,EAAA,MAAA,CAAA,EAAO,CAAEE,SAAS,WAGlB,iBADAC,QAAQrB,MAAM,gCAAiCsB,GACzCA,yBAET,wBA9HK,SAA8B/C,+HAGf,6BADXC,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QACP,CAAA,EAAMC,MAAM,GAAGC,OAAAH,0BAA+B,CAC7DI,OAAQ,OACRH,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,GACdK,KAAMC,KAAKC,UAAUb,aAEvB,KALMc,EAAWC,EAIfC,QACYC,GACZ,MAAM,IAAIC,MAAMJ,EAASK,YAE3B,MAAA,CAAA,GAAO,UAEP,sCAEH,oBAsDK,SAA0BnB,+HAGX,6BADXC,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QACP,CAAA,EAAMC,MAAM,GAAGC,OAAAH,0BAA+B,CAC7DI,OAAQ,OACRH,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,GACdK,KAAMC,KAAKC,UAAUb,aAEvB,KALMc,EAAWC,EAIfC,QACYC,GACZ,MAAM,IAAIC,MAAMJ,EAASK,YAE3B,MAAA,CAAA,GAAO,UAEP,sCAEH,sBAEK,SAA4BnB,+HAGb,6BADXC,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QACP,CAAA,EAAMC,MAAM,GAAGC,OAAAH,4BAAiC,CAC/DI,OAAQ,OACRH,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,GACdK,KAAMC,KAAKC,UAAUb,aAEvB,KALMc,EAAWC,EAIfC,QACYC,GACZ,MAAM,IAAIC,MAAMJ,EAASK,YAE3B,MAAA,CAAA,GAAO,UAEP,sCAEH,2BAkFK,SAAiCG,iIAGlB,6BADXrB,EAAuBC,EAAKA,MAACC,WAAWC,cAAtCC,EAAOJ,EAAAI,QAAEC,EAAOL,EAAAK,QACP,CAAA,EAAMC,MAAM,GAAGC,OAAAH,oBAAyB,CACvDI,OAAQ,OACRH,QAAOI,EAAAA,SAAA,CAAA,EAAOJ,GACdK,KAAMC,KAAKC,UAAU,CAAES,SAAQA,cAEjC,KALMR,EAAWC,EAIfC,QACYC,GACZ,MAAM,IAAIC,MAAM,iCAAAV,OAAiCM,EAASO,OAAM,KAAAb,OAAIM,EAASK,gCAI/E,iBADA2B,QAAQrB,MAAM,+BAAgCuB,GACxCA,yBAET"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nethesis/phone-island",
|
|
3
3
|
"author": "Nethesis",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "1.0.0-dev.2",
|
|
5
5
|
"description": "NethVoice CTI Phone Island",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"nethserver",
|
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
"publish:minor": "node check-publish.js minor && npm version minor --allow-same-version -m v%s --force",
|
|
85
85
|
"publish:major": "node check-publish.js major && npm version major --allow-same-version -m v%s --force",
|
|
86
86
|
"publish:patch": "node check-publish.js patch && npm version patch --allow-same-version -m v%s --force",
|
|
87
|
+
"publish:dev": "node publish-dev.js",
|
|
87
88
|
"preversion": "rm -rf dist-widget && npm run build:widget && git add dist-widget/index.widget.js dist-widget/index.widget.css && git commit -m 'chore(widget): release for jsDelivr'",
|
|
88
89
|
"postversion": "git push origin main --tags",
|
|
89
90
|
"revert-bump": "node revert-bump.js"
|
|
@@ -110,10 +111,10 @@
|
|
|
110
111
|
"@rollup/plugin-node-resolve": "^15.0.1",
|
|
111
112
|
"@rollup/plugin-terser": "^0.4.4",
|
|
112
113
|
"@rollup/plugin-typescript": "^9.0.2",
|
|
113
|
-
"@storybook/addon-actions": "7.6.
|
|
114
|
-
"@storybook/addon-essentials": "7.6.
|
|
115
|
-
"@storybook/addon-interactions": "7.6.
|
|
116
|
-
"@storybook/addon-links": "7.6.
|
|
114
|
+
"@storybook/addon-actions": "7.6.24",
|
|
115
|
+
"@storybook/addon-essentials": "7.6.24",
|
|
116
|
+
"@storybook/addon-interactions": "7.6.24",
|
|
117
|
+
"@storybook/addon-links": "7.6.24",
|
|
117
118
|
"@storybook/node-logger": "7.6.23",
|
|
118
119
|
"@storybook/preset-create-react-app": "7.6.21",
|
|
119
120
|
"@storybook/react": "7.6.20",
|