Aplicació client en català de Mastodon, per Android
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-18 20:35:29 +02:00
app Versió 1.2 2026-10-18 20:35:29 +02:00
gradle Android Gradle Plugin 9.3.3 2026-10-13 14:43:21 +02:00
.gitignore El .gitignore es versiona 2026-10-14 20:11:10 +02:00
build.gradle.kts Tanca el cercle d'OAuth: ja es pot connectar un compte real 2026-08-11 18:04:57 +02:00
DISTRIBUCIO.md R8 al release i mapatges desats fora de build 2026-10-14 20:06:53 +02:00
gradle.properties Esquelet inicial del projecte Android 2026-08-11 15:28:22 +02:00
gradlew Esquelet inicial del projecte Android 2026-08-11 15:28:22 +02:00
gradlew.bat Esquelet inicial del projecte Android 2026-08-11 15:28:22 +02:00
LICENSE Afegeix README, llicència AGPL-3.0 i ajusta el .gitignore 2026-08-11 15:41:49 +02:00
PLAY_STORE.md La signatura de Play ja està configurada 2026-10-13 18:12:48 +02:00
README.md Els mitjans sensibles segueixen la preferència del servidor 2026-10-18 20:30:41 +02:00
settings.gradle.kts Esquelet inicial del projecte Android 2026-08-11 15:28:22 +02:00

Tuts per Android

Client de Mastodon per a Android, escrit en Kotlin i Jetpack Compose. La interfície és en català.

És el port de Tuts per a iOS. Mateixes funcionalitats, però aparença d'Android: Material 3 idiomàtic, no una còpia de la versió iOS.

⚠️ Estat del projecte

En desenvolupament. Ja es pot fer servir per llegir, publicar, editar, citar, programar, conversar, votar en enquestes, mirar imatges i vídeos, cercar, moderar el que et pot arribar, gestionar llistes, filtres i col·leccions, seguir les notificacions —també amb l'app tancada, per push— i visitar el perfil de qualsevol compte —el propi inclòs—, amb més d'un compte alhora.

Tot el que es llista com a funcionant està provat en un dispositiu físic amb comptes reals de dos servidors.

El que ja funciona

Entrar a Tuts. La primera pantalla té dues targetes, Inicia sessió i Crea un compte, cadascuna amb un botó directe per a mastodont.cat i un altre per a «Un altre servidor». Aquest segon demana el servidor en un diàleg, amb l'exemple a sota del camp, i hi ofereix per tocar els servidors on ja tens algun compte connectat, perquè no l'hagis de tornar a escriure. Abans hi havia un sol camp amb «mastodont.cat» com a text d'exemple, i semblava que ja hi fos escrit.

Comptes. Multicompte des del primer dia, amb OAuth 2.0 i PKCE. Canvi de compte des de l'avatar, i desconnexió que revoca la sessió al servidor abans de treure el compte del dispositiu: si la revocació falla, el compte no s'esborra. Res de Tuts entra a la còpia de seguretat d'Android ni passa a un mòbil nou: els testimonis van xifrats amb una clau que no surt mai del dispositiu, i en un mòbil nou cal tornar a connectar els comptes.

Crear un compte. Des de la mateixa pantalla d'inici de sessió, sense sortir de Tuts: les normes del servidor, els seus termes de servei si en publica, i el formulari. Tot el que es demana surt del que diu el servidor —l'edat mínima és la seva, el motiu només si el fa falta— i, si té el registre tancat o el fa al seu web, es diu en comptes d'oferir un formulari que fallaria. Els errors de validació es diuen en català, traduint els codis de l'API i no la frase anglesa del servidor.

Esborrar un compte. Al final del menú de l'avatar, «Esborra el compte…» porta al web del servidor (/settings/delete), on l'usuari inicia la sessió i ho confirma: l'API de Mastodon no té cap camí per esborrar un compte des d'una app. En tornar a Tuts, l'app pregunta al servidor si el testimoni encara val, i només si respon 401 o 403 treu el compte del dispositiu, amb la seva caché. Si no l'has acabat d'esborrar no passa res, i si no es pot comprovar el compte es queda i es pot tornar a provar. Si el sistema tanca Tuts mentre ets al web, la comprovació es fa igualment en tornar.

⚠️ El compte no entra a Tuts fins que en confirmes el correu, perquè fins llavors el testimoni que dona el servidor no serveix. La pantalla d'espera ho comprova sola cada deu segons i en tornar a l'app, així que tant li fa on obris l'enllaç —en aquest mòbil, a l'ordinador o al cap d'una estona—: quan torns a Tuts, hi ets a dins. També pots tornar a demanar el correu i canviar l'adreça si t'has equivocat escrivint-la.

Línies de temps. Inici, Local i Federada, cadascuna amb el seu estat i la seva caché. S'obren a l'instant des de la caché i el refresc arriba per sobre. Mantenint premuda Local o Federada s'hi pot posar una de les teves llistes, que llavors es comporta igual que les altres: caché, tuts nous cada 30 segons i on t'havies quedat llegint. Es tria per compte, perquè les llistes són de cada servidor, i tornar-hi a triar «Local» o «Federada» ho desfà.

Refrescar a mà. El botó de la barra superior torna a baixar la línia de temps del servidor. Mentre dura, la icona es converteix en un indicador que gira dins del mateix botó —que és on mires quan acabes de prémer-lo—, i quan acaba, si ha portat tuts nous, el comptador diu quants n'han entrat per sobre d'on llegies.

⚠️ El refresc no atura la línia de temps ni la pot desfer. Mentre la petició vola tot segueix funcionant igual —els tuts nous hi entren, la paginació cap avall també—, i la llista només es toca si la petició ha portat tuts. Si falla o torna buida, el que hi ha a pantalla es queda exactament com estava i només en surt un avís de tres segons.

Tuts nous. Es demanen cada 30 segons i entren de seguida a la llista, per damunt d'on estàs llegint i sense moure't de lloc. Un comptador diu quants n'hi ha a sobre i baixa a mesura que hi puges amb el dit; tocant-lo t'hi porta de cop.

Tornar després d'unes hores. En obrir l'app es demana una sola pàgina, la més nova, i els tuts entren per sobre sense moure't de lloc. Si aquella pàgina ha vingut plena —senyal que al servidor n'hi pot haver més— es marca el buit amb un «Carrega el que falta» entre els nous i el que llegies, que l'obre quan el toques.

⚠️ El forat hi és per dir la veritat, no per estalviar peticions. Abans es demanaven fins a vint pàgines seguides per omplir el buit, i quan el sostre s'esgotava la línia de temps quedava incompleta sense cap senyal: entre dos tuts consecutius hi podia haver un forat de dies i res no ho deia. Ara el buit es veu, i s'omple només si el vols. És la tècnica d'Ice Cubes.

Tuts llargs. Els que passen dels 500 caràcters es veuen retallats a vuit línies, amb un «Llegir més…» que els desplega allà mateix, com a iOS. El llindar i el punt de tall són dos números diferents a posta: retallar just als 500 deixaria un tut de 501 pràcticament sencer i el botó no estalviaria res.

Avisos de contingut. Un tut amb avís surt tapat: es veu qui l'ha escrit, una franja de color amb el text de l'avís i les accions, i res més. Tocant la franja —«Mostra'n més»— se n'obren el text, la cita, les imatges, la targeta de l'enllaç i l'enquesta, i tornant-la a tocar —«Amaga la publicació»— es torna a tapar, com a Mastodon web. Les imatges marcades com a sensibles segueixen sota la seva cortina després de desplegar l'avís: llegir de què va i voler veure la imatge són dues decisions.

