-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[RNMobile] Audio Player UI for audio block (#27467)
* Basics of Audio block working * Add audio support to MediaUpload * Add handling of file uploads and replace * WPMediaLibrary support for Audio block * Avoid removing media info on error state * Linting * Added an AUDIO file to the test requestMediaPickFromMediaLibrary func * Fixed typo in ToolbarButton of Audio Block. * Removed auto help behavior present on web that's not used on mobile. * [Android] Wired the click of the Audio Media Library button. * Added Audio media options for choosing audio file locally. * [RNMobile] Audio Block: Proper caption field (#27689) * Audio Player UI for audio block * Add extension to styles import * Show file name while loading and retry message on error * Pass state props to audio player component * Implement placeholder-ish player UI structure * added styles for icon, title and subtitle * added blue-wordpress as link color. * added sizing based on design specs. * Fixed object destructuring error. * added icon styling state for upload in progress or upload failed. * implemented error style and behavior. * added styling for upload failed text. * Override MediaUploadProgress styles * Update filename extension spseration to handle two dots * Update UI structure and styles * Make retry message translateable * Update snaphots * Fix lint error * Set initial file name * Remove devOnly flag from audio block * Increase tap target of button * Add 1px between title and subtitle * Align title, subtitle and button vertically * On iOS use VideoPlayer to play audio files in-app * Revert "On iOS use VideoPlayer to play audio files in-app" This reverts commit b1eb8dd. * [RNMobile] Audio Block - Cancel and Retry Dialog (#28540) Co-authored-by: Ceyhun Ozugur <[email protected]> * Rename button title * Add pill-shaped background to button * Add padding to title * Fix file title being empty when selecting from media library * Use safeDecodeURI * On iOS use VideoPlayer to play audio files in-app * Decrease button font size Co-authored-by: Joel Dean <[email protected]> * Revert "Remove devOnly flag from audio block" This reverts commit e6b5b6d. * Add right padding to title container to fix error state Co-authored-by: Joel Dean <[email protected]> Co-authored-by: Ceyhun Ozugur <[email protected]>
- Loading branch information
1 parent
0ff5cc6
commit aadc511
Showing
9 changed files
with
408 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
.progressContainer { | ||
border-radius: 4px; | ||
overflow: hidden; | ||
} | ||
|
||
.progressBar { | ||
height: 4px; | ||
margin-bottom: -4px; | ||
} | ||
|
||
.spinner { | ||
height: 4px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
225 changes: 225 additions & 0 deletions
225
packages/components/src/mobile/audio-player/index.native.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,225 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { | ||
Text, | ||
TouchableWithoutFeedback, | ||
Linking, | ||
Alert, | ||
Platform, | ||
} from 'react-native'; | ||
import { default as VideoPlayer } from 'react-native-video'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { View } from '@wordpress/primitives'; | ||
import { Icon } from '@wordpress/components'; | ||
import { withPreferredColorScheme } from '@wordpress/compose'; | ||
import { __ } from '@wordpress/i18n'; | ||
import { audio, warning } from '@wordpress/icons'; | ||
import { | ||
requestImageFailedRetryDialog, | ||
requestImageUploadCancelDialog, | ||
} from '@wordpress/react-native-bridge'; | ||
import { getProtocol, safeDecodeURI } from '@wordpress/url'; | ||
import { useState } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import styles from './styles.scss'; | ||
|
||
const isIOS = Platform.OS === 'ios'; | ||
|
||
function Player( { | ||
getStylesFromColorScheme, | ||
isUploadInProgress, | ||
isUploadFailed, | ||
attributes, | ||
isSelected, | ||
} ) { | ||
const { id, src } = attributes; | ||
const [ paused, setPaused ] = useState( true ); | ||
|
||
const onPressListen = () => { | ||
if ( src ) { | ||
if ( isIOS && this.player ) { | ||
this.player.presentFullscreenPlayer(); | ||
return; | ||
} | ||
|
||
Linking.canOpenURL( src ) | ||
.then( ( supported ) => { | ||
if ( ! supported ) { | ||
Alert.alert( | ||
__( 'Problem opening the audio' ), | ||
__( 'No application can handle this request.' ) | ||
); | ||
} else { | ||
return Linking.openURL( src ); | ||
} | ||
} ) | ||
.catch( () => { | ||
Alert.alert( | ||
__( 'Problem opening the audio' ), | ||
__( 'An unknown error occurred. Please try again.' ) | ||
); | ||
} ); | ||
} | ||
}; | ||
|
||
const containerStyle = getStylesFromColorScheme( | ||
styles.container, | ||
styles.containerDark | ||
); | ||
|
||
const iconStyle = getStylesFromColorScheme( styles.icon, styles.iconDark ); | ||
|
||
const iconDisabledStyle = getStylesFromColorScheme( | ||
styles.iconDisabled, | ||
styles.iconDisabledDark | ||
); | ||
|
||
const isDisabled = isUploadFailed || isUploadInProgress; | ||
|
||
const finalIconStyle = { | ||
...iconStyle, | ||
...( isDisabled && iconDisabledStyle ), | ||
}; | ||
|
||
const iconContainerStyle = getStylesFromColorScheme( | ||
styles.iconContainer, | ||
styles.iconContainerDark | ||
); | ||
|
||
const titleContainerStyle = { | ||
...styles.titleContainer, | ||
...( isIOS ? styles.titleContainerIOS : styles.titleContainerAndroid ), | ||
}; | ||
|
||
const titleStyle = getStylesFromColorScheme( | ||
styles.title, | ||
styles.titleDark | ||
); | ||
|
||
const uploadFailedStyle = getStylesFromColorScheme( | ||
styles.uploadFailed, | ||
styles.uploadFailedDark | ||
); | ||
|
||
const subtitleStyle = getStylesFromColorScheme( | ||
styles.subtitle, | ||
styles.subtitleDark | ||
); | ||
|
||
const finalSubtitleStyle = { | ||
...subtitleStyle, | ||
...( isUploadFailed && uploadFailedStyle ), | ||
}; | ||
|
||
const buttonBackgroundStyle = getStylesFromColorScheme( | ||
styles.buttonBackground, | ||
styles.buttonBackgroundDark | ||
); | ||
|
||
let title = ''; | ||
let extension = ''; | ||
|
||
if ( src ) { | ||
const decodedURI = safeDecodeURI( src ); | ||
const fileName = decodedURI.split( '/' ).pop(); | ||
const parts = fileName.split( '.' ); | ||
extension = parts.pop().toUpperCase(); | ||
title = parts.join( '.' ); | ||
} | ||
|
||
const getSubtitleValue = () => { | ||
if ( isUploadInProgress ) { | ||
return __( 'Uploading…' ); | ||
} | ||
if ( isUploadFailed ) { | ||
return __( 'Failed to insert audio file. Please tap for options.' ); | ||
} | ||
return ( | ||
extension + | ||
// translators: displays audio file extension. e.g. MP3 audio file | ||
__( ' audio file' ) | ||
); | ||
}; | ||
|
||
function onAudioUploadCancelDialog() { | ||
if ( isUploadInProgress ) { | ||
requestImageUploadCancelDialog( id ); | ||
} else if ( id && getProtocol( src ) === 'file:' ) { | ||
requestImageFailedRetryDialog( id ); | ||
} | ||
} | ||
|
||
return ( | ||
<TouchableWithoutFeedback | ||
accessible={ ! isSelected } | ||
disabled={ ! isSelected } | ||
onPress={ onAudioUploadCancelDialog } | ||
> | ||
<View style={ containerStyle }> | ||
<View style={ iconContainerStyle }> | ||
<Icon icon={ audio } style={ finalIconStyle } size={ 24 } /> | ||
</View> | ||
<View style={ titleContainerStyle }> | ||
<Text style={ titleStyle }>{ title }</Text> | ||
<View style={ styles.subtitleContainer }> | ||
{ isUploadFailed && ( | ||
<Icon | ||
icon={ warning } | ||
style={ { | ||
...styles.errorIcon, | ||
...uploadFailedStyle, | ||
} } | ||
size={ 16 } | ||
/> | ||
) } | ||
<Text style={ finalSubtitleStyle }> | ||
{ getSubtitleValue() } | ||
</Text> | ||
</View> | ||
</View> | ||
{ ! isDisabled && ( | ||
<TouchableWithoutFeedback | ||
accessibilityLabel={ __( 'Audio Player' ) } | ||
accessibilityRole={ 'button' } | ||
accessibilityHint={ __( | ||
'Double tap to listen the audio file' | ||
) } | ||
onPress={ onPressListen } | ||
> | ||
<View style={ buttonBackgroundStyle }> | ||
<Text style={ styles.buttonText }> | ||
{ __( 'OPEN' ) } | ||
</Text> | ||
</View> | ||
</TouchableWithoutFeedback> | ||
) } | ||
{ isIOS && ( | ||
<VideoPlayer | ||
source={ { uri: src } } | ||
paused={ paused } | ||
ref={ ( ref ) => { | ||
this.player = ref; | ||
} } | ||
controls={ false } | ||
ignoreSilentSwitch={ 'ignore' } | ||
onFullscreenPlayerWillPresent={ () => { | ||
setPaused( false ); | ||
} } | ||
onFullscreenPlayerDidDismiss={ () => { | ||
setPaused( true ); | ||
} } | ||
/> | ||
) } | ||
</View> | ||
</TouchableWithoutFeedback> | ||
); | ||
} | ||
|
||
export default withPreferredColorScheme( Player ); |
Oops, something went wrong.