index.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. const { h } = require('preact')
  2. function onPauseResumeCancelRetry (props) {
  3. console.log(props.uppy)
  4. if (props.isUploaded) return
  5. if (props.error && !props.hideRetryButton) {
  6. props.uppy.retryUpload(props.file.id)
  7. return
  8. }
  9. if (props.resumableUploads && !props.hidePauseResumeButton) {
  10. props.uppy.pauseResume(props.file.id)
  11. } else if (props.individualCancellation && !props.hideCancelButton) {
  12. props.uppy.removeFile(props.file.id)
  13. }
  14. }
  15. function progressIndicatorTitle (props) {
  16. if (props.isUploaded) {
  17. return props.i18n('uploadComplete')
  18. }
  19. if (props.error) {
  20. return props.i18n('retryUpload')
  21. }
  22. if (props.resumableUploads) {
  23. if (props.file.isPaused) {
  24. return props.i18n('resumeUpload')
  25. }
  26. return props.i18n('pauseUpload')
  27. } if (props.individualCancellation) {
  28. return props.i18n('cancelUpload')
  29. }
  30. return ''
  31. }
  32. function ProgressIndicatorButton (props) {
  33. return (
  34. <div className="uppy-Dashboard-Item-progress">
  35. <button
  36. className="uppy-u-reset uppy-Dashboard-Item-progressIndicator"
  37. type="button"
  38. aria-label={progressIndicatorTitle(props)}
  39. title={progressIndicatorTitle(props)}
  40. onClick={() => onPauseResumeCancelRetry(props)}
  41. >
  42. {props.children}
  43. </button>
  44. </div>
  45. )
  46. }
  47. function ProgressCircleContainer ({ children }) {
  48. return (
  49. <svg
  50. aria-hidden="true"
  51. focusable="false"
  52. width="70"
  53. height="70"
  54. viewBox="0 0 36 36"
  55. className="uppy-c-icon uppy-Dashboard-Item-progressIcon--circle"
  56. >
  57. {children}
  58. </svg>
  59. )
  60. }
  61. function ProgressCircle ({ progress }) {
  62. // circle length equals 2 * PI * R
  63. const circleLength = 2 * Math.PI * 15
  64. return (
  65. <g>
  66. <circle
  67. className="uppy-Dashboard-Item-progressIcon--bg"
  68. r="15"
  69. cx="18"
  70. cy="18"
  71. stroke-width="2"
  72. fill="none"
  73. />
  74. <circle
  75. className="uppy-Dashboard-Item-progressIcon--progress"
  76. r="15"
  77. cx="18"
  78. cy="18"
  79. transform="rotate(-90, 18, 18)"
  80. fill="none"
  81. stroke-width="2"
  82. stroke-dasharray={circleLength}
  83. stroke-dashoffset={circleLength - ((circleLength / 100) * progress)}
  84. />
  85. </g>
  86. )
  87. }
  88. module.exports = function FileProgress (props) {
  89. // Nothing if upload has not started
  90. if (!props.file.progress.uploadStarted) {
  91. return null
  92. }
  93. // Green checkmark when complete
  94. if (props.isUploaded) {
  95. return (
  96. <div className="uppy-Dashboard-Item-progress">
  97. <div className="uppy-Dashboard-Item-progressIndicator">
  98. <ProgressCircleContainer>
  99. <circle r="15" cx="18" cy="18" fill="#1bb240" />
  100. <polygon className="uppy-Dashboard-Item-progressIcon--check" transform="translate(2, 3)" points="14 22.5 7 15.2457065 8.99985857 13.1732815 14 18.3547104 22.9729883 9 25 11.1005634" />
  101. </ProgressCircleContainer>
  102. </div>
  103. </div>
  104. )
  105. }
  106. if (props.recoveredState) {
  107. return
  108. }
  109. // Retry button for error
  110. if (props.error && !props.hideRetryButton) {
  111. return (
  112. <ProgressIndicatorButton {...props}>
  113. <svg aria-hidden="true" focusable="false" className="uppy-c-icon uppy-Dashboard-Item-progressIcon--retry" width="28" height="31" viewBox="0 0 16 19">
  114. <path d="M16 11a8 8 0 1 1-8-8v2a6 6 0 1 0 6 6h2z" />
  115. <path d="M7.9 3H10v2H7.9z" />
  116. <path d="M8.536.5l3.535 3.536-1.414 1.414L7.12 1.914z" />
  117. <path d="M10.657 2.621l1.414 1.415L8.536 7.57 7.12 6.157z" />
  118. </svg>
  119. </ProgressIndicatorButton>
  120. )
  121. }
  122. // Pause/resume button for resumable uploads
  123. if (props.resumableUploads && !props.hidePauseResumeButton) {
  124. return (
  125. <ProgressIndicatorButton {...props}>
  126. <ProgressCircleContainer>
  127. <ProgressCircle progress={props.file.progress.percentage} />
  128. {
  129. props.file.isPaused
  130. ? <polygon className="uppy-Dashboard-Item-progressIcon--play" transform="translate(3, 3)" points="12 20 12 10 20 15" />
  131. : (
  132. <g className="uppy-Dashboard-Item-progressIcon--pause" transform="translate(14.5, 13)">
  133. <rect x="0" y="0" width="2" height="10" rx="0" />
  134. <rect x="5" y="0" width="2" height="10" rx="0" />
  135. </g>
  136. )
  137. }
  138. </ProgressCircleContainer>
  139. </ProgressIndicatorButton>
  140. )
  141. }
  142. // Cancel button for non-resumable uploads if individualCancellation is supported (not bundled)
  143. if (!props.resumableUploads && props.individualCancellation && !props.hideCancelButton) {
  144. return (
  145. <ProgressIndicatorButton {...props}>
  146. <ProgressCircleContainer>
  147. <ProgressCircle progress={props.file.progress.percentage} />
  148. <polygon className="cancel" transform="translate(2, 2)" points="19.8856516 11.0625 16 14.9481516 12.1019737 11.0625 11.0625 12.1143484 14.9481516 16 11.0625 19.8980263 12.1019737 20.9375 16 17.0518484 19.8856516 20.9375 20.9375 19.8980263 17.0518484 16 20.9375 12" />
  149. </ProgressCircleContainer>
  150. </ProgressIndicatorButton>
  151. )
  152. }
  153. // Just progress when buttons are disabled
  154. return (
  155. <div className="uppy-Dashboard-Item-progress">
  156. <div className="uppy-Dashboard-Item-progressIndicator">
  157. <ProgressCircleContainer>
  158. <ProgressCircle progress={props.file.progress.percentage} />
  159. </ProgressCircleContainer>
  160. </div>
  161. </div>
  162. )
  163. }