Saltar al contenido
Development

Enseñarle a Greenhouse a previsualizar audio del vault dentro de la app

Por Victor Da Luz
taurirustaudiodev-loggreenhouse

Greenhouse es una app de escritorio que impone un ritmo de proceso creativo: capturar una idea, dejarla madurar, trabajarla, tocarla, eventualmente guardarla en el vault o publicarla. Había algo que no dejaba de molestarme: cuando una idea o proyecto tiene un bounce de audio en su carpeta, la única forma de escucharlo es hacer clic en “Show in Finder” y buscarlo manualmente. Quería algo más cercano a Quick Look de macOS: apretar un botón, escuchar el boceto, decidir.

Antes de escribir cualquier código de interfaz escribí una investigación exploratoria (spike). Greenhouse es una app de Tauri v2, y en realidad no sabía cómo se le permite a un webview de Tauri tocar archivos locales. Asumía que estaría bloqueado por defecto, pero quería averiguar exactamente cuánto bloqueado, y qué costaría abrir la puerta un poco.

La seguridad partía de cero

Resultó que la app no exponía ni un byte de archivos al webview. Sin protocolo de assets, sin plugin de sistema de archivos, y con una Content-Security-Policy fijada a default-src 'self'. Lo único que tocaba el sistema de archivos desde el frontend era un botón de “abrir esta carpeta en Finder”, que simplemente le pasa una ruta al sistema operativo, el webview en sí nunca ve el contenido de los archivos.

Eso en realidad es una buena señal para una app que se toma en serio la seguridad, pero significaba que reproducir audio dentro de la app no iba a ser un ajuste menor. Iba a necesitar ampliar el CSP, algo que se sentía incómodo justo después de haber terminado una pasada de endurecimiento de seguridad sobre esta misma app.

Probarlo antes de construirlo

En vez de debatir la concesión en abstracto, construí una prueba de concepto descartable. Tauri tiene un “protocolo de assets” incorporado: se habilita una feature de Cargo, se cambia una bandera de configuración, y el webview puede pedir archivos locales a través de un esquema de URL especial en vez de una petición de red. La parte interesante es el alcance: no conviene darle al webview acceso a todo el sistema de archivos, solo a las carpetas que realmente necesita.

Como la ubicación del vault de Greenhouse la elige la persona usuaria durante el onboarding (no es una ruta fija incrustada en el build), el enfoque habitual de “listar las carpetas permitidas en el archivo de configuración” no encaja del todo. Tauri tiene una API en tiempo de ejecución para esto: se otorga acceso a un directorio específico desde el código, justo en el momento en que se sabe cuál es ese directorio. Así que la raíz del vault queda delimitada dentro del protocolo de assets exactamente una vez, en el momento en que se define o se carga al iniciar la app, nunca más amplio que eso.

También amplié la Content-Security-Policy, pero de forma acotada: solo toqué las dos directivas que cargan contenido multimedia (img-src, media-src), y dejé la política por defecto exactamente tan estricta como estaba. Un diff pequeño y fácil de explicar.

Después de eso, hice correr la app de verdad para comprobar que funcionaba, no solo “compiló”, sino un script que abre la app real, captura una idea real a través de la misma capa de IPC que usa la interfaz, suelta un archivo WAV real en su carpeta desde afuera del webview (simulando a alguien guardando un bounce ahí), y hace clic hasta previsualizarlo. Después le pregunté al elemento de audio en vivo en qué estado estaba: completamente cargado, duración correcta, sin errores, servido a través del propio esquema de URL del protocolo de assets. Algo que solo aprendí probando sobre el build real de macOS: la URL que Tauri realmente usa en macOS (asset://localhost/...) no coincide con lo que muestra la mayoría de la documentación que encontré, que describe la forma de Windows/Linux. Es un detalle menor, pero es exactamente el tipo de cosa que no se obtiene leyendo documentación, se obtiene ejecutando la aplicación.

De la investigación exploratoria a la funcionalidad publicada

Con el enfoque ya validado, construí la versión real: un panel de “Files” en la vista de detalle de proyecto, un botón de Preview junto a cualquier cosa que parezca audio, y un reproductor liviano que se abre en un overlay. Dejé “Show in Finder” tal como estaba en vez de reemplazarlo, algunas personas van a seguir queriendo el archivo real, no una previsualización.

Un bug pequeño y satisfactorio: mi primer borrador hacía que el audio se reprodujera automáticamente en el momento en que se abría la previsualización. Mis pruebas automáticas de accesibilidad empezaron a quedarse colgadas en esa pantalla, y descubrir por qué me llevó a una regla que ya conocía a medias y nunca había terminado de internalizar: no reproducir audio automáticamente. Es una guía de accesibilidad real, no solo un inconveniente de pruebas. Quitar el autoplay arregló la prueba y mejoró la funcionalidad al mismo tiempo, el tipo de coincidencia que en realidad no es coincidencia.

Limité esta primera versión solo a audio, a propósito. Las imágenes y los PDF reutilizarían la misma cañería, pero no los había probado, y toda la razón de ser de Greenhouse es proteger el proceso creativo de las personas contra el feature creep, incluido el mío propio.

Lecturas relacionadas

Development

Dos notas que nadie vio jamás

Greenhouse guardaba fielmente una nota de captura y una nota de traspaso, y no mostraba ninguna de las dos: una no tenía campo en el tipo de wire, la otra tenía un comando funcional que nadie llamaba.

Leer
Development

El escaneo que se ofreció a importarse a sí mismo

Un escaneo de importación que encontró la propia estructura interna de la app, y luego volvió a ofrecer una carpeta que ya había importado - dos versiones de la misma conversación faltante entre capas.

Leer