Mitjans sensibles, com diu el teu servidor. Tuts segueix la preferència «Mitjans» que tens a la web del teu servidor (Preferències → Aparença): amagar només els sensibles, que és el normal, ensenyar-ho tot, o amagar-ho tot —llavors la cortina diu «Mitjans ocults»—. Va per compte, perquè cada compte té la seva, i també s'aplica a la miniatura d'un tut citat. Es torna a llegir en obrir l'app, en canviar de compte, en tornar-hi i en prémer el botó de refrescar, així que un canvi fet des de l'ordinador arriba sense tancar res. L'API només la deixa llegir: a Configuració → Mèdia, «Preferències del servidor» porta a la pàgina on es canvia.

Emojis del servidor. Els emojis personalitzats de cada servidor es veuen com a imatges —no com a :codi:— al cos dels tuts, als avisos de contingut, a les cites, a les traduccions, als noms de la gent i a la biografia i els camps del seu perfil. Es pinten dins del text, així que creixen amb la mida de lletra que triïs a Configuració i surten més petits dins d'una cita, sense trencar les línies. Al compositor, la cara somrient obre el catàleg del teu servidor amb cerca i categories, i el que triïs s'escriu on tinguis el cursor. ⚠️ Els emojis són de cada servidor: n'hi ha que no en tenen cap, i llavors el selector ho diu.

Enllaços, mencions i etiquetes. El contingut d'un tut es parseja de debò: els enllaços s'obren en un full que puja de baix a dalt i deixa veure el tut al darrere —escurçats com a la web de Mastodon—, tocar una menció o un avatar obre el perfil d'aquell compte, i tocar una etiqueta obre la seva línia de temps. Qui prefereixi el navegador del sistema ho pot dir a Configuració.

Etiquetes. Pantalla pròpia amb els tuts de l'etiqueta, paginada, i el botó de seguir-la o deixar-la de seguir a la barra. Funciona igual dins d'un tut remot, on l'adreça de l'etiqueta apunta al servidor d'origen.

Les quatre pestanyes d'Etiquetes. Des del menú «···», com a iOS: Tendència (les que es couen al servidor, amb la corba d'ús), Llistes, Seguint i Destacades —les que surten al teu perfil—. A totes hi ha un filtre per anar-hi de pressa, i el «+» de la barra afegeix una etiqueta a Seguint o a Destacades i obre el formulari a Llistes.

Llistes d'etiquetes. Una etiqueta principal més les condicions que ha de complir un tut: que en porti alguna d'unes altres, que les porti totes, que no en porti cap d'unes terceres, i si ha de ser del servidor o portar imatges. Són els paràmetres que Mastodon accepta a la línia de temps d'una etiqueta, guardats amb un nom. ⚠️ No existeixen a cap servidor: viuen al dispositiu i van per compte —a Room, amb esborrat en cascada—, o sigui que no es veuen ni a la web ni a Tuts d'iOS.

Perfils. Bàner, avatar, biografia, camps verificats i data d'alta, amb tres llistes —tuts, respostes i impulsos— i el botó de seguir, que distingeix seguir de sol·licitud pendent en els comptes amb candau. Sota la data d'alta, el botó Contingut obre els tuts amb imatges, vídeo o àudio d'aquell compte, sense haver de buscar-los baixant per la llista.

El teu perfil. La pestanya Perfil és la mateixa pantalla, amb el teu compte: allà no hi ha botó de seguir, i el lloc de la creu de tancar el pren el menú de comptes. Quan desas els canvis de l'editor de perfil, la capçalera els ensenya a l'acte. Quan publiques un tut, hi apareix a dalt sense haver de canviar de pestanya, i el comptador de tuts puja; si estaves llegint més avall, la llista no es mou. Qui decideix a quina pestanya va és el servidor: una resposta a algú altre surt a Respostes, i una resposta a un tut teu, que és la continuació d'un fil, també surt a Tuts.

Editar el perfil. Des del llapis de la barra del teu perfil: nom visible, biografia, fins a quatre camps, avatar i bàner. El text que s'edita és el que vas escriure, no l'HTML que en fa el servidor.

Seguits i seguidors. Els comptadors del perfil obren la llista, paginada com mana el servidor, amb un menú per compte per seguir, silenciar, i decidir si vols les seves notificacions i els seus impulsos.

On llegies. En tornar a una línia de temps —o en obrir l'app després que el sistema hagi matat el procés— es recupera el punt exacte on eres, per identificador de tut i amb el tros que n'havies passat per sobre, no per posició a la llista.

Converses. Tocar un tut n'obre el fil, col·locat pel tut que has tocat. Dins d'un fil se'n pot obrir un altre.

Respostes a les llistes. A les línies de temps, als perfils, a les etiquetes i a les llistes de tuts, una resposta ho diu a dalt de la cel·la, com Mastodon web: «Continuació del fil» si respon un tut del mateix autor, «En resposta a @algú» si respon algú altre —tocant-ho se n'obre el perfil— i «Respost al fil» si no se'n sap qui. Dins d'una conversa no hi surt, perquè ja es veu de què penja cada resposta, ni en un impuls o una menció privada, que ja tenen la seva línia.

Publicar. Text, avís de contingut, visibilitat i fins a quatre imatges, cadascuna amb el seu text alternatiu. També vídeo, GIF i àudio —triat del dispositiu o gravat allà mateix amb el micròfon—; en un aparell sense micròfon, com una tauleta o un Chromebook, el botó de gravar no hi és i la resta funciona igual. També enquestes de fins a quatre opcions, amb durada i resposta múltiple. Respondre hereta les mencions i la visibilitat de l'original, i ensenya a dalt el tut que respons sencer: el compositor tapa la pantalla sencera, i les mencions que ja hi troba escrites diuen a qui respons, però no a què. El teclat comença cada frase amb majúscula, i qui no ho vulgui ho pot apagar a Configuració → Teclat: val alhora per al cos, l'avís de contingut, el text alternatiu d'una imatge, les opcions d'una enquesta, el títol d'un filtre i el nom d'una llista. Els camps que són identificadors —una etiqueta, un servidor— no capitalitzen mai, hi digui el que hi digui la preferència.

⚠️ Un vídeo va sol, sense cap altre adjunt: ho exigeix el servidor. Per això, amb imatges ja posades, el selector només ofereix fotos, i si es tria un vídeo amb alguna cosa més, Tuts ho diu en comptes de triar per tu què es queda. Un vídeo, un àudio o un GIF diuen «Pujant…» fins que el servidor l'ha acabat de processar, i no només de rebre: abans, el servidor no deixa publicar-lo. El text alternatiu es pot escriure mentrestant, i s'hi desa quan acaba.

⚠️ El botó de publicar és a dalt a la dreta, ple amb el color d'accent —o el del fons de pantalla, amb Material You—, i desactivat es veu gris mentre no hi ha res per publicar. Diu el que farà: «Publica», «Programa» si hi has posat data, o «Desa» si edites. Fins a la prova tancada era un text amb el mateix estil que el títol, i un provador va trigar a trobar-lo. Amb la lletra del sistema molt gran, el que s'escurça és el títol, mai el botó.

⚠️ La barra d'eines es queda sempre damunt del teclat, i el que escrius sempre es veu. El tut respost, el text i els adjunts es desplacen junts, i la línia on tens el cursor es manté a la vista mentre escrius, quan mous el cursor i quan el teclat torna a sortir. Un enllaç, una imatge o un vídeo s'afegeixen a sota del text i no li prenen l'espai: la caixa sempre en conserva unes quatre línies. Ho van reportar provadors de la prova tancada: amb una targeta d'enllaç o un vídeo, la caixa de text quedava aixafada fins a desaparèixer, i responent, els botons de baix quedaven sota el teclat.

⚠️ A la capçalera, la visibilitat i el rellotge no es mouen mai i el nom d'usuari s'estira fins a tocar-los. Abans es repartien l'espai a mitges: un nom llarg es retallava amb punts suspensius tenint espai buit al costat, i el que aquell nom no gastava desplaçava els dos controls de la dreta —fins a treure el rellotge de la targeta—. El menú de la visibilitat es desplega centrat amb el seu botó, sense sortir del compositor.

