Skip to content

Releases

v3.4.1

Choose a tag to compare

@github-actions github-actions released this 23 Jul 05:53

Full Changelog: v3.4.0...v3.4.1

v3.4.0 — Transclusão, .odt e os últimos itens de paridade

Choose a tag to compare

@github-actions github-actions released this 22 Jul 09:32

Fecha os cinco itens que o plano de paridade com o desktop ainda listava como abertos. O que sobra não é pendência: gravação atômica é teto do SAF, o calendário é fase 3, e grafo, chat e plugins estão fora de escopo no celular de propósito.

Transclusão de nota

![[Nota]] e ![[Nota#Seção]] passam a trazer o conteúdo, não só um link. Era o último item de leitura que faltava — sem ele, um texto usado em dez notas é copiado dez vezes e as cópias vão divergindo.

Aqui o conteúdo vira citação, não uma caixa. No desktop o miolo é envolvido num <div>, porque lá o renderizador reprocessa o que está dentro como Markdown. O Markwon não faz isso: HTML injetado deixaria o Markdown de dentro cru na tela. Citação é Markdown de verdade, dá o mesmo limite visual e continua legível se você abrir a nota em qualquer outro editor.

Duas notas que se embutem uma na outra não travam a renderização, e um alvo que não existe fica visível como ![[Nome]] em vez de sumir — embed que some calado esconde que falta uma nota.

Lê .odt

Documentos do LibreOffice abrem e convertem para Markdown, como já acontecia com .docx. Cobre título, negrito e itálico (lidos dos estilos declarados no próprio documento), link, lista com marcador, lista numerada, lista aninhada e tabela.

O parser XML é escrito à mão, e não com o XmlPullParser do Android, porque o do Android é um stub que lança em teste unitário. Sem isso o conversor iria para a loja sem um único teste — e conversor de formato alheio é justamente onde os casos esquecidos moram.

%%comentário%%

Anotação sua que fica no arquivo e não aparece na leitura. Pode engolir um bloco inteiro — um título de rascunho, uma lista — sem deixar restos.

Exportar HTML

No menu da nota, ao lado de exportar PDF. Usa o mesmo HTML da impressão, então o que você salva é o que você veria impresso.

Abrir nota aleatória

No menu do vault. Cai numa nota que você não estava procurando; exclui a que já está aberta, senão o botão devolveria a mesma tela.


Sem permissões, sem Google Play Services, nada sai do aparelho. 231 testes.

v3.3.0

Choose a tag to compare

@github-actions github-actions released this 22 Jul 05:03

Full Changelog: v3.2.0...v3.3.0

v3.2.0

Choose a tag to compare

@github-actions github-actions released this 22 Jul 04:54

Full Changelog: v3.1.0...v3.2.0

v3.1.0

Choose a tag to compare

@github-actions github-actions released this 22 Jul 04:49

Full Changelog: v3.0.0...v3.1.0

v3.0.0 — O celular deixa de ser a versão reduzida

Choose a tag to compare

@github-actions github-actions released this 21 Jul 15:43

O celular deixa de ser a versão reduzida.

Desde a 2.0.0 o app ganhou português, wikilinks que funcionam, busca com operadores, diagnóstico do vault, backup, cache do índice e blocos query. Esta versão fecha as três últimas peças — e com elas o Android faz praticamente tudo que o desktop faz, tirando o que só existe num computador.


🃏 Import de baralho do Anki, direto no celular

⋮ da gaveta → Importar do Anki. Sem Anki Desktop, sem passo intermediário.

E sem dependência nenhuma: a coleção dentro de um .apkg é SQLite puro, e o Android já tem SQLite. A versão desktop precisou trazer o SQLite compilado para WebAssembly para fazer o mesmo trabalho.

  • Notas cloze viram cartões de lacuna; tags A::B viram #A/B.
  • Cloze é detectado pelo texto, não pela tabela de tipo de nota — cujo formato mudou entre versões do Anki. E como nota cloze não tem campo de resposta, exigir uma jogava todas fora em silêncio. Esse bug já aconteceu no desktop; não valia a pena ter duas vezes.
  • Baralho grande vira uma pasta, 100 cartões por nota: uma nota com milhares de cartões leva segundos para abrir; com cem, é instantânea.
  • Ele pergunta antes de escrever qualquer coisa no vault.

Uma limitação, dita com todas as letras: o Anki 2.1.50+ comprime a coleção com zstd, que o Android não tem. Em vez de engordar o APK com uma biblioteca nativa só por isso, um pacote nesse formato é recusado com a instrução exata: no Anki, exporte de novo marcando "Suportar versões antigas do Anki". Instrução precisa vale mais que falha misteriosa.

Mídia não entra por aqui. Os arquivos ficam no pacote com nomes numéricos, e uma referência quebrada no meio do cartão é pior que nada. Se o baralho tem imagens, importe no desktop — o vault é o mesmo.

📊 Estatísticas de revisão

⋮ da gaveta → Estatísticas. Retenção, facilidade média, e a previsão dos próximos 14 dias desenhada como barras.

Sem biblioteca de gráficos: são catorze números, e a forma da fila é a mensagem inteira — uma parede no primeiro dia se lê igual em qualquer resolução. Tudo que está atrasado cai nesse primeiro dia, porque é ali que está.

Um vault sem nada revisado mostra retenção 0, que é a resposta honesta — não uma divisão por zero vestida de 100%.

📖 Leitor de EPUB

Abra um .epub do vault e ele lê, com sumário e zoom, um capítulo por vez.

Também sem biblioteca de leitor: um .epub é um ZIP com um manifesto XML, e o WebView já renderiza o resto. Trazer um leitor inteiro adicionaria uma dependência e os bugs dela; o que é genuinamente chato é achar a ordem de leitura, e essa parte está coberta por testes.

Um capítulo por vez é de propósito: um livro-texto tem dezenas de MB de XHTML, e um celular que precisa segurar tudo para mostrar a primeira página não mostra nada. As imagens do capítulo entram embutidas, porque o WebView roda sem acesso a arquivo e sem rede — um livro é conteúdo não confiável como qualquer outro download.


🧪 Por baixo

153 testes, rodando no CI antes de cada APK. O projeto não tinha nenhum há duas semanas.

Um deles pegou um erro que eu não teria visto de outro jeito: em JavaScript, dois cifrões numa substituição viram um cifrão literal; em Kotlin o cifrão começa uma referência de grupo. A mesma linha portada literalmente do desktop produzia outra coisa na matemática dos cartões do Anki.

📥 Instalação

Assinado com a mesma chave desde a 1.x, então instala por cima sem desinstalar nada e sem perder configurações. Android 9 ou mais novo.

v2.4.0 — Índices que se escrevem sozinhos

Choose a tag to compare

@github-actions github-actions released this 21 Jul 15:12

Índices que se escrevem sozinhos.

🔎 Blocos query

Um bloco assim, dentro de qualquer nota:

```query
tag: sis-cardio
tipo: patologia
sort: modificado desc
limit: 20
```

…vira, no preview, a lista das notas que ele encontra — com wikilinks clicáveis. Não é escrito à mão e não desatualiza: ele lê as tags e o frontmatter na hora de abrir a nota.

  • Filtra por tag:, pasta:, has: e por qualquer campo do frontmatter.
  • Duas linhas tag: se somam: precisa ter as duas. É o corte que dá trabalho manual.
  • sort: por título, modificação ou caminho, com desc; limit: corta a lista.
  • Chaves em português funcionam igual: pasta:, ordenar:, limite:.

Duas regras que vieram de propósito do desktop:

  • Linha que a consulta não entendeu aparece acima da lista, em vez de sumir. Uma consulta que erra em silêncio devolve uma lista que parece certa — e você confia nela.
  • Consulta sem nenhum filtro devolve nada, não o vault inteiro. Pelo mesmo motivo.

📊 Estatísticas de revisão

A lógica está pronta e testada — retenção, previsão de 14 dias, notas com mais cartões. A tela ainda não existe; ela entra numa próxima versão. Prefiro dizer isso a listar como entregue.

Duas decisões que valem explicar: um vault sem nada revisado tem retenção 0, que é a resposta honesta, não uma divisão por zero vestida de 100%. E tudo que está atrasado cai no primeiro dia da previsão, porque é ali que está.

📥 Import de .apkg: adiado, e por quê

O vault é compartilhado entre celular e computador. Importe o baralho no desktop — que já faz isso, inclusive com as imagens — e o resultado aparece aqui pela sincronização: as notas e o srs.json são os mesmos arquivos.

Fazer no celular exigiria uma dependência nativa de zstd só para ele, engordando o APK, para resolver um problema que a pasta compartilhada já resolve.

🧪 Por baixo

+23 testes (117 no total), rodando no CI antes de cada APK.

📥 Instalação

Assinado com a mesma chave, instala por cima da 2.3.0. Android 9 ou mais novo.

v2.3.0 — Abrir o app ficou rápido, e o vault tem backup

Choose a tag to compare

@github-actions github-actions released this 21 Jul 15:00

Abrir o app para de reler o vault inteiro, e o vault ganha um botão de backup.

⚡ O índice não é mais reconstruído do zero

A cada abertura o app lia todas as notas, uma por uma, através do Storage Access Framework — para montar a busca, os backlinks, as tags e os flashcards. Num vault de algumas centenas de notas essa é a coisa mais lenta que ele faz, e fazia por conteúdo que não tinha mudado.

Agora o texto fica guardado entre sessões e é validado por data de modificação: uma nota mexida em outro lugar — no desktop, por exemplo, numa pasta sincronizada — tem mtime diferente e é relida. O resto vem do cache.

Duas decisões que valem explicar:

  • O cache não fica dentro do vault. É informação derivada: perder custa uma releitura e nada mais. Um JSON do tamanho do vault não tem o que fazer numa pasta que você sincroniza e faz backup.
  • Uma nota que não pôde ser lida fica de fora do cache. Guardá-la como texto vazio com data válida a faria parecer atual para sempre, e ela sumiria da busca e dos backlinks atravessando reinícios. Foi exatamente esse o bug que mordeu a versão desktop.

💾 Backup do vault em .zip

No ⋮ do cabeçalho da gaveta. O destino é escolhido pelo seletor do próprio Android, então o arquivo pode ir para o Drive, para o cartão ou para onde você quiser — e o app não precisa de nenhuma permissão de armazenamento.

Inclui tudo: notas, anexos, PDFs e o agendamento dos flashcards. Backup que descarta as imagens em silêncio é pior que nenhum, porque você descobre quando precisa. Um arquivo que não puder ser lido é contado e pulado, e o total aparece no fim — em vez de abortar a operação inteira.

🧭 Onde ficam as ações do vault

Diagnóstico e backup foram para o ⋮ da gaveta, não para o ⋮ da nota. O da nota só existe quando há uma nota aberta; ações do vault ali ficariam inalcançáveis justamente para quem acabou de abrir o app.

🧪 Por baixo

+13 testes (94 no total), rodando no CI antes de cada APK.

📥 Instalação

Assinado com a mesma chave, instala por cima da 2.2.0. Android 9 ou mais novo.

v2.2.0 — Os links levam a algum lugar

Choose a tag to compare

@github-actions github-actions released this 21 Jul 14:42

Os links passam a levar a algum lugar, e a busca a devolver o que você procurou.

🔗 Wikilinks completos

Tocar num link era uma busca por nome exato. Isso quer dizer que [[Nota#Seção]], [[Pasta/Nota]] e qualquer alias do frontmatter simplesmente não faziam nada — sem abrir nota, sem mensagem, sem pista de que havia um alvo.

Agora:

  • [[Nota#Seção]] e [[Nota#^bloco]] abrem a nota.
  • [[Pasta/Nota]] resolve pelo caminho.
  • Aliases do frontmatter funcionam: com aliases: [IAM, Infarto], um [[Infarto]] chega na nota. Em medicina quase tudo tem três nomes; sem isso ou o nome do arquivo vira uma lista de sinônimos, ou a nota fica inalcançável pelos outros nomes.
  • Duas notas com o mesmo nome? Ganha a mais próxima de quem linka — senão o resultado dependeria da ordem em que a pasta foi lida, que ninguém consegue prever.
  • Nome de arquivo real sempre ganha de um alias.
  • E um link que não leva a lugar nenhum diz isso, em vez de ignorar o toque.

🔍 Busca com operadores

Era uma varredura de substring, que num vault de algumas centenas de notas devolve tudo — e portanto nada.

tag:cardio                 protocolo -rascunho
path:Clinica               "dor torácica"
file:sepse                 tag:sistema  (encontra sistema/cardio também)

Os resultados saem por relevância, não em ordem alfabética. O corpo conta com retorno decrescente: contar cada menção linearmente deixava uma nota longa ganhar de uma nota que é de fato sobre o assunto.

Um campo que não existe (autor:joao) vira texto de busca em vez de ser ignorado — ignorar devolveria o vault inteiro por causa de um erro de digitação.

🩺 Diagnóstico do vault

No menu ⋮. Mostra o que está silenciosamente errado:

  • Links mortos, com o nome de quem aponta pra eles. Nomear a origem é a diferença entre uma lista de reclamações e algo em que dá pra agir.
  • Notas órfãs — aquelas que nada referencia.
  • Nomes duplicados — a razão pela qual um [[link]] pode ser ambíguo.

Somente leitura, de propósito: ele diz o que achou; consertar é sua decisão.

🧪 Por baixo

+34 testes (81 no total), rodando no CI antes de cada APK. O resolver de links trabalha sobre um tipo próprio em vez do tipo do Android, porque Uri não existe em teste unitário — e justamente a parte mais delicada não podia ser a intestável.

📥 Instalação

Assinado com a mesma chave, instala por cima da 2.1.0. Android 9 ou mais novo.

v2.1.0 — O app fala português

Choose a tag to compare

@github-actions github-actions released this 21 Jul 14:24

O app fala português.

Até agora todas as strings estavam escritas direto no código, em inglês — inclusive as telas de flashcard e de diagrama que acabaram de nascer na 2.0.0. O desktop já falava três idiomas; o celular, que é onde o app mais é usado, falava um só.

~95 strings extraídas para strings.xml, com português do Brasil, inglês e espanhol. O app segue o idioma do sistema, sem ajuste nenhum a fazer.

O inglês continua sendo a fonte: se uma chave faltar nas outras traduções, ela cai no inglês em vez de quebrar a tela.

Por que agora, e não depois

Os próximos blocos — navegação e busca, robustez, estudo — trazem telas novas. Feito depois, cada uma delas nasceria em inglês e precisaria ser retraduzida. Feito agora, já nascem nos três idiomas.

Instalação

Assinado com a mesma chave das versões anteriores, então instala por cima da 2.0.0 sem desinstalar nada. Android 9 ou mais novo.