Making WordPress.org


Ignore:
Timestamp:
04/29/2021 05:26:25 AM (4 years ago)
Author:
dd32
Message:

WordPress.TV: Add a progress bar to the upload process.

Fixes #1117.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.tv/public_html/wp-content/themes/wptv2/anon-upload-template.php

    r10468 r10932  
    164164            display: inline;
    165165            width: auto;
     166        }
     167
     168        #upload-progress .status,
     169        #upload-progress .percent {
     170            font-family: monospace;
     171        }
     172        #upload-progress a.abort:hover {
     173            color: red;
    166174        }
    167175    </style>
     
    276284                <?php } ?>
    277285
    278                 <form method="post" action="<?php echo admin_url('admin-post.php'); ?>" id="video-upload-form" enctype="multipart/form-data">
     286                <form method="post" action="<?php echo admin_url('admin-post.php'); ?>" data-xhr-action="<?php echo admin_url('admin-post.php?xhr=1'); ?>" id="video-upload-form" enctype="multipart/form-data">
    279287                    <?php wp_nonce_field('wptv-upload-video', 'wptvvideon'); ?>
    280288                    <input type="hidden" name="action" value="wptv_video_upload" />
     
    384392                        <input type="submit" id="wptv_video_upload" style="display:none;" value="<?php esc_attr_e( 'Submit' ); ?>" />
    385393                    </p>
     394                    <p id="upload-progress" style="display:none;">
     395                        <progress value="0" max="100" style="width:90%;"></progress><span class="percent"></span><br>
     396                        <span class="status"></span> <a href="#" class="abort">Cancel</a>
     397                    </p>
    386398                </form>
    387399            </div>
     
    435447
    436448                // .. and the Year
    437                 title += $( '#wptv_date' ).value.substring( 0, 4 );
     449                title += $( '#wptv_date' ).val().substring( 0, 4 );
    438450
    439451                // If a location or year has been selected, build the Event Name.
     
    487499                if ( ! file.val() || !/\.(avi|mov|qt|mpeg|mpg|mpe|mp4|m4v|asf|asx|wax|wmv|wmx|ogv|3gp|3g2)$/.test( file.val() ) ) {
    488500                    invalid(file, e);
     501                    scroll = true;
    489502                }
    490503
     
    495508                }
    496509
    497                 if ( scroll && uploaded_by.length ) {
    498                     uploaded_by.get( 0 ).scrollIntoView();
     510                if ( scroll ) {
     511                    jQuery( '.invalid' ).get(0).scrollIntoView();
     512                    return;
     513                }
     514
     515                // Start the upload!
     516                if (
     517                    'undefined' != typeof XMLHttpRequest &&
     518                    'undefined' != typeof FormData
     519                ) {
     520                    e.preventDefault();
     521                    processXHRUpload();
    499522                }
    500523            } );
    501524        } );
     525
     526        function processXHRUpload() {
     527            var $form        = jQuery( '#video-upload-form' ),
     528                $file        = $form.find('input[type="file"]'),
     529                $submit      = $form.find( 'p.last' ),
     530                $progressBar = $form.find( '#upload-progress' ),
     531                $progress    = $progressBar.find( 'progress' ),
     532                $status      = $progressBar.find( '.status' ),
     533                $percent     = $progressBar.find( '.percent' ),
     534                $abort       = $progressBar.find( '.abort' ),
     535                formdata     = new FormData( $form.get(0) ),
     536                xhr          = new XMLHttpRequest(),
     537                startTime    = (new Date()).getTime(),
     538                round_to, disable_form;
     539
     540            round_to = function(x, precision ) {
     541                return x.toLocaleString(
     542                    undefined,
     543                    {
     544                        minimumFractionDigits: precision,
     545                        maximumFractionDigits: precision
     546                    }
     547                );
     548            };
     549
     550            disable_form = function( disable ) {
     551                $form.find( 'input,select,option,textarea' ).prop( 'disabled', !! disable );
     552            };
     553
     554            disable_form( true );
     555            $submit.hide();
     556            $progress.val( 0 );
     557            $percent.text( '0%' );
     558            $progressBar.show();
     559            $abort.show();
     560
     561            $status.text( 'Preparing upload..' );
     562
     563            xhr.upload.addEventListener( 'progress', function(e) {
     564                var percent     = Math.round( e.loaded / e.total * 100 ),
     565                    size        = round_to( e.total / 1024 / 1024, 1 ),
     566                    uploaded    = round_to( e.loaded / 1024 / 1024, 1 ),
     567                    elapsed     = ( (new Date()).getTime() - startTime ) / 1000,
     568                    // This isn't a perfect speed measurement, but is close enough for our needs.
     569                    speed_kbps  = e.loaded / elapsed / 1024,
     570                    eta_seconds = Math.round( ( e.total - e.loaded ) / 1024 / speed_kbps ),
     571                    eta_minutes = Math.floor( eta_seconds / 60 ),
     572                    eta         = '',
     573                    speed;
     574
     575                // Give some time for the upload speed to settle.
     576                if ( elapsed > 10 || percent > 5 ) {
     577                    if ( eta_minutes ) {
     578                        eta += eta_minutes + ( eta_minutes > 1 ? ' mins ' : ' min ' );
     579                    }
     580                    if ( eta_seconds % 60 ) {
     581                        eta += ( eta_seconds - eta_minutes * 60 ) + 's';
     582                    }
     583                } else {
     584                    eta = 'Calculating..';
     585                }
     586
     587                if ( speed_kbps > 1024 ) {
     588                    speed = round_to( speed_kbps / 1024, 2 ) + 'mb/s';
     589                } else {
     590                    speed = round_to( Math.round( speed_kbps ), 0 ) + 'kb/s';
     591                }
     592
     593                $progress.val( percent );
     594
     595                $percent.text( `${percent}%` );
     596
     597                $status.text(
     598                    `Uploaded ${uploaded}MB of ${size}MB. ${speed} Remaining: ${eta}`
     599                );
     600                if ( percent >= 100 ) {
     601                    $status.text( 'Processing upload.. please wait..' );
     602                    $abort.hide();
     603                }
     604
     605            }, false);
     606
     607            xhr.addEventListener( 'load', function( e ) {
     608                $status.text( 'Done.. please wait..' );
     609                $abort.hide();
     610                // Redirect. Upload done.
     611                document.location = e.target.responseText;
     612            }, false);
     613
     614            xhr.addEventListener( 'error', function( e ) {
     615                $status.text( 'Upload failed. Network or Browser issue encountered.' );
     616                console.log( e );
     617
     618                disable_form( false );
     619                $submit.show();
     620                $abort.hide();
     621            }, false );
     622
     623            xhr.addEventListener( 'abort', function( e ) {
     624                $status.text( 'Aborted.' );
     625
     626                disable_form( false );
     627                $submit.show();
     628                $progressBar.hide();
     629            }, false );
     630
     631            // Note: form.action will return the `<input name="action">` element, which is why a data attribute is ued.
     632            xhr.withCredentials = true;
     633            xhr.open( $form.prop( 'method' ), $form.data( 'xhr-action' ) );
     634            xhr.send( formdata );
     635
     636            $abort.click( function( e ) {
     637                xhr.abort();
     638                e.preventDefault();
     639            } );
     640        }
    502641    </script>
    503642
Note: See TracChangeset for help on using the changeset viewer.