Mencionar algú. Escrivint @ i dues lletres, surten fins a quatre comptes per triar; el que es tria substitueix el que estaves escrivint i el text es queda tal com el tenies, salts de línia inclosos. Es busca la menció sota el cursor, així que també funciona editant-ne una al mig d'un tut ja escrit.

Targeta dels enllaços. Un tut amb un enllaç ensenya la targeta que n'ha fet el servidor: miniatura, d'on ve, títol i descripció, i tocar-la l'obre. Només si el tut no porta adjunts —el que ha triat l'autor mana—, com fan iOS i la web de Mastodon. Que un enllaç no en tingui és normal: la targeta la fabrica el servidor en segon pla, i una pàgina sense metadades Open Graph no en dona cap.

Previsualització en escriure. En enganxar una adreça al compositor, si la pàgina té metadades Open Graph surt la seva targeta —imatge, títol, descripció i nom del lloc— sense haver de publicar res. La creu la treu. ⚠️ Qui visita la pàgina és el teu mòbil, no el servidor: no hi ha cap camí de l'API de Mastodon per demanar la targeta d'un enllaç abans de publicar-lo, i la petició va sense el testimoni del teu compte.

Enquestes. Es veuen a les línies de temps amb les seves barres, s'hi vota des de la mateixa cel·la i el resultat s'actualitza a l'instant. Les pròpies no s'hi voten, igual que a Mastodon web.

Imatges, vídeo i àudio. Tocar una imatge l'obre a mida original, amb zoom de pinça cap al punt dels dits, pas d'una imatge a l'altra, text alternatiu desplegable i un menú per compartir-la, desar-la a la galeria o copiar-la. Els vídeos i els GIF es reprodueixen a la mateixa cel·la, a la mida de la previsualització, i la icona de la cantonada els amplia. A Configuració es pot demanar que s'animin sols: llavors ho fa el del mig de la pantalla, mut i en bucle com a Mastodon web, i tocant-lo se sent. L'àudio sona també dins de la cel·la, amb la seva forma d'ona i la durada que dona el servidor. El rètol ALT de qualsevol imatge, vídeo o GIF ensenya el text alternatiu en una bafarada, sense reproduir ni obrir res, com a Mastodon web.

L'idioma del tut. Es declara sempre, i no és cap etiqueta decorativa: Mastodon decideix a partir d'ell si el tut es podrà traduir i cap a quins idiomes. El selector és a l'extrem de la barra d'eines, amb bandera i nom, i recorda l'últim que has triat; si no n'has triat mai cap, fa servir el del dispositiu. Sense enviar-lo, el servidor hi posaria l'idioma del teu perfil, que en un mòbil gairebé mai és el del text.

Editar un tut. Des del menú del tut. El compositor s'obre amb el text que vas escriure, no amb l'HTML que en fa el servidor, i el tut editat s'actualitza a totes les pantalles obertes sense refrescar res. La visibilitat s'ensenya però no es pot canviar: el tut ja ha federat i l'API no ho admet. L'enquesta s'hi conserva amb els seus vots mentre no en canviïs les opcions; si ja era tancada, en desar l'edició es torna a obrir, igual que a Mastodon web. Cada vegada que l'obres, el compositor parteix del tut tal com és ara: una edició deixada a mitges no es recupera.

Citar un tut. També des del menú, si qui l'ha escrit ho permet. El tut citat es veu dins del compositor mentre escrius i, un cop publicat, dins de la teva cel·la, amb el seu autor, la seva visibilitat i la seva hora. Els avisos de contingut del tut citat es respecten: una cita no és una manera d'esquivar-los.

Històric d'edicions. De qualsevol tut que s'hagi editat: totes les versions, de la més nova a la més vella, amb la data de cadascuna i «Original» a la primera.

De qui és i qui el veu, d'un cop d'ull. Al costat de l'hora de cada tut hi ha la icona de la seva visibilitat —el globus si és públic, el candau obert, el candau o el sobre— i, si s'ha editat, un llapis. Van enganxats a l'hora, que és on l'ull ja mira.

Accions. Impulsar, marcar com a favorit i respondre, amb els comptadors sincronitzats entre totes les pantalles obertes. La cinquena icona és el comptador de cites: quan un tut n'ha rebut alguna s'hi pot tocar, i surt la llista de qui l'ha citat. ⚠️ Aquella llista pot ser més curta que el número, com les de qui ha marcat i qui ha impulsat: el comptador és un agregat i la llista la filtra el servidor per visibilitat. Les cinc accions es reparteixen l'amplada de la cel·la a parts iguals, de manera que les icones cauen sempre al mateix lloc: un comptador de quatre xifres no desplaça les que té al costat.

Notificacions. A Configuració → Notificacions, i és per compte: la política de filtratge del servidor amb els seus sis criteris —qui no segueixes, qui no et segueix, comptes nous, mencions privades, comptes limitats i bots—, cadascun amb accepta, filtra o descarta. El que la política filtra no es perd: la pestanya Notificacions ho avisa amb una fila al capdamunt —com el bàner de Mastodon web— que obre la safata del que s'ha retingut, i des d'allà s'accepta o es descarta compte per compte —descartar demana confirmació, perquè el servidor no en guarda cap còpia—. Cada fila es desplega i ensenya què s'ha retingut de debò —el tipus i un tros del tut— sense haver d'acceptar res, de manera que la decisió es pren veient-la i no a cegues. ⚠️ Acceptar no és puntual: deixa passar aquell compte a partir d'aleshores, i la pantalla ho diu perquè el servidor no ho pot desfer. Cada criteri diu sota seu què vol dir de debò, amb els llindars que fa servir el servidor: 30 dies per a un compte nou, 3 per a un seguidor recent. ⚠️ Els vuit «tipus de notificació» d'aquella pantalla no filtren la llista: són les alertes del push, i decideixen què et sona al mòbil. Qui decideix què entra a la llista és la política, que viu al servidor i val per als dos camins.

Barres que s'aparten. Opcional, a Configuració → Navegació: mentre desplaces la llista —amunt o avall— la barra de dalt, la de pestanyes i els dos botons flotants s'aparten de la pantalla, i tornen sols quan pares. Mentre llegeixes hi ha la pantalla sencera; en aturar-te hi tornes a tenir tot a mà. Al Moto g84 això són 142 dp dels 861 de la pantalla —un 16,5 %—, que és la diferència entre veure tres tuts i mig i veure'n quatre i mig. Ve apagat de fàbrica.

Aparença. Tema clar, fosc o igual que el sistema; color d'accent —el dinàmic del fons de pantalla o sis colors fixos, amb un tut d'exemple per veure com queda—; i la mida del text dels tuts amb una mostra que creix mentre mous el control. Tot s'aplica a l'instant, barres del sistema incloses. La pantalla d'inici també segueix el tema: la dibuixa el sistema abans que l'app existeixi, i per això té fons propi per a clar i per a fosc —agafat de la mateixa paleta dinàmica que l'app, perquè no es vegi cap graó— i se li diu quin vol Tuts quan el tema està forçat i no coincideix amb el del mòbil.

Memòria cau. Configuració —tocant l'avatar— diu què ocupen les imatges i les dades, i les esborra totes dues. A diferència de la versió d'iOS, el número inclou la caché d'imatges, que és la grossa de llarg.

Favorits i marcadors. Les dues llistes, paginades tal com mana el servidor —el cursor d'aquests dos camins no és l'identificador del tut i només arriba per la capçalera Link—. Els marcadors es desen i es treuen des del menú de qualsevol tut, i el que deixa de pertànyer a la llista en surt sol.

