Author SHA1 Message Date
ShanaiaBot a82dcc9c1b chore: bump version to 1.3.3+159 [ci skip] 2026-08-31 14:38:18 +02:00
FreeTLab 3449e2cb79 fix: corregir ecualizador desincronizado, musica local en Android Auto y bloqueo del paywall
Build & Deploy PluriWave / Análisis de código (push) Successful in 27s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 3m23s
Tres fallos reportados en uso real, con sus causas raiz verificadas en codigo.

1. Ecualizador: el estado no tenia dueño unico

El handler arrancaba con `_ecualizadorActivo = true` a fuego. El valor
persistido solo llegaba por EstadoEcualizador.cargarPersistido(), alcanzable
unicamente desde el arbol de widgets, que un arranque headless de Android Auto
nunca construye. Resultado: el coche reproducia con el EQ forzado a ON mientras
disco e interfaz decian OFF.

Ahora registrarHandler siembra el flag desde disco en todos los motores y
setEcualizadorActivo persiste por su cuenta, asi que un toggle desde el coche o
la notificacion sobrevive sin EstadoEcualizador. _resincronizarConHandler pasa
a ser adopcion pura de interfaz.

Ademas mapearGananciaNativa enviaba 0 dB al punto MEDIO del rango nativo. Con
un getBandLevelRange() asimetrico, un preset plano metia varios dB de boost
real: la causa del "suena muy alto con el boton apagado". Reescrito para
escalar cada lado contra su propio extremo, de modo que 0 dB es siempre 0.

El dispatch de customAction no tenia ningun test. Se extrae decidirToggleEq y
se cubre contra el handler real. El efecto nativo se re-asierta al reactivarse
el reproductor, porque AudioEffect.setEnabled de just_audio es un no-op
mientras la plataforma esta desacoplada.

2. Musica Local no aparecia en el arbol de Android Auto

hayCarpetaConfigurada() consultaba MethodChannel('pluriwave/file_actions'),
registrado solo en MainActivity.configureFlutterEngine. Sin Activity no hay
handler, invokeMethod lanza MissingPluginException y el catch la confundia con
"permiso revocado", omitiendo el nodo. No dependia del entitlement.

La logica SAF sale a packages/pluriwave_file_actions, un paquete plugin local.
El motor headless que crea audio_service ejecuta GeneratedPluginRegistrant en
su constructor, asi que el canal queda registrado en ambos motores. Repuntar el
manifest a una subclase de AudioService no era viable: AudioServicePlugin
enlaza por ComponentName explicito y la app perderia el audio.

EstadoCarpetaLocal de tres valores separa "sin carpeta" de "canal no
disponible"; la raiz decide por la URI persistida y el subarbol muestra un item
explicativo en vez de una carpeta vacia. La invalidacion del arbol cacheado se
dispara al reanudar con el coche ya suscrito; el guardia anterior miraba
View.maybeOf, que bajo runApp siempre existe, por lo que se gastaba en el
arranque headless y no volvia a dispararse.

3. El paywall bloqueaba las compras

restorePurchases() de in_app_purchase_android emite siempre, y con lista vacia
si no hay nada que restaurar. El `if (compras.isEmpty) return;` se la tragaba,
noEncontrada nunca se emitia y la rama que limpia _compraEnCurso estaba muerta
en produccion. Como comprar y restaurar comparten ese flag, un usuario sin
compras que pulsaba restaurar se quedaba sin poder comprar.

Suite completa: 1366 pasan, 2 omitidos. 17 tests nuevos, todos nacidos rojos y
verificados por mutacion. flutter analyze mantiene los 5 avisos preexistentes.
2026-08-31 14:34:49 +02:00
ShanaiaBot 10bb017f4c chore: bump version to 1.3.3+158 [ci skip] 2026-08-29 11:00:00 +02:00
FreeTLab a99df5d055 ci: let PRO own the version name and split artifacts by branch [version set]
Build & Deploy PluriWave / Análisis de código (push) Successful in 28s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 2m44s
Three related fixes to the release plumbing:

- Only PRO bumps the semver now. main was bumping its patch on every push,
  so it raced permanently ahead of the branch that actually ships (main hit
  1.3.3 while PRO sat at 1.3.0), buried release artifacts under a dev branch
  on the portal, and made every main<->PRO merge conflict on pubspec.yaml.
  The build number still advances on every branch, since Play requires it to
  be monotonic across the whole app.

- The [version set] marker is now searched across every commit the push
  introduced, not just the tip. A plain 'git pull' inserts a merge commit
  with no marker, which silently dropped a pinned name and turned 1.3.0
  into 1.3.1.

- Artifacts land in a per-branch folder so the portal stops interleaving
  development and release builds.
2026-08-29 10:59:20 +02:00
ShanaiaBot ab66f4985c chore: bump version to 1.3.3+157 [ci skip] 2026-08-28 23:53:24 +02:00
FreeTLab d61c62540a ci: name build artifacts by branch and version code [version set]
Build & Deploy PluriWave / Análisis de código (push) Successful in 23s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 1m57s
Every build of a given semver was published as `pluriwave-v1.3.0.aab` into
the same folder, so main and PRO overwrote each other and three different
builds became indistinguishable once downloaded — the browser saves them as
"(1)", "(2)" and the version code is only visible by unzipping the bundle.

