Всем привет! Меня зовут Хатам. Я работаю в компании Neti. Когда-то я был верстальщиком сайтов, но мне хотелось развиваться дальше. Поэтому я изучил React и научился делать веб-приложения, а затем решил попробовать свои силы в мобильной разработке. В этой статье я делюсь примерами решений, к которым пришел, работая над задачей одного из клиентов. Надеюсь, что мой опыт будет кому-то полезен. Мобильное приложение, предназначенное для быстрой отправки сообщений о проблемах и опасных факторах для жизни и здоровья людей на территории производственного предприятия. Пользователи: сотрудники компании, подрядчики и гости предприятия. Платформы: Android, IOS. Стек технологий: React Native, MobX. Возможности, которые необходимо было реализовать:  Запись голоса; Отмена записи свайпом вправо с анимацией и изменением иконки; Воспроизведение записанного звука.  Также записанный голос должен был воспроизводиться в админке в браузере. Вот как это должно работать: Я приступил к поиску библиотеки. Из найденных вариантов самым популярным оказался react-native-audio-recorder-player. Основным его плюсом является принцип «2 в 1», то есть запись и воспроизведение записанного аудио. Сделал два компонента: AudioRecorder и AudioPlayer. Начнем с AudioRecorder.tsx. Библиотеку нашел, но она не умеет по свайпу отменять запись. Это надо было реализовать самостоятельно. После долгих поисков и раздумий в голову пришла идея: а что, если этот свайп сделать слайдером? Почему бы и нет: у слайдера есть состояние, которое позволяет плавно анимировать нужный элемент и прописать отмену на определенной позиции. Но чтобы сделать такую кнопку, какая нам нужна, слайдер должен быть нестандартный. Поэтому подключил библиотеку react-native-slider-custom. Скрыл полосу слайдера, сделал кнопку «запись/отмена» с динамичными иконками, сделал абсолютное позиционирование поверх двух блоков: текста и продолжительности записи. Все готово, идея сработала 😎 Для реализации отмены записи воспользовался методом onSlidingComplete у библиотеки слайдера, который срабатывает при отпускании ползунка. Позицию отмены решил сделать 80%. Вынес в константу для удобства CANCEL_RECORDING_SLIDER_VALUE, равный 0.8, потому что слайдер по умолчанию работает от 0 до 1. При отпускании кнопки записи (ползунка слайдера) вызываем обработчик handleSlidingComplete. Он, в свою очередь, вызывает функцию onStopRecord, передавая туда позицию слайдера на момент отпускания. В функции onStopRecord в зависимости от позиции слайдера делаем проверку: сохранить запись или отменить запись. Чтобы определить, какое действие выполнить, прописываем условие value > CANCEL_RECORDING_SLIDER_VALUE. Если значения слайдера при отпускании кнопки записи больше 0.8 — отменяем запись, если меньше — сохраняем. Вот и все! Это обычный кастомный аудиоплеер с некоторыми отличиями библиотеки.  Чтобы рекордер и плеер работали совместно, нужно использовать один и тот же экземпляр плеера. Также для хорошего UX нужно было отключить скролл экрана "Создания сообщения о риске" во время записи голоса, чтобы работал только слайдер. Поэтому сделал MobX стор AudioRecPlayStore.ts. В сторе есть следующие свойства: Экземпляр плеера audioRecorderPlayer для переключение из рекордера в плеер и обратно; Состояние записи isRecording для отключения скролла во время записи. За рендер рекордера или плеера отвечает компонент MessageAudioMessage.tsx. Были проблемы с воспроизведением записанного голоса на разных платформах из разных платформ: они были несовместимы. Решение есть в самой документации библиотеки рекордера.  Создаем объект audioSet с настройками записи аудиофайла и передаем как второй аргумент методу startRecorder. Эти настройки кроссплатформенные, то есть записанный голос на Android/iOS воспроизводится на вебе в нативном html5 плеере и на Android/iOS. Полезные ресурсы: https://www.npmjs.com/package/react-native-audio-recorder-player  https://www.npmjs.com/package/react-native-slider-custom Team Lead, React / React Native Developer в Neti