El menú de cada tut. La primera icona de la fila d'accions obre el menú del tut, i també s'obre mantenint premut el tut: editar-lo, citar-lo, veure qui l'ha marcat com a favorit i qui l'ha impulsat, fixar-lo al perfil, esborrar-lo, desar-lo als marcadors, copiar-ne el text —tal com es llegeix, amb els salts de línia, i només si no és tapat per un avís de contingut—, obrir-lo al navegador, copiar-ne l'enllaç, compartir-lo, traduir-lo, veure'n l'històric d'edicions i denunciar-lo. Fixar, editar i esborrar només surten als teus, i denunciar només als d'altri; l'històric, només als tuts que s'han editat. La traducció la fa el servidor, així que l'opció només apareix si la instància la té activada; les cites demanen Mastodon 4.5 o superior.

⚠️ Denunciar informa qui modera el teu servidor sobre el COMPTE, amb el tut adjunt com a context: és com funciona l'API, i la pantalla ho diu perquè no sorprengui. Es pot triar el motiu i, si és per incompliment, quines normes del servidor; el comentari té el màxim de 1.000 caràcters que accepta l'API. Amb un compte d'un altre servidor es pot demanar que la denúncia hi arribi també.

Silenciar una conversa. A la barra del fil, i només si hi has participat: deixes de rebre notificacions d'aquell fil i el botó queda destacat mentre ho està. Es pot desfer.

El botó «···». Sura a baix a la dreta a les quatre pestanyes, translúcid com les barres, i porta el menú del que no cap a la barra. A Inici comparteix columna amb el botó de tut nou, que s'aparta cap amunt per deixar-li lloc. A Configuració → Navegació es pot demanar que el botó de tut nou surti també a Perfil, al mateix lloc que a Inici; ve apagat de fàbrica. Les nou entrades porten a la seva pantalla; l'ordre és el de la versió d'iOS.

Silenciats i bloquejats. Les dues llistes comparteixen pantalla amb dues pestanyes, com a iOS, i des del menú de cada compte s'hi pot desfer. ⚠️ Bloquejar no és silenciar amb més força: trenca el seguiment en totes dues direccions i desbloquejar no el refà, i per això al menú va en vermell i silenciar no.

Quan el servidor no contesta. Si hi ha un límit de peticions o cau la connexió, surt un avís de tres segons sota la barra i, mentre duri el límit, l'app deixa de sondejar fins a l'hora que el servidor ha dit: les peticions rebutjades també compten per al límit. Ho detecta un interceptor, així que cap petició se n'escapa.

⚠️ I n'és un de sol. Aquell avís i el de la pantalla on ets es dibuixen al mateix pam de pantalla, o sigui que la línia de temps calla quan la franja de dalt ja ho diu: repetir-ho només servia per tapar-ho. La resta d'errors —un 422, una resposta que no s'entén— els diu la pantalla, perquè aquells no els diu ningú més.

El teu servidor. Des del menú de l'avatar, just sobre de Configuració: qui és el servidor on tens el compte, amb la seva portada, la descripció que n'ha escrit qui l'administra —cada apartat a la seva fitxa—, els idiomes, la versió i el contacte; les seves normes numerades, una per fitxa; i les xifres d'ús, amb els comptes actius aquest mes i en sis mesos sobre el total de registrats, i els tuts publicats. ⚠️ Les xifres les dona NodeInfo, que és opcional al fedivers: un servidor que no les publiqui ho diu en comptes de deixar la pestanya en blanc, i la resta segueix servint.

Quant a Tuts. A Configuració: la versió que tens instal·lada, la llicència, l'enllaç al codi font i, a baix de tot, el de la política de privacitat.

Notificacions. Agrupades, com a la web de Mastodon: una fila diu «tres persones han impulsat el teu tut», no tres files iguals. El comptador de no llegides i el marcador de lectura els porta el servidor, i per tant llegir-les al mòbil les deixa llegides també a la web. Les denúncies que arriben a qui modera un servidor tenen fila pròpia —qui denuncia, quants tuts, de qui i per quin motiu— i porten a l'informe.

Les noves entren soles. Es demanen cada 30 segons, igual que a les línies de temps, i entren per damunt d'on llegeixes i sense moure't de lloc, d'una en una. Mentre no hi hagi push, aquest sondeig és l'únic senyal que n'hi ha de noves, i per això no en porta només el número: porta també la llista.

Descartar-les. Una notificació se'n va lliscant-la cap a qualsevol de les dues bandes, com a la safata d'Android, i mentre ets a temps surt un «Desfés». La paperera de la barra les esborra totes, amb confirmació: el servidor no en guarda cap còpia i el que se'n va, se'n va per a tots els clients alhora.

Notificacions push. Amb Tuts tancat, els avisos arriben igualment a la barra d'Android: qui t'ha mencionat, amb el seu avatar i el text que escriu el teu servidor. Va per UnifiedPush, i s'encén i s'apaga per compte a Configuració → Notificacions.

⚠️ Cal una app que faci de servei de push —ntfy i companyia—, i si no en tens cap, Tuts t'ho diu en comptes de callar. Si en tens més d'una, tries quina en fa la feina —i si cap no és la predeterminada del mòbil, Tuts t'ho diu i espera que la triïs—; i encara que només en tinguis una, la pantalla diu quina és, que és el primer que vols saber el dia que els avisos no arribin —perquè és aquella app la que has d'excloure de l'optimització de bateria—. És el preu de no dependre de Google: el teu servidor de Mastodon parla directament amb el servei que tu triïs, i no hi ha cap intermediari nostre pel mig. Qui vulgui pot fer-se'l seu.

⚠️⚠️ El contingut va xifrat d'extrem a extrem i el servei de push no el pot llegir. Les claus les genera el teu mòbil i no surten d'allà; pel servei hi passa un bloc xifrat. Mesurat contra un servidor propi el 05/09/2026: el que hi arriba és gmDqDVHw/nUQD0hLe7QvLQAAEABBBHARqcgMsHHD…, i qui el desxifra és el telèfon.

⚠️ Cada compte té la seva subscripció, perquè és com funciona l'API de Mastodon —una per testimoni d'accés—: les alertes que triïs en un no toquen les dels altres, ni les del mateix compte en un altre dispositiu.

⚠️ Quins avisos vols es tria per tipus —mencions, cites, favorits, impulsos, seguidors, enquestes, edicions i tuts nous—, i la tria viu al servidor, no al mòbil.

El menú d'un perfil. Copiar-ne l'adreça, obrir-lo al navegador, compartir-lo, mencionar-lo —en públic o en privat—, afegir-lo a una llista, activar-ne o desactivar-ne les notificacions, mostrar-ne o amagar-ne els impulsos, silenciar-lo i bloquejar-lo. ⚠️ Les opcions que depenen de la relació no es pinten fins que se sap quina és: dir «Silencia» a qui ja tens silenciat és pitjor que ensenyar un menú més curt mig segon. I les notificacions i els impulsos només surten si el segueixes, perquè al servidor són opcions del seguiment i es canvien pel mateix camí: oferir-les a qui no segueixes voldria dir començar-lo a seguir sense dir-ho.

Programar tuts. El rellotge de la capçalera del compositor, al costat de la visibilitat i al mateix lloc que a iOS, obre el selector de dia i hora; amb data posada el botó deixa de dir «Publica» i diu «Programa». El menú «···» → Programats en porta la llista, amb la data, el text i la visibilitat; tocant-ne la data se'n canvia l'hora de publicació, i la paperera el cancel·la. ⚠️ Només se'n pot canviar la data, no el text: l'API no ho admet.

⚠️ El mínim són més de cinc minuts, i una data passada no dona error: el tut es publica a l'instant. Ho diu el codi del servidor, no la documentació, i per això el selector no deixa triar dies passats i puja sola l'hora si es queda curta. Els altres dos límits —300 tuts programats i 25 el mateix dia— els diu el servidor.

