Fossil SCM
Add an error message to each attached file which exceeds the attachment-size-limit setting. This tentatively won't prevent it from being submitted because the limit may have changed since the page was loaded (and the limit recorded).
Commit
ee430462c41f07b500ecafd5ca6e874cdb68729d9d8247698a6b43171bd12268
Parent
13d99044c886640…
2 files changed
+6
+31
-2
+6
| --- src/default.css | ||
| +++ src/default.css | ||
| @@ -2023,10 +2023,15 @@ | ||
| 2023 | 2023 | gap: 0.5em; |
| 2024 | 2024 | padding: 0.75em; |
| 2025 | 2025 | border: 1px dashed #ccc; |
| 2026 | 2026 | border-radius: 0.25em; |
| 2027 | 2027 | background-color: #fafafa; |
| 2028 | +} | |
| 2029 | +.attach-widget .error { | |
| 2030 | + padding: 0.5em; | |
| 2031 | + background-color: #d32f2f; | |
| 2032 | + color: #fff; | |
| 2028 | 2033 | } |
| 2029 | 2034 | body.fossil-dark-style .attach-widget .attach-row { |
| 2030 | 2035 | background-color: initial; |
| 2031 | 2036 | } |
| 2032 | 2037 | .attach-widget .attach-dropzone { |
| @@ -2065,10 +2070,11 @@ | ||
| 2065 | 2070 | border-color: #03a9f4; |
| 2066 | 2071 | } |
| 2067 | 2072 | .attach-widget .thumbnail { |
| 2068 | 2073 | max-width: 10em; |
| 2069 | 2074 | max-height: 10em; |
| 2075 | + margin: 0 1em; | |
| 2070 | 2076 | } |
| 2071 | 2077 | .attach-widget .attach-row-info{ |
| 2072 | 2078 | font-family: monospace; |
| 2073 | 2079 | flex-grow: 1; |
| 2074 | 2080 | display: flex; |
| 2075 | 2081 |
| --- src/default.css | |
| +++ src/default.css | |
| @@ -2023,10 +2023,15 @@ | |
| 2023 | gap: 0.5em; |
| 2024 | padding: 0.75em; |
| 2025 | border: 1px dashed #ccc; |
| 2026 | border-radius: 0.25em; |
| 2027 | background-color: #fafafa; |
| 2028 | } |
| 2029 | body.fossil-dark-style .attach-widget .attach-row { |
| 2030 | background-color: initial; |
| 2031 | } |
| 2032 | .attach-widget .attach-dropzone { |
| @@ -2065,10 +2070,11 @@ | |
| 2065 | border-color: #03a9f4; |
| 2066 | } |
| 2067 | .attach-widget .thumbnail { |
| 2068 | max-width: 10em; |
| 2069 | max-height: 10em; |
| 2070 | } |
| 2071 | .attach-widget .attach-row-info{ |
| 2072 | font-family: monospace; |
| 2073 | flex-grow: 1; |
| 2074 | display: flex; |
| 2075 |
| --- src/default.css | |
| +++ src/default.css | |
| @@ -2023,10 +2023,15 @@ | |
| 2023 | gap: 0.5em; |
| 2024 | padding: 0.75em; |
| 2025 | border: 1px dashed #ccc; |
| 2026 | border-radius: 0.25em; |
| 2027 | background-color: #fafafa; |
| 2028 | } |
| 2029 | .attach-widget .error { |
| 2030 | padding: 0.5em; |
| 2031 | background-color: #d32f2f; |
| 2032 | color: #fff; |
| 2033 | } |
| 2034 | body.fossil-dark-style .attach-widget .attach-row { |
| 2035 | background-color: initial; |
| 2036 | } |
| 2037 | .attach-widget .attach-dropzone { |
| @@ -2065,10 +2070,11 @@ | |
| 2070 | border-color: #03a9f4; |
| 2071 | } |
| 2072 | .attach-widget .thumbnail { |
| 2073 | max-width: 10em; |
| 2074 | max-height: 10em; |
| 2075 | margin: 0 1em; |
| 2076 | } |
| 2077 | .attach-widget .attach-row-info{ |
| 2078 | font-family: monospace; |
| 2079 | flex-grow: 1; |
| 2080 | display: flex; |
| 2081 |
+31
-2
| --- src/fossil.attach.js | ||
| +++ src/fossil.attach.js | ||
| @@ -164,10 +164,27 @@ | ||
| 164 | 164 | b.classList.remove('hidden'); |
| 165 | 165 | //b.removeAttribute('disabled'); |
| 166 | 166 | this.#e.list.append(this.#e.controls/*move to the end*/); |
| 167 | 167 | } |
| 168 | 168 | } |
| 169 | + | |
| 170 | + #rowError(rowObj, ...msg){ | |
| 171 | + let e = rowObj.e.err; | |
| 172 | + if( e ){ | |
| 173 | + D.clearElement(e); | |
| 174 | + }else{ | |
| 175 | + if( !msg.length ) return; | |
| 176 | + e = rowObj.e.err = D.addClass(D.span(), 'error'); | |
| 177 | + rowObj.e.info.append(e); | |
| 178 | + } | |
| 179 | + if( msg.length ){ | |
| 180 | + e.append(...msg); | |
| 181 | + e.classList.remove('hidden'); | |
| 182 | + }else{ | |
| 183 | + e.classList.add('hidden'); | |
| 184 | + } | |
| 185 | + } | |
| 169 | 186 | |
| 170 | 187 | #addRow(){ |
| 171 | 188 | const id = ++idCounter; |
| 172 | 189 | const rowObj = F.nu({ |
| 173 | 190 | id, file: null, mimeType: '' |
| @@ -335,10 +352,21 @@ | ||
| 335 | 352 | img.classList.add('thumbnail'); |
| 336 | 353 | rowObj.e.dropzone.insertBefore(img, rowObj.e.remove); |
| 337 | 354 | const reader = new FileReader(); |
| 338 | 355 | reader.onload = (e)=>img.setAttribute('src', e.target.result); |
| 339 | 356 | reader.readAsDataURL(file); |
| 357 | + } | |
| 358 | + if( file.size>F.config.attachmentSizeLimit ){ | |
| 359 | + /* Problem: tapping this link propagates its click event through | |
| 360 | + to eDropzone. Thus... */ | |
| 361 | + const eLink = D.a(F.repoUrl('help/attachment-size-limit'),'limit'); | |
| 362 | + eLink.addEventListener('click', ev=>ev.stopPropagation()); | |
| 363 | + this.#rowError(rowObj, "Too large: ", eLink, | |
| 364 | + " is ",F.config.attachmentSizeLimit," bytes"); | |
| 365 | + rowObj.ok = false; | |
| 366 | + }else{ | |
| 367 | + rowObj.ok = true; | |
| 340 | 368 | } |
| 341 | 369 | this.#events.dispatchEvent( |
| 342 | 370 | new CustomEvent('entry-populated',{ |
| 343 | 371 | detail: F.nu({ |
| 344 | 372 | type: 'entry-populated', |
| @@ -354,17 +382,17 @@ | ||
| 354 | 382 | attachments. |
| 355 | 383 | */ |
| 356 | 384 | collectState(){ |
| 357 | 385 | const rv = []; |
| 358 | 386 | for(let r of this.#rows){ |
| 359 | - if( !r.eDropzone?.classList?.contains?.('populated') ){ | |
| 387 | + if( !r.e.dropzone?.classList?.contains?.('populated') ){ | |
| 360 | 388 | continue; |
| 361 | 389 | } |
| 362 | 390 | rv.push(F.nu({ |
| 363 | 391 | name: r.name || r.file.name || `pasted-content-${r.id}.${r.mimeType.split('/')[1] || 'txt'}`, |
| 364 | 392 | content: r.file, |
| 365 | - description: r.eDesc?.value || '', | |
| 393 | + description: r.e.desc?.value || '', | |
| 366 | 394 | mimeType: r.mimeType |
| 367 | 395 | })); |
| 368 | 396 | } |
| 369 | 397 | return rv; |
| 370 | 398 | } |
| @@ -415,8 +443,9 @@ | ||
| 415 | 443 | startWith: 1, |
| 416 | 444 | listener: F.nu({all: cbAttacherChange}), |
| 417 | 445 | controls: [eBtnSubmit] |
| 418 | 446 | }); |
| 419 | 447 | updateBtnSubmit(att); |
| 448 | + F.page.attacher = att /* only for testing via dev console */; | |
| 420 | 449 | }/* /attachaddV2 */ |
| 421 | 450 | |
| 422 | 451 | })(window.fossil); |
| 423 | 452 |
| --- src/fossil.attach.js | |
| +++ src/fossil.attach.js | |
| @@ -164,10 +164,27 @@ | |
| 164 | b.classList.remove('hidden'); |
| 165 | //b.removeAttribute('disabled'); |
| 166 | this.#e.list.append(this.#e.controls/*move to the end*/); |
| 167 | } |
| 168 | } |
| 169 | |
| 170 | #addRow(){ |
| 171 | const id = ++idCounter; |
| 172 | const rowObj = F.nu({ |
| 173 | id, file: null, mimeType: '' |
| @@ -335,10 +352,21 @@ | |
| 335 | img.classList.add('thumbnail'); |
| 336 | rowObj.e.dropzone.insertBefore(img, rowObj.e.remove); |
| 337 | const reader = new FileReader(); |
| 338 | reader.onload = (e)=>img.setAttribute('src', e.target.result); |
| 339 | reader.readAsDataURL(file); |
| 340 | } |
| 341 | this.#events.dispatchEvent( |
| 342 | new CustomEvent('entry-populated',{ |
| 343 | detail: F.nu({ |
| 344 | type: 'entry-populated', |
| @@ -354,17 +382,17 @@ | |
| 354 | attachments. |
| 355 | */ |
| 356 | collectState(){ |
| 357 | const rv = []; |
| 358 | for(let r of this.#rows){ |
| 359 | if( !r.eDropzone?.classList?.contains?.('populated') ){ |
| 360 | continue; |
| 361 | } |
| 362 | rv.push(F.nu({ |
| 363 | name: r.name || r.file.name || `pasted-content-${r.id}.${r.mimeType.split('/')[1] || 'txt'}`, |
| 364 | content: r.file, |
| 365 | description: r.eDesc?.value || '', |
| 366 | mimeType: r.mimeType |
| 367 | })); |
| 368 | } |
| 369 | return rv; |
| 370 | } |
| @@ -415,8 +443,9 @@ | |
| 415 | startWith: 1, |
| 416 | listener: F.nu({all: cbAttacherChange}), |
| 417 | controls: [eBtnSubmit] |
| 418 | }); |
| 419 | updateBtnSubmit(att); |
| 420 | }/* /attachaddV2 */ |
| 421 | |
| 422 | })(window.fossil); |
| 423 |
| --- src/fossil.attach.js | |
| +++ src/fossil.attach.js | |
| @@ -164,10 +164,27 @@ | |
| 164 | b.classList.remove('hidden'); |
| 165 | //b.removeAttribute('disabled'); |
| 166 | this.#e.list.append(this.#e.controls/*move to the end*/); |
| 167 | } |
| 168 | } |
| 169 | |
| 170 | #rowError(rowObj, ...msg){ |
| 171 | let e = rowObj.e.err; |
| 172 | if( e ){ |
| 173 | D.clearElement(e); |
| 174 | }else{ |
| 175 | if( !msg.length ) return; |
| 176 | e = rowObj.e.err = D.addClass(D.span(), 'error'); |
| 177 | rowObj.e.info.append(e); |
| 178 | } |
| 179 | if( msg.length ){ |
| 180 | e.append(...msg); |
| 181 | e.classList.remove('hidden'); |
| 182 | }else{ |
| 183 | e.classList.add('hidden'); |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | #addRow(){ |
| 188 | const id = ++idCounter; |
| 189 | const rowObj = F.nu({ |
| 190 | id, file: null, mimeType: '' |
| @@ -335,10 +352,21 @@ | |
| 352 | img.classList.add('thumbnail'); |
| 353 | rowObj.e.dropzone.insertBefore(img, rowObj.e.remove); |
| 354 | const reader = new FileReader(); |
| 355 | reader.onload = (e)=>img.setAttribute('src', e.target.result); |
| 356 | reader.readAsDataURL(file); |
| 357 | } |
| 358 | if( file.size>F.config.attachmentSizeLimit ){ |
| 359 | /* Problem: tapping this link propagates its click event through |
| 360 | to eDropzone. Thus... */ |
| 361 | const eLink = D.a(F.repoUrl('help/attachment-size-limit'),'limit'); |
| 362 | eLink.addEventListener('click', ev=>ev.stopPropagation()); |
| 363 | this.#rowError(rowObj, "Too large: ", eLink, |
| 364 | " is ",F.config.attachmentSizeLimit," bytes"); |
| 365 | rowObj.ok = false; |
| 366 | }else{ |
| 367 | rowObj.ok = true; |
| 368 | } |
| 369 | this.#events.dispatchEvent( |
| 370 | new CustomEvent('entry-populated',{ |
| 371 | detail: F.nu({ |
| 372 | type: 'entry-populated', |
| @@ -354,17 +382,17 @@ | |
| 382 | attachments. |
| 383 | */ |
| 384 | collectState(){ |
| 385 | const rv = []; |
| 386 | for(let r of this.#rows){ |
| 387 | if( !r.e.dropzone?.classList?.contains?.('populated') ){ |
| 388 | continue; |
| 389 | } |
| 390 | rv.push(F.nu({ |
| 391 | name: r.name || r.file.name || `pasted-content-${r.id}.${r.mimeType.split('/')[1] || 'txt'}`, |
| 392 | content: r.file, |
| 393 | description: r.e.desc?.value || '', |
| 394 | mimeType: r.mimeType |
| 395 | })); |
| 396 | } |
| 397 | return rv; |
| 398 | } |
| @@ -415,8 +443,9 @@ | |
| 443 | startWith: 1, |
| 444 | listener: F.nu({all: cbAttacherChange}), |
| 445 | controls: [eBtnSubmit] |
| 446 | }); |
| 447 | updateBtnSubmit(att); |
| 448 | F.page.attacher = att /* only for testing via dev console */; |
| 449 | }/* /attachaddV2 */ |
| 450 | |
| 451 | })(window.fossil); |
| 452 |