Repository navigation
feat(web): the screen says what is happening, instead of looking stuck (E13-T06, T07, T08) - #107
Merged
Conversation
E13-T06, T07 and T08. Three answers to the same question: "is it stuck or is it loading?". The progress line at the top needed a single point every fetch goes through, and lib/api.ts had nineteen loose ones. lib/progress.ts is that point, and a test asserts none escaped: whoever adds the twentieth call gets the bar without having to remember it, which is the only way a global indicator stays true over time. It counts rather than flags, because two overlapping fetches finishing out of order would erase a bar with work still running, and it stops growing at 80% instead of pretending to know the part nobody can measure. The bar is aria-hidden on purpose. Every screen already carries its own role="status" saying it is loading, and announcing both would make a person hear the same notice twice per fetch. Reduced motion turns the transition off, so it jumps between widths instead of sliding, and still says the same thing: the signal is the width, not the slide. Seven screens traded the word "Carregando" for the shape of what is coming. The word says neither how much nor what; the shape says three paragraphs, a card, a list, and for someone who reads with effort that changes the decision to wait or leave. The word stays, visually hidden, because someone navigating by ear needs the word and not the shape. The offline strip exists because without it the person taps, nothing happens, and the screen blames our side, which is a lie. It separates what still works from what waits: reading the explanation already on screen works, sending answers does not. Two fixes I made after the fact. OfflineBar started as useState in an effect and lint was right to refuse it: it now uses useSyncExternalStore, which is the tool for subscribing to state that lives outside React and which also answers for the server, where navigator does not exist. And RouteProgress had largura in its dependency list, so the effect resubscribed on every width change and left the pending timeout with nobody to clear it; a ref carries that now and the deps are empty.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Quinta fatia do E13 (#23). Três respostas para a mesma pergunta: "travou ou está carregando?"
A linha de progresso no topo
Ela precisava de um ponto único por onde toda busca passa, e o
lib/api.tstinha dezenovefetchsoltos. Olib/progress.tsé esse ponto, e um teste afirma que nenhum escapou: quem acrescentar a vigésima chamada ganha a barra sem precisar lembrar dela, que é a única forma de um indicador global continuar verdadeiro com o tempo.Três decisões que não são óbvias:
aria-hiddende propósito. Cada tela já tem o seurole="status"dizendo que está carregando, e anunciar as duas coisas faria a pessoa ouvir o mesmo aviso duas vezes por busca.Para quem pede menos movimento, a transição some e a barra salta de largura. Continua dizendo a mesma coisa, porque o sinal está na largura, não no deslizamento.
Sete telas trocaram "Carregando" pelo contorno
A palavra sozinha não diz quanto nem o quê. O contorno diz: são três parágrafos, é um cartão, é uma lista. Para quem lê com esforço, isso muda a decisão de esperar ou sair.
A palavra continua lá, escondida. Quem navega ouvindo precisa da palavra, não do contorno — trocar um pelo outro consertaria a tela de quem enxerga e pioraria a de quem não. E com erro o que aparece é a frase, não o desenho do que não vem mais.
Sem animação de brilho: é enfeite, custa bateria em celular básico e some de todo jeito para quem pede menos movimento.
A faixa de sem conexão
Sem ela, a pessoa toca, nada acontece, e a tela culpa o nosso lado — que é mentira. O texto separa o que continua funcionando do que espera: ler a explicação que já está na tela funciona; enviar respostas, não. Essa diferença decide se ela guarda o celular ou continua lendo.
Dois erros meus, e só um foi acusado
O
OfflineBarcomeçou comuseStatedentro de efeito, e o lint recusou com razão. Passou a usaruseSyncExternalStore, que é a ferramenta para assinar estado que vive fora do React — e que também responde pelo servidor, ondenavigatornão existe.O segundo ninguém acusou, e é o que me preocupa mais. Eu tinha posto
largurana lista de dependências do efeito doRouteProgresspara satisfazer uma guarda, e com isso o efeito reassinava a cada crescimento da barra, deixando o tempo pendente da rodada anterior sem quem o cancelasse. Nem tsc, nem lint, nem teste pegam isso. Achei relendo.A regra que fica: dependência nova num efeito que assina algo é sinal de que a guarda está no lugar errado. A guarda virou referência, as dependências ficaram vazias, e o tempo é cancelado na limpeza.
89 testes, lint limpo, build limpo.