Neteja d'enllaços. En publicar, editar o programar un tut, Tuts treu dels enllaços els paràmetres de seguiment coneguts —utm_*, fbclid, gclid i els de YouTube, Spotify, X, Instagram i Amazon— i obre els redireccionadors de Google per publicar l'adreça de debò. Es fa al telèfon, sense cap petició, i el que queda de l'adreça surt idèntic: no es torna a codificar res ni es reordenen els paràmetres. Quan n'ha netejat algun, ho diu amb una franja verda a dalt de la pantalla. Els enllaços escurçats (bit.ly, t.co…) no es poden netejar sense obrir-los, i el compositor ho avisa mentre escrius. La previsualització de l'enllaç també es demana amb l'adreça neta. S'apaga a Configuració → Privadesa; ve activada de fàbrica.

Esborranys. Tancant el compositor amb un tut a mig escriure, Tuts pregunta si el vols desar; la icona d'esborranys de la barra d'eines n'obre la llista, i tocant-ne un el tut torna tal com el vas deixar: el text, l'avís de contingut, la visibilitat, l'idioma, l'enquesta i el tut que responies o citaves. La pregunta surt tant amb la creu com amb el gest d'enrere, que és el més fàcil de fer sense voler.

⚠️ Són de cada compte i viuen només al mòbil. Mastodon no té cap camí d'API per desar un esborrany, així que no se sincronitzen ni amb la web ni amb Tuts d'iOS. Van a la base de dades lligats al seu compte: els que escriguis des d'un servidor no sortiran quan escriguis des d'un altre, i esborrar un compte se n'emporta els seus.

⚠️ Els adjunts no s'hi desen, i la llista diu quants n'hi havia. Les imatges i els àudios que tries els dona el selector del sistema amb un permís de lectura que caduca, i la còpia que en té el servidor no està pujada a cap tut: cap de les dues coses es pot prometre demà. Val més dir-ho abans de desar-lo que fer-ho descobrir en reprendre'l.

⚠️ Una data programada que ha quedat enrere no es recupera. Un esborrany desat amb «publica'l dimarts» i reobert dimecres portaria una data passada, i llavors el servidor no dona cap error: el publica a l'instant. Perdre la data es veu —el botó torna a dir «Publica»—; publicar sense voler, no.

⚠️ Editant un tut no se'n desa cap. Editar no és publicar: reprendre l'esborrany d'una edició des d'un compositor de tut nou publicaria una còpia del tut que ja hi és.

Col·leccions. Llistes públiques de comptes que recomanes, perquè altres hi descobreixin gent (Mastodon 4.6). Des del menú «···», les que has creat i aquelles on surts tu; des del perfil d'algú, les seves, i «Afegeix a col·leccions» si s'hi deixa afegir. Es creen en dos passos, com a Mastodon web —primer qui hi surt, després el nom, la descripció, el tema, l'idioma, si és pública i si és sensible—, i cada compte s'hi veu amb els seus seguidors, els tuts, la darrera activitat, l'enllaç verificat i la biografia. Si surts en la d'algú altre, «Treu-me». Les persones que hi afegeixes se n'assabenten: ho diu una notificació, que porta a la col·lecció. ⚠️ Només surten als servidors que en tenen: appy.cat, de moment, no.

Llistes. Des del menú «···»: crear-les, editar-les i esborrar-les amb el formulari sencer de Mastodon web —nom, quines respostes hi entren i si els seus membres desapareixen d'Inici—, veure la línia de temps de cadascuna i gestionar qui hi és. Des del perfil d'algú, «Afegeix a la llista» ensenya totes les teves llistes amb marca a les que ja el tenen, així que també se'n pot treure.

⚠️ Per afegir algú a una llista l'has de seguir, i ho diu el servidor —no és cosa de Tuts—: per això la cerca de membres només troba comptes que segueixes i l'opció del perfil és grisa amb qui no. ⚠️ No confondre-les amb les llistes d'etiquetes, que són una altra cosa: aquelles viuen al mòbil i agrupen etiquetes; aquestes viuen al servidor i agrupen comptes.

Filtres de contingut. El formulari sencer de Mastodon web, camp per camp: títol, quan expira, en quins dels cinc contextos s'aplica, què hi fa —avisar, difuminar els adjunts o amagar— i les paraules clau amb «paraula sencera» per a cadascuna. Es creen, s'editen i s'esborren, i com que viuen al servidor, el que facis aquí es veu igual a Mastodon web i a la versió d'iOS.

⚠️ Els filtres els aplica el servidor, no Tuts. Cada tut arriba dient quin filtre l'ha enganxat, ja resolt per al context de la petició, i l'app només l'obeeix: amaga, tapa amb un avís que diu el títol del filtre i un «Mostra'l igualment», o difumina els adjunts. Refer-se les coincidències al client —que és el que fa la versió d'iOS— vol dir que només funcioni el tipus «amaga»: allà un filtre que avisa no fa res.

⚠️ La llista es torna a demanar en tornar a l'app i estirant-la cap avall, perquè un filtre es pot canviar des de la web mentre la tens oberta. Sincronia en viu no n'hi ha: caldria el flux de streaming.

Peticions de seguiment. Qui té el perfil amb candau les rep com una notificació més, i des d'allà mateix s'accepten o es rebutgen sense anar enlloc. El menú «···» en porta la llista sencera —les que segueixen vives encara que la notificació ja s'hagi descartat o hagi quedat enrere—, i s'hi pot resoldre cadascuna des de la seva fila. ⚠️ Amb un grup de més d'una persona no hi ha botons a la notificació: els avatars que hi envia el servidor són una mostra, i acceptar «la sol·licitud» d'un grup de cinc voldria dir triar-ne una a l'atzar; per això allà hi ha el botó que obre la llista.

Amb què s'ha publicat un tut. Dins d'una conversa, sota el tut destacat: «Via Tuts/Android», i el nom obre el web de l'aplicació si el servidor en dona un. Només hi és quan el servidor ho diu, que és en els comptes locals que ho permeten i sempre en els teus.

Cerca i tendències. Quatre pestanyes amb els noms de Mastodon web —Tuts, Etiquetes, Persones i Enllaços— i, amb el camp buit, cadascuna ensenya què es cou al servidor: els tuts del moment, les etiquetes en tendència amb la corba d'ús dels últims dies, els comptes suggerits amb el botó de seguir, i els enllaços amb el seu autor i quantes publicacions en parlen. Els resultats són les mateixes cel·les que a les línies de temps, amb totes les accions. Les tendències es tornen a demanar en tornar a l'app si ja han passat cinc minuts, que és cada quan les recalcula el servidor, i el títol de la secció diu a quina hora es van portar les que estàs veient; mentre baixen no desapareix res, i si la xarxa falla es conserva el que hi havia.

⚠️ La cerca de tuts depèn del servidor: Mastodon només la fa si té Elasticsearch instal·lat i, encara així, només indexa els teus tuts, els que has marcat o impulsat i aquells on t'han mencionat —la pantalla ho explica en comptes de deixar un buit sec—. I els enllaços no es poden cercar: l'API només cerca comptes, etiquetes i tuts, així que aquella pestanya sempre ensenya les tendències.

Captures de pantalla

(pròximament)

Requisits

  • Android Studio 2026.1 o superior
  • Android 12 (API 31) o superior al dispositiu
  • Compte a qualsevol instància de Mastodon

No cal cap JDK del sistema: es fa servir el JBR que ve amb Android Studio.

Instal·lació

  1. Clona el repositori:
    git clone https://codeberg.org/spla/Tuts-android.git
    
  2. Obre la carpeta amb Android Studio i espera que acabi la sincronització de Gradle
  3. Tria un dispositiu o un emulador
  4. Compila i executa (⌃R)

També es pot fer des del terminal, amb el wrapper de Gradle:

export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home"
./gradlew :app:installDebug

