Index: trunk/extensions/UploadWizard/UploadWizardHooks.php |
— | — | @@ -128,6 +128,9 @@ |
129 | 129 | 'mwe-upwiz-api-error-duplicate-popup-title', |
130 | 130 | 'mwe-upwiz-api-error-timeout', |
131 | 131 | 'mwe-upwiz-api-error-noimageinfo', |
| 132 | + |
| 133 | + 'mwe-upwiz-api-error-fileexists-shared-forbidden', |
| 134 | + |
132 | 135 | 'mwe-upwiz-api-warning-exists', |
133 | 136 | 'mwe-upwiz-tutorial-error-localized-file-missing', |
134 | 137 | 'mwe-upwiz-tutorial-error-file-missing', |
Index: trunk/extensions/UploadWizard/UploadWizard.i18n.php |
— | — | @@ -61,6 +61,9 @@ |
62 | 62 | 'mwe-upwiz-api-error-duplicate-popup-title' => 'Duplicate {{PLURAL:$1|file|files}}', |
63 | 63 | 'mwe-upwiz-api-error-timeout' => 'The server did not respond within the expected time.', |
64 | 64 | 'mwe-upwiz-api-error-noimageinfo' => 'The upload succeeded, but the server did not give us any information about the file.', |
| 65 | + 'mwe-upwiz-api-error-fileexists-shared-forbidden' => 'This filename is reserved by a file on a remote shared repository. Choose another name.', |
| 66 | + |
| 67 | + |
65 | 68 | 'mwe-upwiz-api-warning-exists' => 'There is [$1 another file] already on the wiki with the same filename', |
66 | 69 | 'mwe-upwiz-tutorial-error-localized-file-missing' => 'Sorry, we could not find a tutorial in your language. The English one is shown instead.', |
67 | 70 | 'mwe-upwiz-tutorial-error-file-missing' => 'Sorry, we could not find any files for the tutorial that is supposed to go here. Please contact the system administrators.', |
Index: trunk/extensions/UploadWizard/resources/mw.Api.js |
— | — | @@ -189,7 +189,8 @@ |
190 | 190 | 'internal-error', |
191 | 191 | 'overwrite', |
192 | 192 | 'badtoken', |
193 | | - 'fetchfileerror' |
| 193 | + 'fetchfileerror', |
| 194 | + 'fileexists-shared-forbidden' |
194 | 195 | ]; |
195 | 196 | |
196 | 197 | /** |
Index: trunk/extensions/UploadWizard/resources/uploadWizard.css |
— | — | @@ -279,7 +279,7 @@ |
280 | 280 | width: 40px; |
281 | 281 | } |
282 | 282 | |
283 | | -.mwe-upwiz-mask, .mwe-upwiz-status { |
| 283 | +.mwe-upwiz-mask { |
284 | 284 | position: absolute; |
285 | 285 | top: 0px; |
286 | 286 | left: 0px; |
Index: trunk/extensions/UploadWizard/resources/mw.UploadWizard.js |
— | — | @@ -1136,6 +1136,7 @@ |
1137 | 1137 | /** |
1138 | 1138 | * Submit all edited details and other metadata |
1139 | 1139 | * Works just like startUploads -- parallel simultaneous submits with progress bar. |
| 1140 | + * @param {Function} endCallback - called when all uploads complete. In our case is probably a move to the next step |
1140 | 1141 | */ |
1141 | 1142 | detailsSubmit: function( endCallback ) { |
1142 | 1143 | var _this = this; |
— | — | @@ -1154,24 +1155,9 @@ |
1155 | 1156 | [ 'submitting-details' ], |
1156 | 1157 | [ 'complete' ], |
1157 | 1158 | function( upload ) { |
1158 | | - // activate spinner |
1159 | | - upload.details.div.data( 'status' ).addClass( 'mwe-upwiz-status-progress' ); |
1160 | | - upload.details.submit( function( result ) { |
1161 | | - if ( result && result.upload && result.upload.imageinfo ) { |
1162 | | - upload.extractImageInfo( result.upload.imageinfo ); |
1163 | | - // change spinner to checkmark |
1164 | | - upload.details.div.data( 'status' ).removeClass( 'mwe-upwiz-status-progress' ); |
1165 | | - upload.details.div.data( 'status' ).addClass( 'mwe-upwiz-status-uploaded' ); |
1166 | | - } else { |
1167 | | - // XXX alert the user, maybe don't proceed to step 4. |
1168 | | - mw.log( "error -- final API call did not return image info" ); |
1169 | | - // change spinner to error icon |
1170 | | - upload.details.div.data( 'status' ).removeClass( 'mwe-upwiz-status-progress' ); |
1171 | | - upload.details.div.data( 'status' ).addClass( 'mwe-upwiz-status-error' ); |
1172 | | - } |
1173 | | - } ); |
| 1159 | + upload.details.submit(); |
1174 | 1160 | }, |
1175 | | - endCallback |
| 1161 | + endCallback /* called when all uploads are "complete" */ |
1176 | 1162 | ); |
1177 | 1163 | }, |
1178 | 1164 | |
— | — | @@ -1490,6 +1476,7 @@ |
1491 | 1477 | return this; |
1492 | 1478 | }; |
1493 | 1479 | |
| 1480 | + // XXX this is highly specific to the "details" page now, not really jQuery function |
1494 | 1481 | jQuery.fn.mask = function( options ) { |
1495 | 1482 | |
1496 | 1483 | // intercept clicks... |
— | — | @@ -1512,23 +1499,40 @@ |
1513 | 1500 | 'height' : el.offsetHeight + 'px', |
1514 | 1501 | 'z-index' : 90 |
1515 | 1502 | } ); |
1516 | | - |
1517 | | - var status = $j( '<div class="mwe-upwiz-status"></div>' ) |
1518 | | - .css( { |
1519 | | - 'width' : el.offsetWidth + 'px', |
1520 | | - 'height' : el.offsetHeight + 'px', |
1521 | | - 'z-index' : 91 |
1522 | | - } ) |
1523 | | - .click( function( e ) { e.stopPropagation(); } ); |
| 1503 | + |
| 1504 | + var $statusDiv = $j( '<div></div>' ).css( { |
| 1505 | + 'width' : el.offsetWidth + 'px', |
| 1506 | + 'height' : el.offsetHeight + 'px', |
| 1507 | + 'z-index' : 91, |
| 1508 | + 'text-align' : 'center', |
| 1509 | + 'position' : 'absolute', |
| 1510 | + 'top' : '0px', |
| 1511 | + 'left' : '0px' |
| 1512 | + } ); |
1524 | 1513 | |
| 1514 | + var $indicatorDiv = $j( '<div class="mwe-upwiz-status"></div>' ) |
| 1515 | + .css( { |
| 1516 | + 'width' : 32, |
| 1517 | + 'height' : 32, |
| 1518 | + 'z-index' : 91, |
| 1519 | + 'margin' : '0 auto 0 auto' |
| 1520 | + } ); |
| 1521 | + var $statusLineDiv = $j( '<div></div>' ) |
| 1522 | + .css( { |
| 1523 | + 'z-index' : 91 |
| 1524 | + } ); |
| 1525 | + var $statusIndicatorLineDiv = $j( '<div></div>' ) |
| 1526 | + .css( { 'margin-top': '6em' } ) |
| 1527 | + .append( $indicatorDiv, $statusLineDiv ); |
| 1528 | + $statusDiv.append( $statusIndicatorLineDiv ); |
| 1529 | + |
1525 | 1530 | $j( el ).css( { 'position' : 'relative' } ) |
1526 | 1531 | .append( mask.fadeTo( 'fast', 0.6 ) ) |
1527 | | - .append( status ) |
1528 | | - .data( 'status', status ); |
1529 | | - |
| 1532 | + .append( $statusDiv ) |
| 1533 | + .data( 'indicator', $indicatorDiv ) |
| 1534 | + .data( 'statusLine', $statusLineDiv ); |
1530 | 1535 | |
1531 | 1536 | } |
1532 | | - // XXX bind to a custom event in case the div size changes |
1533 | 1537 | } ); |
1534 | 1538 | |
1535 | 1539 | return this; |
Index: trunk/extensions/UploadWizard/resources/mw.UploadWizardDetails.js |
— | — | @@ -54,7 +54,7 @@ |
55 | 55 | api: _this.upload.api, |
56 | 56 | spinner: function(bool) { _this.toggleDestinationBusy(bool); }, |
57 | 57 | preprocess: function( name ) { |
58 | | - if ( name != '' ) { |
| 58 | + if ( name !== '' ) { |
59 | 59 | // turn the contents of the input into a MediaWiki title ("File:foo_bar.jpg") to look up |
60 | 60 | return _this.upload.title.setNameText( name ).toString(); |
61 | 61 | } else { |
— | — | @@ -666,10 +666,14 @@ |
667 | 667 | * XXX This should be split up -- one part should get wikitext from the interface here, and the ajax call |
668 | 668 | * should be be part of upload |
669 | 669 | */ |
670 | | - submit: function( endCallback ) { |
| 670 | + submit: function() { |
671 | 671 | var _this = this; |
672 | 672 | |
| 673 | + _this.upload.state = 'submitting-details'; |
| 674 | + _this.showIndicator( 'progress' ); |
| 675 | + |
673 | 676 | // XXX check state of details for okayness ( license selected, at least one desc, sane filename ) |
| 677 | + // validation does MOST of this already |
674 | 678 | var wikiText = _this.getWikiText(); |
675 | 679 | |
676 | 680 | var params = { |
— | — | @@ -680,27 +684,46 @@ |
681 | 685 | summary: "User created page with " + mw.UploadWizard.userAgent |
682 | 686 | }; |
683 | 687 | |
684 | | - var finalCallback = function( result ) { |
685 | | - endCallback( result ); |
686 | | - _this.completeDetailsSubmission(); |
687 | | - }; |
| 688 | + var err = function( code, info ) { |
| 689 | + _this.showError( code, info ); |
| 690 | + }; |
688 | 691 | |
689 | | - var callback = function( result ) { |
690 | | - finalCallback( result ); |
| 692 | + var ok = function( result ) { |
| 693 | + if ( result && result.upload && result.upload.imageinfo ) { |
| 694 | + _this.upload.extractImageInfo( result.upload.imageinfo ); |
| 695 | + _this.upload.detailsProgress = 1.0; |
| 696 | + _this.upload.state = 'complete'; |
| 697 | + _this.showIndicator( 'uploaded' ); |
| 698 | + } else { |
| 699 | + _this.showError( 'details-info-missing', result ); |
| 700 | + } |
691 | 701 | }; |
692 | 702 | |
693 | | - _this.upload.state = 'submitting-details'; |
694 | | - // XXX this can still fail with bad filename, or other 'warnings' -- capture these |
695 | | - _this.upload.api.postWithEditToken( params, callback ); |
| 703 | + _this.upload.api.postWithEditToken( params, ok, err ); |
696 | 704 | }, |
697 | 705 | |
698 | | - completeDetailsSubmission: function() { |
699 | | - var _this = this; |
700 | | - _this.upload.state = 'complete'; |
701 | | - // de-spinnerize |
702 | | - _this.upload.detailsProgress = 1.0; |
| 706 | + showError: function( code, result ) { |
| 707 | + this.showIndicator( 'error' ); |
| 708 | + // types of errors we know about... |
| 709 | + // recoverable by fixing title |
| 710 | + // TODO unmask and fix the error on the title |
| 711 | + |
| 712 | + // recoverable by trying again, or removing |
| 713 | + // TODO removal / retry interface |
| 714 | + this.setStatus( result.error.info ); |
703 | 715 | }, |
704 | 716 | |
| 717 | + setStatus: function( s ) { |
| 718 | + this.div.data( 'statusLine' ).html( s ).show(); |
| 719 | + }, |
| 720 | + |
| 721 | + showIndicator: function( statusStr ) { |
| 722 | + this.div.data( 'indicator' ) |
| 723 | + .show() |
| 724 | + .removeClass( 'mwe-upwiz-status-progress mwe-upwiz-status-error mwe-upwiz-status-uploaded' ) |
| 725 | + .addClass( 'mwe-upwiz-status-' + statusStr ); |
| 726 | + }, |
| 727 | + |
705 | 728 | dateInputCount: 0 |
706 | 729 | |
707 | 730 | |