feat: accept large JPG and WebP artworks instead of refusing them
Above 150 MB the browser cannot read JPG or WebP in parts, so a large artwork was refused. It is now measured from its header, graded and priced with the discount like any other, and placed on the sheet as a full box, which is exact for JPG. The card says there is no preview and that the team checks the art before printing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -170,6 +170,17 @@ try{
|
|||||||
await evaluate(`folhas=[];pintaFolha()`);
|
await evaluate(`folhas=[];pintaFolha()`);
|
||||||
await evaluate(`pickTipo('avulsa')`);
|
await evaluate(`pickTipo('avulsa')`);
|
||||||
assert.equal(await evaluate('modo'),'avulsa');
|
assert.equal(await evaluate('modo'),'avulsa');
|
||||||
|
// A large JPG artwork cannot be read in parts: it is measured from its
|
||||||
|
// header and placed as a full box, with the discount, instead of refused.
|
||||||
|
await evaluate(`(()=>{const h=new Uint8Array(20);h.set([0xFF,0xD8,0xFF,0xC0,0,17,8,0x09,0x3A,0x09,0x3A,3]);
|
||||||
|
const f=new File([h],'arte-grande.jpg');Object.defineProperty(f,'size',{value:400*1048576});sel([f]);})()`);
|
||||||
|
await waitFor(()=>evaluate(`artes.length===1 && artes[0].semPrevia===true`),'large JPG artwork measured from its header');
|
||||||
|
await fill('[data-cm]',20);
|
||||||
|
await waitFor(()=>evaluate(`!!itemAtual?.production?.sources?.length`),'large JPG artwork packed');
|
||||||
|
assert.deepEqual(await evaluate(`({dpi:Math.round(dpiDe(artes[0])),src:!!artes[0].src,
|
||||||
|
measurement:itemAtual.production.sources[0].measurement,note:$('lista').textContent.includes('Sem prévia')})`),
|
||||||
|
{dpi:300,src:false,measurement:'file',note:true});
|
||||||
|
await evaluate(`artes=[];pintaArtes()`);
|
||||||
await evaluate('sendImage()');
|
await evaluate('sendImage()');
|
||||||
await waitFor(()=>evaluate(`artes.length===1 && !!artes[0].src`),'JPG artwork model');
|
await waitFor(()=>evaluate(`artes.length===1 && !!artes[0].src`),'JPG artwork model');
|
||||||
assert.deepEqual(await evaluate(`({mode:modo,sheets:folhas.length,width:artes[0].cm,quantity:artes[0].q})`),{mode:'avulsa',sheets:0,width:0,quantity:1});
|
assert.deepEqual(await evaluate(`({mode:modo,sheets:folhas.length,width:artes[0].cm,quantity:artes[0].q})`),{mode:'avulsa',sheets:0,width:0,quantity:1});
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ function carrinho(){
|
|||||||
measurement:x.med?'file':'customer'}
|
measurement:x.med?'file':'customer'}
|
||||||
: {kind:'artwork',width_cm:x.cm,length_cm:+(x.cm*propDe(x)).toFixed(4),
|
: {kind:'artwork',width_cm:x.cm,length_cm:+(x.cm*propDe(x)).toFixed(4),
|
||||||
copies:x.q,rotation_degrees:x.giro||0,mirrored:!!x.esp,
|
copies:x.q,rotation_degrees:x.giro||0,mirrored:!!x.esp,
|
||||||
measurement:x.src?'file':'customer'});
|
measurement:(x.src||x.semPrevia)?'file':'customer'});
|
||||||
let layout;
|
let layout;
|
||||||
if(ehFolha()){
|
if(ehFolha()){
|
||||||
let y=0;
|
let y=0;
|
||||||
|
|||||||
@@ -337,7 +337,7 @@ function previaAoVivo(){
|
|||||||
tMont=setTimeout(()=>{
|
tMont=setTimeout(()=>{
|
||||||
// o produto pode ter sido fechado nesses 140 ms (item foi para o carrinho)
|
// o produto pode ter sido fechado nesses 140 ms (item foi para o carrinho)
|
||||||
if(!modo) return;
|
if(!modo) return;
|
||||||
const prontas=artes.filter(a=>a.cm>0 && a.cm<=larguraFilme() && a.src);
|
const prontas=artes.filter(a=>a.cm>0 && a.cm<=larguraFilme() && (a.src||a.semPrevia));
|
||||||
const W=Math.round(300*ZOOMS[zoomI]);
|
const W=Math.round(300*ZOOMS[zoomI]);
|
||||||
$('vArea').classList.toggle('ampliado', zoomI>0);
|
$('vArea').classList.toggle('ampliado', zoomI>0);
|
||||||
desenhaMontagem($('vArea'), prontas, 0, W, $('vUso'), r=>{
|
desenhaMontagem($('vArea'), prontas, 0, W, $('vUso'), r=>{
|
||||||
|
|||||||
@@ -541,13 +541,11 @@ function pintaArtes(){
|
|||||||
if(a.lendo!=null){
|
if(a.lendo!=null){
|
||||||
barra='<div class="prog"><i style="width:'+a.lendo+'%"></i></div>'+
|
barra='<div class="prog"><i style="width:'+a.lendo+'%"></i></div>'+
|
||||||
'<span class="progT">arquivo grande · gerando a prévia… '+a.lendo+'%</span>';
|
'<span class="progT">arquivo grande · gerando a prévia… '+a.lendo+'%</span>';
|
||||||
}else if(a.decodeError==='grande'){
|
|
||||||
aviso='<p class="avisoF"><b>Arquivo grande em JPG ou WebP.</b> Exporte em PNG para montar a folha.</p>';
|
|
||||||
}else if(a.decodeError){
|
}else if(a.decodeError){
|
||||||
aviso='<p class="avisoF"><b>Não conseguimos ler esta imagem.</b> Exporte novamente em PNG ou JPG.</p>';
|
aviso='<p class="avisoF"><b>Não conseguimos ler esta imagem.</b> Exporte novamente em PNG ou JPG.</p>';
|
||||||
}else if(a.cm>larguraFilme()){
|
}else if(a.cm>larguraFilme()){
|
||||||
aviso='<p class="avisoF"><b>Largura maior que o filme.</b> O filme aqui tem '+n1(larguraFilme())+' cm.</p>';
|
aviso='<p class="avisoF"><b>Largura maior que o filme.</b> O filme aqui tem '+n1(larguraFilme())+' cm.</p>';
|
||||||
}else if(a.cm>0 && a.src){
|
}else if(a.cm>0 && (a.src||a.semPrevia)){
|
||||||
const dpi=Math.round(dpiDe(a));
|
const dpi=Math.round(dpiDe(a));
|
||||||
medida='<b>'+n1(a.cm)+' × '+n1(a.cm*propDe(a))+' cm</b>';
|
medida='<b>'+n1(a.cm)+' × '+n1(a.cm*propDe(a))+' cm</b>';
|
||||||
chips='<ul class="chips"><li class="chip '+(dpi>=DPI_AVISA?'ok':dpi>=DPI_RECUSA?'av':'er')+'">'+dpi+' DPI</li>'+
|
chips='<ul class="chips"><li class="chip '+(dpi>=DPI_AVISA?'ok':dpi>=DPI_RECUSA?'av':'er')+'">'+dpi+' DPI</li>'+
|
||||||
@@ -564,8 +562,11 @@ function pintaArtes(){
|
|||||||
n1(sug.cm)+' cm.<button data-usar="'+i+'" data-cm="'+sug.alvo+'">Usar '+n1(sug.alvo)+' cm</button></div>'
|
n1(sug.cm)+' cm.<button data-usar="'+i+'" data-cm="'+sug.alvo+'">Usar '+n1(sug.alvo)+' cm</button></div>'
|
||||||
: '';
|
: '';
|
||||||
}
|
}
|
||||||
|
if(a.semPrevia && !a.decodeError)
|
||||||
|
aviso+='<p class="repTxt"><b>Sem prévia para '+escapeHTML(extDe(a.f.name))+' deste tamanho.</b> '+
|
||||||
|
'A arte entra na folha pela medida, e a equipe confere antes de imprimir. Em PNG, a prévia aparece.</p>';
|
||||||
const mini = a.miniSrc ? '<img src="'+escapeHTML(a.miniSrc)+'" alt="">' : '<span>'+escapeHTML(extDe(a.f.name))+'</span>';
|
const mini = a.miniSrc ? '<img src="'+escapeHTML(a.miniSrc)+'" alt="">' : '<span>'+escapeHTML(extDe(a.f.name))+'</span>';
|
||||||
const sub = a.cm>0 && a.src ? (a.q>1? a.q+' × ' : '')+'<b>'+n1(a.cm)+' × '+n1(a.cm*propDe(a))+' cm</b>' : '';
|
const sub = a.cm>0 && (a.src||a.semPrevia) ? (a.q>1? a.q+' × ' : '')+'<b>'+n1(a.cm)+' × '+n1(a.cm*propDe(a))+' cm</b>' : '';
|
||||||
return '<div class="rep art2'+(a===recemChegada?' nova':'')+'" data-arte="'+i+'">'+
|
return '<div class="rep art2'+(a===recemChegada?' nova':'')+'" data-arte="'+i+'">'+
|
||||||
'<div class="repTopo"><div class="miniF">'+mini+'</div><div class="repInfo">'+
|
'<div class="repTopo"><div class="miniF">'+mini+'</div><div class="repInfo">'+
|
||||||
'<div class="l1"><b>'+escapeHTML(a.f.name)+'</b>'+(a===recemChegada?'<em class="novaT">nova</em>':'')+
|
'<div class="l1"><b>'+escapeHTML(a.f.name)+'</b>'+(a===recemChegada?'<em class="novaT">nova</em>':'')+
|
||||||
@@ -622,7 +623,7 @@ function pintaArtes(){
|
|||||||
previaAoVivo();
|
previaAoVivo();
|
||||||
}
|
}
|
||||||
function resumoArtes(){
|
function resumoArtes(){
|
||||||
const r=$('rA'), prontas=artes.filter(a=>a.cm>0 && a.cm<=larguraFilme() && a.src);
|
const r=$('rA'), prontas=artes.filter(a=>a.cm>0 && a.cm<=larguraFilme() && (a.src||a.semPrevia));
|
||||||
if(!prontas.length){ r.style.display='none'; return; }
|
if(!prontas.length){ r.style.display='none'; return; }
|
||||||
const m=montagemCm/100; // a mesma folha que aparece ao lado
|
const m=montagemCm/100; // a mesma folha que aparece ao lado
|
||||||
const notas=prontas.map(a=>Math.max(6,Math.min(100,Math.round(dpiDe(a)/300*100))));
|
const notas=prontas.map(a=>Math.max(6,Math.min(100,Math.round(dpiDe(a)/300*100))));
|
||||||
|
|||||||
@@ -64,9 +64,7 @@ function avaliar(){
|
|||||||
}
|
}
|
||||||
if(!artes.length) return {pronto:false, falta:'Arraste suas artes para começar.'};
|
if(!artes.length) return {pronto:false, falta:'Arraste suas artes para começar.'};
|
||||||
if(artes.some(a=>a.lendo!=null)) return {pronto:false, falta:'Gerando a prévia das artes grandes…'};
|
if(artes.some(a=>a.lendo!=null)) return {pronto:false, falta:'Gerando a prévia das artes grandes…'};
|
||||||
if(artes.some(a=>a.decodeError==='grande'))
|
if(artes.some(a=>a.decodeError || !(a.src||a.semPrevia) || !(a.px>0) || !(a.py>0)))
|
||||||
return {pronto:false, falta:'Uma arte grande está em JPG ou WebP. Exporte-a em PNG para montar a folha.'};
|
|
||||||
if(artes.some(a=>a.decodeError || !a.src || !(a.px>0) || !(a.py>0)))
|
|
||||||
return {pronto:false, falta:'Não conseguimos ler uma das imagens. Exporte-a novamente em PNG ou JPG antes de continuar.'};
|
return {pronto:false, falta:'Não conseguimos ler uma das imagens. Exporte-a novamente em PNG ou JPG antes de continuar.'};
|
||||||
if(artes.some(a=>!Number.isFinite(a.cm) || a.cm>larguraFilme()))
|
if(artes.some(a=>!Number.isFinite(a.cm) || a.cm>larguraFilme()))
|
||||||
return {pronto:false, falta:'A largura da arte precisa caber no filme de '+
|
return {pronto:false, falta:'A largura da arte precisa caber no filme de '+
|
||||||
|
|||||||
@@ -128,7 +128,9 @@ function medir(a){
|
|||||||
return dimensoesImagem(a.f).then(async d=>{
|
return dimensoesImagem(a.f).then(async d=>{
|
||||||
if(!d || !(d.w>0) || !(d.h>0)){ a.decodeError=true; return a; }
|
if(!d || !(d.w>0) || !(d.h>0)){ a.decodeError=true; return a; }
|
||||||
a.px=d.w; a.py=d.h; a.prop=d.h/d.w; a.grande=true;
|
a.px=d.w; a.py=d.h; a.prop=d.h/d.w; a.grande=true;
|
||||||
if(!/\.png$/i.test(a.f.name)){ a.decodeError='grande'; return a; }
|
// JPG and WebP cannot be read in parts: the art is placed by its
|
||||||
|
// measurements, as a full box, and the team checks it before printing.
|
||||||
|
if(!/\.png$/i.test(a.f.name)){ a.semPrevia=true; return a; }
|
||||||
a.lendo=0; pintaArtes();
|
a.lendo=0; pintaArtes();
|
||||||
let mostrado=0;
|
let mostrado=0;
|
||||||
const cv=await previaPngGrande(a.f, 1200, p=>{
|
const cv=await previaPngGrande(a.f, 1200, p=>{
|
||||||
|
|||||||
Reference in New Issue
Block a user