No cal cap dependència externa més enllà de les que resol Gradle.

La compilació de depuració s'instal·la com una app a part, «Tuts debug» (cat.spla.tuts.debug), i conviu amb la versió publicada sense tocar-ne els comptes. Comença sense cap compte connectat.

Per generar l'APK signat que es reparteix als provadors, vegeu DISTRIBUCIO.md. Els passos per publicar-la a Google Play són a PLAY_STORE.md.

Comprovar un APK baixat

Tots els APK de Tuts van signats amb la mateixa clau. L'empremta SHA-256 del seu certificat és sempre aquesta:

DB:9E:95:13:08:34:E0:A4:B0:2E:75:FE:D5:22:F3:A4:72:4F:5D:BA:3E:8A:64:1E:32:4A:58:64:D5:D8:7C:3A

Si la d'un APK no hi coincideix, aquell APK no l'ha signat l'autor, l'hagis baixat d'on l'hagis baixat. Es comprova amb apksigner, de les build-tools de l'SDK d'Android, o amb qualsevol app que verifiqui signatures:

apksigner verify --print-certs Tuts.apk

Aquesta empremta no canvia d'una versió a l'altra. El que sí que canvia és el SHA-256 del fitxer: cada lliurament el porta al seu costat, en un fitxer .sha256, i serveix per comprovar que l'APK ha arribat sencer i és exactament el que es va publicar:

shasum -a 256 Tuts.apk

Funcionalitats

La llista marca l'objectiu del port: paritat funcional amb la versió d'iOS.

Línia de temps

  • Inici, local i federada
  • Una llista al lloc de Local o de Federada, per compte
  • Tuts amb text, imatges, vídeo, GIF i àudio
  • Converses, amb fils aniuats
  • Enquestes: veure-les i votar-hi
  • Tuts llargs truncats amb botó «Llegir més»
  • Cites de tuts (Mastodon 4.5+), amb el tut citat a dins de la cel·la
  • Històric d'edicions
  • Amb quina aplicació s'ha publicat un tut, dins de la conversa
  • Impuls, favorit i resposta
  • Enllaços clicables, escurçats com a la web
  • Mencions i avatars que obren el perfil
  • Visibilitat de cada tut a la vista (menció privada, seguidors, no llistat)
  • Recuperació del punt de lectura, per identificador de tut
  • Menú per tut: fixar, esborrar, marcadors, traduir, compartir i copiar l'enllaç
  • Bloquejar, silenciar i denunciar usuaris
  • Qui cita un tut, des del comptador de cites de la cel·la
  • Targeta dels enllaços, amb la miniatura i les metadades del servidor
  • Buit marcat amb «Carrega el que falta» en tornar després d'unes hores
  • Línia de temps d'una etiqueta, amb seguir i deixar de seguir
  • Etiquetes: tendència, llistes, seguint i destacades
  • Un tut esborrat al servidor ho diu i marxa de la llista
  • Streaming per WebSocket

⚠️ Sense streaming, un tut esborrat des d'un altre lloc es queda a la llista fins que alguna cosa hi topa. Quan hi topa —obrint-ne la conversa, impulsant-lo, marcant-lo o demanant qui l'ha impulsat—, Tuts ho diu amb una sola frase, «Aquest tut ja no existeix», i se n'oblida: el treu de la memòria cau i de totes les llistes obertes alhora. ⚠️ I el botó de respondre comprova el tut abans d'obrir el compositor: escriure cinc-cents caràcters per trobar l'error en publicar era el pitjor moment possible per assabentar-se'n. Amb qualsevol error que no sigui un 404 —xarxa caiguda, un 500— el compositor s'obre igualment: no saber si el tut hi és no és saber que no hi és.

Notificacions

  • Notificacions agrupades (API v2, Mastodon 4.3+)
  • Comptador de no llegides
  • Les noves entren soles cada 30 s, empenyent i sense moure't de lloc
  • Descartar-ne una lliscant-la, amb «Desfés», i esborrar-les totes
  • Política de filtratge del servidor, per compte, amb els seus sis criteris
  • Safata del que la política ha retingut, desplegable, per acceptar o descartar
  • Push per UnifiedPush, amb xifratge d'extrem a extrem i sense relay
  • Encendre'l i apagar-lo per compte, i triar quins avisos vols
  • Triar quin servei de push reparteix els avisos, si n'hi ha més d'un
  • Silenciar la conversa d'un fil on has participat
  • Filtrar la llista per tipus de notificació
  • Obrir el perfil de qualsevol persona d'un grup de notificacions
  • Denúncies (admin.report), per als comptes que moderen el servidor
  • T'han afegit a una col·lecció, o n'han editat una on surts
  • Peticions de seguiment: llista de pendents i acceptar o rebutjar
  • Accions ràpides des de la notificació

Publicar

  • Editor de tuts
  • Respostes
  • Adjuntar fins a quatre imatges amb text alternatiu
  • Visibilitat (públic, no llistat, privat, directe)
  • Avís de contingut
  • Emojis personalitzats del servidor, amb selector amb cerca i categories
  • Citar un tut, amb la cita a dins del compositor
  • Editar tuts propis, amb el text original i no l'HTML
  • Esborranys locals, per compte
  • Adjuntar vídeo i àudio, del dispositiu o gravat amb el micròfon
  • Enquestes, amb durada i resposta múltiple
  • Declarar l'idioma del tut, amb selector d'idiomes
  • Autocompletar mencions mentre escrius
  • Previsualització de l'enllaç, amb les metadades Open Graph
  • Programar tuts, i la llista dels programats
  • Neteja dels paràmetres de seguiment dels enllaços, sense cap petició

Cerca

  • Cerca de tuts, comptes i etiquetes
  • Tendències (tuts, etiquetes amb gràfica, i enllaços) i comptes suggerits
  • Seguir un compte suggerit sense sortir de la llista
  • Historial de cerques recents

Perfil

  • Perfils d'altres usuaris, amb tuts, respostes i impulsos
  • Perfil propi, a la pestanya Perfil
  • Seguir i deixar de seguir, amb sol·licituds pendents
  • Camps personalitzats amb verificació i data d'alta
  • Llistes de seguidors i de seguits
  • Silenciar, i triar notificacions i impulsos, des de la llista de comptes
  • Editar perfil: nom, biografia, camps, avatar i bàner
  • Menú … del perfil: silenciar, bloquejar, mencionar, compartir i afegir a una llista
  • Fixar i esborrar tuts propis
  • Llistes de comptes (qui ha marcat com a favorit, qui ha impulsat)
  • Històric d'edicions d'un tut

Configuració

  • Esborra la memòria cau, amb el desglossament d'imatges i dades
  • Obrir els enllaços dins de l'app o al navegador del sistema
  • Tema clar, fosc o igual que el sistema, amb color dinàmic de Material You
  • Color d'accent, amb el color dinàmic de Material You per defecte
  • Mida del text dels tuts
  • Reproduir els vídeos i els GIF automàticament
  • Amagar les barres flotants mentre es desplaça la llista
  • Notificacions: política de filtratge del servidor, avís a la pestanya i safata del que ha filtrat
  • Majúscula automàtica als camps de text
  • Neteja d'enllaços en publicar
  • Quant a Tuts

