UNPKG

stream-chat-react-native-core

Version:

The official React Native and Expo components for Stream Chat, a service for building chat applications

261 lines 11.8 kB
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.AudioAttachment = void 0; var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _react = _interopRequireWildcard(require("react")); var _reactNative = require("react-native"); var _dayjs = _interopRequireDefault(require("dayjs")); var _duration = _interopRequireDefault(require("dayjs/plugin/duration")); var _streamChat = require("stream-chat"); var _PlayPauseButton = require("./PlayPauseButton"); var _contexts = require("../../../contexts"); var _hooks = require("../../../hooks"); var _useAudioPlayer = require("../../../hooks/useAudioPlayer"); var _native = require("../../../native"); var _theme = require("../../../theme"); var _ProgressControl = require("../../ProgressControl/ProgressControl"); var _StableDurationLabel = require("../../ProgressControl/StableDurationLabel"); var _WaveProgressBar = require("../../ProgressControl/WaveProgressBar"); var _SpeedSettingsButton = require("../../ui/SpeedSettingsButton"); var _jsxRuntime = require("react/jsx-runtime"); var _jsxFileName = "/home/runner/work/stream-chat-react-native/stream-chat-react-native/package/src/components/Attachment/Audio/AudioAttachment.tsx"; function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } var ONE_HOUR_IN_MILLISECONDS = 3600 * 1000; var ONE_SECOND_IN_MILLISECONDS = 1000; _dayjs.default.extend(_duration.default); var getAudioDurationLabel = durationInMilliseconds => { if (!durationInMilliseconds) { return '00:00'; } return durationInMilliseconds / ONE_HOUR_IN_MILLISECONDS >= 1 ? _dayjs.default.duration(durationInMilliseconds, 'milliseconds').format('HH:mm:ss') : _dayjs.default.duration(durationInMilliseconds, 'milliseconds').format('mm:ss'); }; var audioPlayerSelector = state => ({ currentPlaybackRate: state.currentPlaybackRate, duration: state.duration, isPlaying: state.isPlaying, position: state.position, progress: state.progress }); var AudioAttachment = props => { var soundRef = _react.default.useRef(null); var styles = useStyles(); var _props$hideProgressBa = props.hideProgressBar, hideProgressBar = _props$hideProgressBa === void 0 ? false : _props$hideProgressBa, item = props.item, message = props.message, _props$showSpeedSetti = props.showSpeedSettings, showSpeedSettings = _props$showSpeedSetti === void 0 ? false : _props$showSpeedSetti, _props$showTitle = props.showTitle, showTitle = _props$showTitle === void 0 ? true : _props$showTitle, testID = props.testID, _props$isPreview = props.isPreview, isPreview = _props$isPreview === void 0 ? false : _props$isPreview, containerStyle = props.containerStyle, stylesProps = props.styles, indicator = props.indicator; var isVoiceRecording = (0, _streamChat.isVoiceRecordingAttachment)(item); var audioPlayer = (0, _useAudioPlayer.useAudioPlayer)({ duration: item.duration ?? 0, mimeType: item.mime_type ?? '', requester: isPreview ? 'preview' : message?.id && `${message?.parent_id ?? message?.id}${message?.id}`, type: isVoiceRecording ? 'voiceRecording' : 'audio', uri: item.asset_url ?? '' }); var _useStateStore = (0, _hooks.useStateStore)(audioPlayer.state, audioPlayerSelector), duration = _useStateStore.duration, isPlaying = _useStateStore.isPlaying, position = _useStateStore.position, progress = _useStateStore.progress, currentPlaybackRate = _useStateStore.currentPlaybackRate; (0, _react.useEffect)(() => { if (soundRef.current) { audioPlayer.initPlayer({ playerRef: soundRef.current }); } }, [audioPlayer]); (0, _react.useEffect)(() => () => { if (isPreview) { audioPlayer.onRemove(); } }, [audioPlayer, isPreview]); var handleLoad = payload => { if (isVoiceRecording) { return; } audioPlayer.duration = payload.duration * ONE_SECOND_IN_MILLISECONDS; }; var handleProgress = data => { var currentTime = data.currentTime; audioPlayer.position = currentTime * ONE_SECOND_IN_MILLISECONDS; }; var onSeek = seekResponse => { audioPlayer.position = seekResponse.currentTime * ONE_SECOND_IN_MILLISECONDS; }; var handlePlayPause = () => { audioPlayer.toggle(); }; var handleEnd = function () { var _ref = (0, _asyncToGenerator2.default)(function* () { yield audioPlayer.stop(); }); return function handleEnd() { return _ref.apply(this, arguments); }; }(); var dragStart = (0, _hooks.useStableCallback)(() => { audioPlayer.pause(); }); var dragEnd = (0, _hooks.useStableCallback)(function () { var _ref2 = (0, _asyncToGenerator2.default)(function* (currentProgress) { var positionInSeconds = currentProgress * duration / ONE_SECOND_IN_MILLISECONDS; yield audioPlayer.seek(positionInSeconds); }); return function (_x) { return _ref2.apply(this, arguments); }; }()); var onSpeedChangeHandler = function () { var _ref3 = (0, _asyncToGenerator2.default)(function* () { yield audioPlayer.changePlaybackRate(); }); return function onSpeedChangeHandler() { return _ref3.apply(this, arguments); }; }(); var _useTheme = (0, _contexts.useTheme)(), _useTheme$theme = _useTheme.theme, _useTheme$theme$audio = _useTheme$theme.audioAttachment, container = _useTheme$theme$audio.container, centerContainer = _useTheme$theme$audio.centerContainer, audioInfo = _useTheme$theme$audio.audioInfo, leftContainer = _useTheme$theme$audio.leftContainer, progressControlContainer = _useTheme$theme$audio.progressControlContainer, progressDurationText = _useTheme$theme$audio.progressDurationText, rightContainer = _useTheme$theme$audio.rightContainer, semantics = _useTheme$theme.semantics, filenameText = _useTheme$theme.messageComposer.fileAttachmentUploadPreview.filenameText; var maxDurationLabel = (0, _react.useMemo)(() => getAudioDurationLabel(duration), [duration]); var remainingDuration = (0, _react.useMemo)(() => Math.max(duration - position, 0), [duration, position]); var progressDuration = (0, _react.useMemo)(() => getAudioDurationLabel(remainingDuration || duration), [duration, remainingDuration]); return (0, _jsxRuntime.jsxs)(_reactNative.View, { accessibilityLabel: "audio-attachment-preview", style: [styles.container, container, containerStyle, stylesProps?.container], testID: testID, children: [(0, _jsxRuntime.jsx)(_reactNative.View, { style: [styles.leftContainer, stylesProps?.leftContainer, leftContainer], children: (0, _jsxRuntime.jsx)(_PlayPauseButton.PlayPauseButton, { isPlaying: isPlaying, accessibilityLabel: "Play Pause Button", onPress: handlePlayPause, containerStyle: stylesProps?.playPauseButton }) }), (0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.centerContainer, { flexGrow: 1, flexShrink: showTitle ? 1 : 0 }, centerContainer], children: [showTitle ? (0, _jsxRuntime.jsx)(_reactNative.Text, { accessibilityLabel: "File Name", numberOfLines: 1, style: [styles.filenameText, _reactNative.I18nManager.isRTL ? { writingDirection: 'rtl' } : { writingDirection: 'ltr' }, filenameText], children: (0, _streamChat.isVoiceRecordingAttachment)(item) || (0, _streamChat.isLocalVoiceRecordingAttachment)(item) ? 'Voice Message' : item.title }) : null, indicator ? indicator : (0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.audioInfo, audioInfo], children: [(0, _jsxRuntime.jsx)(_StableDurationLabel.StableDurationLabel, { accessibilityLabel: "Progress Duration", reserveLabel: maxDurationLabel, label: progressDuration, style: [styles.progressDurationText, progressDurationText, stylesProps?.durationText], visibleStyle: { color: isPlaying ? semantics.accentPrimary : semantics.textSecondary } }), !hideProgressBar && (0, _jsxRuntime.jsx)(_reactNative.View, { style: [styles.progressControlContainer, progressControlContainer], children: item.waveform_data ? (0, _jsxRuntime.jsx)(_WaveProgressBar.WaveProgressBar, { isPlaying: isPlaying, onEndDrag: dragEnd, onStartDrag: dragStart, progress: progress, waveformData: item.waveform_data }) : (0, _jsxRuntime.jsx)(_ProgressControl.ProgressControl, { isPlaying: isPlaying, onEndDrag: dragEnd, onStartDrag: dragStart, progress: progress, testID: "progress-control" }) })] }), _native.NativeHandlers.Sound?.Player && (0, _jsxRuntime.jsx)(_native.NativeHandlers.Sound.Player, { onEnd: handleEnd, onLoad: handleLoad, onProgress: handleProgress, onSeek: onSeek, paused: !isPlaying, rate: currentPlaybackRate, soundRef: soundRef, testID: "sound-player", uri: item.asset_url })] }), showSpeedSettings && !indicator ? (0, _jsxRuntime.jsx)(_reactNative.View, { style: [styles.rightContainer, rightContainer], children: (0, _jsxRuntime.jsx)(_SpeedSettingsButton.SpeedSettingsButton, { currentPlaybackRate: currentPlaybackRate, onPress: onSpeedChangeHandler, containerStyle: stylesProps?.speedSettingsButton }) }) : null] }); }; exports.AudioAttachment = AudioAttachment; var useStyles = () => { var _useTheme2 = (0, _contexts.useTheme)(), semantics = _useTheme2.theme.semantics; return (0, _react.useMemo)(() => { return _reactNative.StyleSheet.create({ container: { alignItems: 'center', flexDirection: 'row', padding: _theme.primitives.spacingSm, gap: _theme.primitives.spacingXs, minWidth: 256, borderColor: semantics.borderCoreDefault, borderWidth: 1 }, audioInfo: { alignItems: 'center', flexDirection: 'row', gap: _theme.primitives.spacingXxs }, centerContainer: { gap: _theme.primitives.spacingXxs }, filenameText: { color: semantics.textPrimary, fontSize: _theme.primitives.typographyFontSizeSm, fontWeight: _theme.primitives.typographyFontWeightSemiBold, lineHeight: _theme.primitives.typographyLineHeightTight }, leftContainer: {}, progressControlContainer: { flex: 1 }, progressDurationText: { color: semantics.textPrimary, fontVariant: ['tabular-nums'], fontSize: _theme.primitives.typographyFontSizeXs, fontWeight: _theme.primitives.typographyFontWeightRegular, lineHeight: _theme.primitives.typographyLineHeightTight }, rightContainer: {} }); }, [semantics]); }; AudioAttachment.displayName = 'AudioAttachment{messageComposer{audioAttachment}}'; //# sourceMappingURL=AudioAttachment.js.map