1 |
|
2 |
|
3 |
|
4 | import { getBlobByURL, isBlobURL } from '@wordpress/blob';
|
5 | import {
|
6 | Disabled,
|
7 | IconButton,
|
8 | PanelBody,
|
9 | SelectControl,
|
10 | ToggleControl,
|
11 | Toolbar,
|
12 | withNotices,
|
13 | } from '@wordpress/components';
|
14 | import {
|
15 | BlockControls,
|
16 | BlockIcon,
|
17 | InspectorControls,
|
18 | MediaPlaceholder,
|
19 | RichText,
|
20 | } from '@wordpress/block-editor';
|
21 | import { mediaUpload } from '@wordpress/editor';
|
22 | import { Component, Fragment } from '@wordpress/element';
|
23 | import { __ } from '@wordpress/i18n';
|
24 |
|
25 |
|
26 |
|
27 |
|
28 | import icon from './icon';
|
29 |
|
30 |
|
31 |
|
32 |
|
33 | import { createUpgradedEmbedBlock } from '../embed/util';
|
34 |
|
35 | const ALLOWED_MEDIA_TYPES = [ 'audio' ];
|
36 |
|
37 | class AudioEdit extends Component {
|
38 | constructor() {
|
39 | super( ...arguments );
|
40 |
|
41 |
|
42 | this.state = {
|
43 | editing: ! this.props.attributes.src,
|
44 | };
|
45 |
|
46 | this.toggleAttribute = this.toggleAttribute.bind( this );
|
47 | this.onSelectURL = this.onSelectURL.bind( this );
|
48 | }
|
49 |
|
50 | componentDidMount() {
|
51 | const { attributes, noticeOperations, setAttributes } = this.props;
|
52 | const { id, src = '' } = attributes;
|
53 |
|
54 | if ( ! id && isBlobURL( src ) ) {
|
55 | const file = getBlobByURL( src );
|
56 |
|
57 | if ( file ) {
|
58 | mediaUpload( {
|
59 | filesList: [ file ],
|
60 | onFileChange: ( [ { id: mediaId, url } ] ) => {
|
61 | setAttributes( { id: mediaId, src: url } );
|
62 | },
|
63 | onError: ( e ) => {
|
64 | setAttributes( { src: undefined, id: undefined } );
|
65 | this.setState( { editing: true } );
|
66 | noticeOperations.createErrorNotice( e );
|
67 | },
|
68 | allowedTypes: ALLOWED_MEDIA_TYPES,
|
69 | } );
|
70 | }
|
71 | }
|
72 | }
|
73 |
|
74 | toggleAttribute( attribute ) {
|
75 | return ( newValue ) => {
|
76 | this.props.setAttributes( { [ attribute ]: newValue } );
|
77 | };
|
78 | }
|
79 |
|
80 | onSelectURL( newSrc ) {
|
81 | const { attributes, setAttributes } = this.props;
|
82 | const { src } = attributes;
|
83 |
|
84 |
|
85 |
|
86 | if ( newSrc !== src ) {
|
87 |
|
88 | const embedBlock = createUpgradedEmbedBlock(
|
89 | { attributes: { url: newSrc } }
|
90 | );
|
91 | if ( undefined !== embedBlock ) {
|
92 | this.props.onReplace( embedBlock );
|
93 | return;
|
94 | }
|
95 | setAttributes( { src: newSrc, id: undefined } );
|
96 | }
|
97 |
|
98 | this.setState( { editing: false } );
|
99 | }
|
100 |
|
101 | render() {
|
102 | const { autoplay, caption, loop, preload, src } = this.props.attributes;
|
103 | const { setAttributes, isSelected, className, noticeOperations, noticeUI } = this.props;
|
104 | const { editing } = this.state;
|
105 | const switchToEditing = () => {
|
106 | this.setState( { editing: true } );
|
107 | };
|
108 | const onSelectAudio = ( media ) => {
|
109 | if ( ! media || ! media.url ) {
|
110 |
|
111 |
|
112 | setAttributes( { src: undefined, id: undefined } );
|
113 | switchToEditing();
|
114 | return;
|
115 | }
|
116 |
|
117 |
|
118 | setAttributes( { src: media.url, id: media.id } );
|
119 | this.setState( { src: media.url, editing: false } );
|
120 | };
|
121 | if ( editing ) {
|
122 | return (
|
123 | <MediaPlaceholder
|
124 | icon={ <BlockIcon icon={ icon } /> }
|
125 | className={ className }
|
126 | onSelect={ onSelectAudio }
|
127 | onSelectURL={ this.onSelectURL }
|
128 | accept="audio/*"
|
129 | allowedTypes={ ALLOWED_MEDIA_TYPES }
|
130 | value={ this.props.attributes }
|
131 | notices={ noticeUI }
|
132 | onError={ noticeOperations.createErrorNotice }
|
133 | />
|
134 | );
|
135 | }
|
136 |
|
137 |
|
138 | return (
|
139 | <Fragment>
|
140 | <BlockControls>
|
141 | <Toolbar>
|
142 | <IconButton
|
143 | className="components-icon-button components-toolbar__control"
|
144 | label={ __( 'Edit audio' ) }
|
145 | onClick={ switchToEditing }
|
146 | icon="edit"
|
147 | />
|
148 | </Toolbar>
|
149 | </BlockControls>
|
150 | <InspectorControls>
|
151 | <PanelBody title={ __( 'Audio Settings' ) }>
|
152 | <ToggleControl
|
153 | label={ __( 'Autoplay' ) }
|
154 | onChange={ this.toggleAttribute( 'autoplay' ) }
|
155 | checked={ autoplay }
|
156 | />
|
157 | <ToggleControl
|
158 | label={ __( 'Loop' ) }
|
159 | onChange={ this.toggleAttribute( 'loop' ) }
|
160 | checked={ loop }
|
161 | />
|
162 | <SelectControl
|
163 | label={ __( 'Preload' ) }
|
164 | value={ undefined !== preload ? preload : 'none' }
|
165 |
|
166 | onChange={ ( value ) => setAttributes( { preload: ( 'none' !== value ) ? value : undefined } ) }
|
167 | options={ [
|
168 | { value: 'auto', label: __( 'Auto' ) },
|
169 | { value: 'metadata', label: __( 'Metadata' ) },
|
170 | { value: 'none', label: __( 'None' ) },
|
171 | ] }
|
172 | />
|
173 | </PanelBody>
|
174 | </InspectorControls>
|
175 | <figure className={ className }>
|
176 | { |
177 |
|
178 |
|
179 | }
|
180 | <Disabled>
|
181 | <audio controls="controls" src={ src } />
|
182 | </Disabled>
|
183 | { ( ! RichText.isEmpty( caption ) || isSelected ) && (
|
184 | <RichText
|
185 | tagName="figcaption"
|
186 | placeholder={ __( 'Write caption…' ) }
|
187 | value={ caption }
|
188 | onChange={ ( value ) => setAttributes( { caption: value } ) }
|
189 | inlineToolbar
|
190 | />
|
191 | ) }
|
192 | </figure>
|
193 | </Fragment>
|
194 | );
|
195 |
|
196 | }
|
197 | }
|
198 |
|
199 | export default withNotices( AudioEdit );
|