Altres

  • Multicompte amb canvi ràpid entre comptes
  • Botó «···» flotant a les quatre pestanyes, amb el seu menú
  • Llista de favorits, paginada
  • Llista de marcadors, paginada, amb el marcador tocable a la cel·la
  • Llistes: crear-les, editar-les, la seva línia de temps i qui hi és
  • Col·leccions de comptes: crear-les, editar-les, qui hi surt, i sortir de les d'altri
  • Filtres de contingut: crear-los, editar-los, esborrar-los i aplicar-los
  • Tuts programats: la llista, canviar-ne la data i cancel·lar-los
  • Informació del servidor: descripció, normes i xifres d'ús (NodeInfo)
  • Crear un compte nou des de la mateixa pantalla d'inici de sessió
  • Esborrar el compte al servidor, des del menú de l'avatar
  • Avís de límit de peticions i de xarxa caiguda, en un sol lloc
  • Traduir tuts, si el servidor ho permet
  • Visor d'imatges amb gest de pinça, cap al punt dels dits
  • Reproductor de vídeo i GIF integrat (Media3/ExoPlayer), a la cel·la i a pantalla completa
  • Emojis personalitzats del servidor, al contingut, als noms i als perfils

L'app de Wear OS, equivalent a la d'Apple Watch, queda per a una fase molt posterior.

Arquitectura

  • Patró: MVVM estricta amb Jetpack Compose i StateFlow
  • Xarxa: OkHttp i kotlinx.serialization, amb crida directa a l'API REST de Mastodon. Sense Retrofit: els casos rars de descodificació de l'API es gestionen millor amb accés a la resposta crua
  • Autenticació: OAuth 2.0 amb Chrome Custom Tabs
  • Secrets: rere una interfície pròpia, amb DataStore, Tink i l'Android Keystore
  • Caché: Room per a la línia de temps local
  • Push: UnifiedPush. Sense relay propi i sense Google: el servidor Mastodon parla directament amb el distribuïdor que l'usuari tingui, i el desxifrat es fa al dispositiu. El distribuïdor FCM incrustat queda per quan calgui Play Store
  • Navegació: Navigation 3. Les converses són pantalles, no fulls modals

Multicompte des del primer dia

No és un afegit posterior. L'identificador únic d'un compte és "{instancia}|{accountId}", cada secret va prefixat pel compte al qual pertany, i cap consulta a la caché es fa sense filtrar per compte i per tipus de línia de temps.

Estructura del projecte

app/src/main/java/cat/spla/tuts/
├── ActivitatPrincipal.kt        # Activitat única, amb la pila de navegació
├── funcionalitats/
│   ├── arrel/                   # Estat d'arrel, menú de comptes i barra de pestanyes
│   ├── autenticacio/            # OAuth 2.0 amb PKCE
│   ├── adjunts/                 # Visor d'imatges i vídeo, reproductor d'àudio
│   ├── cerca/                   # Cerca i tendències
│   ├── colleccions/             # Col·leccions de comptes, el seu editor i el seu detall
│   ├── conversa/                # Fil d'un tut
│   ├── configuracio/            # Preferències i «Quant a Tuts»
│   ├── etiqueta/                # Línia de temps d'una etiqueta i les seves quatre pestanyes
│   ├── filtres/                 # Filtres de contingut del servidor
│   ├── historic/                # Versions d'un tut editat
│   ├── llistadetuts/            # Favorits, marcadors i qui cita un tut
│   ├── llistes/                 # Llistes del servidor i els seus membres
│   ├── notificacions/           # Notificacions agrupades, política i safata del retingut
│   ├── perfil/                  # Perfil d'un compte
│   ├── programats/              # Tuts programats
│   ├── publicar/                # Compositor
│   ├── servidor/                # Fitxa del servidor: descripció, normes i xifres
│   └── timeline/                # Inici, Local, Federada, i les llistes que hi posis
├── interficie/
│   ├── efectes/                 # Fons difuminat
│   ├── format/                  # Temps relatiu viu i contingut HTML amb enllaços
│   ├── navegacio/               # Destinacions de Navigation 3 i obridor d'enllaços
│   └── tema/                    # Tema, colors i tipografia
└── sistema/
    ├── comptes/                 # GestorComptes i neteja en esborrar
    ├── dades/                   # Room, GestorCache i les llistes d'etiquetes
    ├── esdeveniments/           # BusEsdeveniments
    ├── injeccio/                # Mòduls de Hilt
    ├── preferencies/            # Tema, accent, mida del text i la resta de Configuració
    ├── secrets/                 # GestorSecrets
    └── xarxa/                   # ClientAPI, interceptors i models

Convenció de noms

El codi va tot en català, i els noms segueixen l'ordre del català, amb el nucli al davant: PantallaTimeline, ViewModelTimeline, GestorComptes, CellaTut. És l'invers de la convenció anglesa d'Android (TimelineViewModel), i és deliberat.

API de Mastodon

Es fa servir l'API REST de Mastodon directament, sense cap capa d'abstracció.