That cost two rejected uploads to Play Console for reusing a version code.
Artifacts are now `pluriwave-<branch>-v<semver>+<build>.<ext>", which
identifies itself weeks later and outside this repo.
2026-08-28 23:52:41 +02:00
ShanaiaBot 25d5841d57 chore: bump version to 1.3.3+156 [ci skip] 2026-08-28 23:38:07 +02:00
FreeTLab 663fed5f41 merge: alarm-import recovery, dismissible paywall and complete config export
Build & Deploy PluriWave / Análisis de código (push) Successful in 26s
Build & Deploy PluriWave / Build APK + AAB release (push) Failing after 2m41s
Three fixes that all came out of on-device testing:
- e57f7bb restores alarms after a backup import. The import wrote the JSON
  to prefs but EstadoAlarmas never re-read it, so imported alarms were
  invisible, were overwritten by the next edit, and were never scheduled
  natively — they would not have rung.
- a2bed18 makes the premium sheet dismissible (close button, 'not now',
  back gesture) and replaces the bare title with the five concrete things
  the purchase unlocks. A purchase sheet with no way out is a Play policy
  risk, not just bad UX.
- 4ca2813 closes the last export gap: the equalizer on/off toggle now
  travels with the backup (schema v4, additive; an old backup without the
  field leaves the current toggle untouched).
2026-08-28 23:35:37 +02:00
2 changed files with 33 additions and 9 deletions
+32 -8
View File
@@ -68,7 +68,18 @@ jobs:
echo "keyPassword=$KEYSTORE_PASSWORD" >> android/key.properties
echo "✅ Keystore configurado"
- name: Bump versión patch + commit
# PRO owns the version NAME; every branch advances the build NUMBER.
#
# Previously main also bumped its patch on every push, so main's semver
# raced permanently ahead of PRO's (main hit 1.3.3 while the branch that
# actually ships sat at 1.3.0). That buried the release artifacts under a
# dev branch on builds.freetimelab.es, which sorts by version, and made
# every main<->PRO merge conflict on pubspec.yaml.
#
# The build number still advances everywhere: Google Play requires it to
# be monotonic across the whole app, so two branches must never mint the
# same code.
- name: Bump versión + commit
run: |
BRANCH="${CURRENT_REF#refs/heads/}"
git config user.name "ShanaiaBot"
@@ -77,12 +88,20 @@ jobs:
SEMVER=$(echo "$CURRENT" | cut -d'+' -f1)
BUILD=$(echo "$CURRENT" | cut -d'+' -f2)
NEW_BUILD=$((BUILD + 1))
# If the triggering commit explicitly pins the version name via the
# [version set] marker, ship that semver as-is (a milestone like 1.0.0
# or a major/minor jump the automatic patch bump cannot reach) and only
# advance the build number, which Google Play requires to stay
# monotonic. Otherwise keep the default automatic patch+build bump.
if git log -1 --pretty=%B | grep -q '\[version set\]'; then
# Look for [version set] across EVERY commit this push introduced,
# not just the tip. `git pull` inserts an auto-generated merge commit
# whose message carries no marker, which silently discarded a pinned
# version name and bumped 1.3.0 to 1.3.1 behind our backs.
RANGO="${{ gitea.event.before }}..${{ gitea.sha }}"
if git log "$RANGO" --pretty=%B 2>/dev/null | grep -q '\[version set\]'; then
MARCADOR="si"
else
MARCADOR="no"
fi
if [ "$BRANCH" != "PRO" ] || [ "$MARCADOR" = "si" ]; then
# Non-release branches never touch the name; PRO respects a pin.
NEW_VERSION="${SEMVER}+${NEW_BUILD}"
else
MAJOR=$(echo "$SEMVER" | cut -d. -f1)
@@ -91,6 +110,8 @@ jobs:
NEW_PATCH=$((PATCH + 1))
NEW_VERSION="${MAJOR}.${MINOR}.${NEW_PATCH}+${NEW_BUILD}"
fi
echo "rama=${BRANCH} marcador=${MARCADOR} ${CURRENT} -> ${NEW_VERSION}"
sed -i '' "s/^version: .*/version: ${NEW_VERSION}/" pubspec.yaml
git add pubspec.yaml
git commit -m "chore: bump version to ${NEW_VERSION} [ci skip]"
@@ -255,7 +276,10 @@ jobs:
ETIQUETA="${BRANCH}-v${VERSION}+${BUILD_NUMBER}"
APK_NOMBRE="pluriwave-${ETIQUETA}.apk"
AAB_NOMBRE="pluriwave-${ETIQUETA}.aab"
DESTINO="/opt/ftl-builds/builds/pluriwave/v${VERSION}"
# Carpeta por rama: main y PRO ya no se mezclan en el portal, que
# ordena por número de versión y por tanto mostraba el build de
# desarrollo como "última versión" por delante del de release.
DESTINO="/opt/ftl-builds/builds/pluriwave/${BRANCH}/v${VERSION}"
SSH_KEY="/Users/freetlab/.openclaw/workspace/.secure/zimaboard_ed25519"
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no ShanaiaBot@192.168.0.33 "mkdir -p ${DESTINO}"
+1 -1
View File
@@ -1,7 +1,7 @@
name: pluriwave
description: "Radio mundial con ecualizador, reconocimiento de canciones y UI premium"
publish_to: 'none'
version: 1.3.1+157
version: 1.3.3+159
environment:
sdk: ^3.7.0