Ja implementats:

  • POST /api/v1/apps, /oauth/authorize, /oauth/token, /oauth/revoke — autenticació

  • POST /api/v1/accounts — crear un compte. Demana un testimoni de l'aplicació (client_credentials), i el que retorna no serveix fins que es confirma el correu

  • GET /api/v1/emails/check_confirmation i POST /api/v1/emails/confirmations — si el correu ja està confirmat, i tornar-lo a enviar (opcionalment a una altra adreça)

  • GET /api/v1/instance/terms_of_service — els termes de servei, que van per un camí propi i no dins de /api/v2/instance

  • GET /api/v1/timelines/{home,public} — línies de temps

  • GET /api/v1/statuses/:id i /context — un tut i el seu fil

  • POST /api/v1/statuses — publicar, amb Idempotency-Key i quoted_status_id per a les cites

  • GET /api/v1/statuses/:id/source i PUT /api/v1/statuses/:id — editar. El text bo és el de source: el content és l'HTML que genera el servidor, i editar-lo el degradaria a cada desada. La visibilitat no es pot canviar, i el cos va en JSON: media_attributes és una llista d'objectes i en formulari el servidor respon 500; ⚠️ poll substitueix com els adjunts, i una edició que no la porta esborra l'enquesta

  • GET /api/v1/statuses/:id/history — totes les versions d'un tut editat

  • POST /api/v1/statuses/:id/{favourite,unfavourite,reblog,unreblog,bookmark,unbookmark} — accions

  • POST /api/v1/statuses/:id/{pin,unpin,mute,unmute} i DELETE /api/v1/statuses/:id — fixar, silenciar el fil i esborrar

  • POST /api/v1/statuses/:id/translate — traducció, quan la instància la té activada

  • GET /api/v1/{favourites,bookmarks} — favorits i marcadors, paginats només per la capçalera Link: aquí el cursor és l'identificador del favorit o del marcador, no el del tut, i no surt enlloc de la resposta

  • POST /api/v2/media i PUT /api/v1/media/:id — adjunts i text alternatiu. En un tut ja publicat el text alternatiu viatja amb media_attributes del PUT del tut: aquell altre camí només val abans de publicar-lo

  • GET /api/v1/media/:id — si el servidor ja ha acabat de processar un adjunt. Un àudio, un vídeo o un GIF tornen 202 en pujar-los i el servidor els transcodifica després; ⚠️ fins que no ha acabat, el tut no es pot publicar —respon 422, «Cannot attach files that have not finished processing»—, i per això l'adjunt diu «Pujant…» fins aleshores. Es pregunta amb el ritme de Mastodon web i sense límit de temps

  • GET /api/v1/statuses/:id/quotes — els tuts que en citen un (Mastodon 4.5+). Pagina només per la capçalera Link, i la llista pot ser més curta que quotes_count: el comptador és un agregat i la llista la filtra el servidor per visibilitat

  • GET /api/v1/custom_emojis — els emojis personalitzats del servidor, per pintar-los al text i per al selector del compositor

  • GET /api/v2/notifications — notificacions agrupades

  • POST /api/v2/notifications/:group_key/dismiss i POST /api/v1/notifications/clear — descartar-ne una o esborrar-les totes. Cap de les dues deixa paperera al servidor

  • GET /api/v1/notifications/unread_count i POST /api/v1/markers — comptador i marcador de lectura

  • GET, PATCH /api/v2/notifications/policy — la política de filtratge, amb els seus sis criteris. ⚠️ for_bots només existeix des de Mastodon 4.6: tots sis es descodifiquen com a nul·lables, i nul vol dir «aquest servidor no ho ofereix»

  • GET /api/v1/notifications/requests i POST /api/v1/notifications/requests/:id/{accept,dismiss} — el que la política ha retingut. Pagina per la capçalera Link, i les dues accions responen un cos buit. ⚠️ Acceptar no entrega unes notificacions: crea un permís permanent per a aquell compte que l'API no pot desfer

  • GET /api/v1/notifications?account_id=X — què s'ha retingut d'un compte, sense haver-ho d'acceptar. És l'únic camí de l'app que fa servir la v1 de notificacions: aquí no cal agrupar res i la v1 les torna planes

  • GET /api/v2/instance — límits del servidor i si pot traduir. Es demana una sola vegada per compte i es guarda en memòria del procés

  • GET /api/v1/preferences — la preferència reading:expand:media de cada compte, desada per compte

  • GET /api/v1/accounts/:id i /statuses — perfils i els seus tuts; amb only_media=true, el seu Contingut, paginat per la capçalera Link

  • GET /api/v1/accounts/verify_credentials i PATCH /api/v1/accounts/update_credentials — el teu perfil i editar-lo. El text bo és el de source, que és el que vas escriure, i no el note, que és l'HTML; ⚠️ fields_attributes substitueix la llista sencera de camps, i per això s'envien sempre els quatre

  • GET /api/v1/accounts/search — comptes per a l'autocompletat de mencions. És el camí fet per a això, i no /api/v2/search; resolve només es demana quan la consulta ja és una adreça sencera, perquè amb ell el servidor surt a fer un WebFinger abans de respondre

  • POST /api/v1/polls/:id/votes i GET /api/v1/polls/:id — votar en una enquesta i tornar-la a demanar. Retornen una enquesta, no un tut; aquí sí que es pot rellegir just després d'actuar, perquè els vots no passen per cap treballador asíncron

  • GET /api/v1/accounts/relationships i POST /accounts/:id/{follow,unfollow} — seguiment

  • GET /api/v1/accounts/:id/{following,followers} i GET /api/v1/statuses/:id/{favourited_by,reblogged_by} — llistes de comptes, totes paginades per la capçalera Link

  • GET /api/v1/{mutes,blocks} i POST /api/v1/accounts/:id/{block,unblock} — silenciats i bloquejats. Paginen també per la capçalera Link: el cursor és l'ID intern del silenci o del bloqueig, no el del compte

  • POST /api/v1/accounts/:id/{mute,unmute} i /follow amb notify i reblogs — silenci, notificacions i impulsos per compte

  • POST /api/v1/reports — denunciar. Es denuncia un compte i els tuts hi van com a context; amb rule_ids la categoria passa a ser violation digui el que digui, i sense normes amb aquella categoria el servidor respon 422

  • GET /api/v1/timelines/tag/:nom — línia de temps d'una etiqueta, amb any[], all[], none[], local i only_media per a les llistes d'etiquetes

  • GET /api/v1/tags/:nom i POST /tags/:nom/{follow,unfollow} — seguir una etiqueta

  • GET /api/v1/followed_tags — les etiquetes que segueixes. Pagina només per la capçalera Link

  • GET, POST /api/v1/featured_tags i DELETE /api/v1/featured_tags/:id — les destacades al perfil. ⚠️ L'identificador de l'esborrat és el de la fila, no el nom de l'etiqueta, i statuses_count arriba com a cadena o com a número

  • GET /api/v2/search — cerca de comptes, etiquetes i tuts. offset i resolve només funcionen autenticat, i offset només si s'ha dit el type

  • GET /api/v1/trends/{tags,statuses,links} i GET /api/v2/suggestions — tendències i comptes suggerits. Es recalculen al servidor cada 5 minuts, i un servidor pot tenir-les desactivades: llavors la secció no es pinta

  • GET /api/v1/follow_requests i POST /api/v1/follow_requests/:id/{authorize,reject} — peticions de seguiment. Pagina per la capçalera Link —el cursor és l'ID de la petició, que no surt enlloc de la resposta— i les accions demanen l'ID del compte, no el de la petició

  • GET, POST /api/v1/lists, PUT i DELETE /api/v1/lists/:id — llistes del servidor. GET, POST i DELETE /api/v1/lists/:id/accounts en gestionen els membres, i ⚠️ per afegir-hi algú l'has de seguir: ho diu el servidor

  • GET /api/v1/accounts/:id/lists — a quines llistes ja hi és un compte, que és el que deixa treure'l des del seu perfil i no només afegir-l'hi

  • GET /api/v1/timelines/list/:id — la línia de temps d'una llista, paginada per la capçalera Link

  • GET /api/v1/accounts/:id/collections i GET /api/v1/accounts/:id/in_collections — les col·leccions d'un compte i aquelles on surts tu. GET, POST, PATCH i DELETE /api/v1/collections/:id, i POST i DELETE /api/v1/collections/:id/items/:id per als comptes, d'un en un. ⚠️ Una col·lecció nova s'envia sencera en un sol POST, comptes inclosos; un compte d'un altre servidor hi entra pendent fins que el seu servidor respon; i el 422 d'aquest camí porta l'error niat ({"error": {"error": …}}). Si surts de la d'algú altre (POST …/items/:id/revoke), no t'hi pot tornar a afegir durant 24 hores. Només s'ofereixen si el servidor declara API 10 a api_versions

  • GET, POST /api/v2/filters, PUT i DELETE /api/v2/filters/:id — filtres de contingut. El cos va en JSON, perquè keywords_attributes és una llista d'objectes; ⚠️ al PUT, una paraula que no s'anomena es queda com estava: per esborrar-la cal enviar-la amb el seu id i _destroy. Els filtres els aplica el servidor: cada tut arriba amb filtered ja resolt per al context de la petició

  • GET /api/v1/scheduled_statuses, PUT i DELETE /api/v1/scheduled_statuses/:id — tuts programats. Es creen pel mateix camí que publicar, amb scheduled_at, però ⚠️ la resposta canvia de tipus; i del que ja està programat només se'n pot canviar la data

  • GET /api/v1/instance/extended_description i GET /nodeinfo/2.0.json — la descripció llarga del servidor i les seves xifres d'ús. ⚠️ NodeInfo és opcional al fedivers: un servidor que no el publiqui ho diu, i la resta de la pantalla segueix servint

  • GET /api/v1/accounts/:id/featured_tags — les etiquetes destacades d'un perfil

  • POST, GET, PUT i DELETE /api/v1/push/subscription — la subscripció de push, una per testimoni d'accés: crear-ne una esborra l'anterior d'aquell testimoni, i per això només es crea quan el distribuïdor dona una adreça nova. ⚠️⚠️ subscription[standard] s'envia sempre cert i sense això el push no serviria de res: Mastodon xifra amb el mètode antic (aesgcm) si no se li demana l'estàndard (aes128gcm), i és l'estàndard l'únic que el client sap desxifrar. El paràmetre és de Mastodon 4.4 i un servidor més vell l'ignora, així que es mira el standard de la resposta i es diu clar quan no hi arriba

  • GET /api/v2/instance → configuration.vapid.public_key — la clau VAPID del servidor, que el distribuïdor vol abans de donar cap adreça. ⚠️ No arriba igual de tots: uns la donen amb farciment i altres sense

Previstos:

  • Streaming per WebSocket

Diferències amb la versió d'iOS

iOS Android
SwiftUI Jetpack Compose
SwiftData Room
Keychain DataStore + Tink + Android Keystore
APNs amb relay propi (toot-relay) UnifiedPush, sense relay
Fulls modals per a les converses Navegació
Disseny Liquid Glass Material 3
watchOS Wear OS (fase posterior)

Llicència

AGPL-3.0

Autor

spla