Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ app.*.map.json
/android/app/pkg/sumdb/
/android/key.properties
/android/key-staging.properties
/android/app/google-services.json
/android/app/src/*/google-services.json
*.jks
*.keystore

Expand Down Expand Up @@ -76,8 +78,11 @@ docs/plans/
# Local relay data created by `docker compose up`.
/dev/data/

# Local product analytics dart-defines.
.env.analytics*

# Reviews
reviews/
/reviews/

# AI tools
opencode.json
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,25 @@ just deps # Install Flutter and Rust dependencies
just run # Run on a connected device (staging flavor)
```

## Product Analytics

Product analytics are opt-in only and delivered by `whitenoise-rs`; Flutter does not call Aptabase directly. To enable a staging or production analytics build, pass the self-hosted Aptabase base URL and the flavor-specific app key as Dart defines:

```sh
flutter run --flavor staging \
--dart-define=APTABASE_HOST=https://analytics.example.com \
--dart-define=APTABASE_APP_KEY=staging-app-key
```

For local builds, a Flutter dart-define file is usually less error-prone:

```sh
flutter run --flavor staging --dart-define-from-file=.env.analytics.staging.local.json
flutter run --flavor production --dart-define-from-file=.env.analytics.production.local.json
```

Use separate staging and production app keys. Keep real values in CI secrets or local ignored `.env.analytics*.json` files; do not commit them.

## Structure

```
Expand Down
6 changes: 6 additions & 0 deletions lib/l10n/app_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
"nsecPlaceholder": "nsec...",
"setupProfile": "Profil einrichten",
"createProfile": "Profil erstellen",
"analyticsConsentTitle": "Hilf mit, White Noise zu verbessern",
"analyticsConsentDescription": "Teile datenschutzfreundliche Nutzungsanalysen. Wir senden niemals Nachrichteninhalte, Kontakte, öffentliche Schlüssel, Relay-URLs, Gruppen-IDs, Nachrichten-IDs oder Profildaten. Du kannst dies jederzeit deaktivieren.",
"analyticsConsentSettingsDescription": "Teile anonyme Nutzungsdaten, damit wir Fehler finden und die App verbessern können. Nachrichten, Kontakte und Schlüssel werden nie einbezogen.",
"analyticsPromptTitle": "Möchtest du helfen, White Noise zu verbessern?",
"analyticsPromptNotNow": "Nicht jetzt",
"analyticsPromptShare": "Analysedaten teilen",
"chooseName": "Name",
"enterYourName": "Namen eingeben",
"introduceYourself": "Über dich",
Expand Down
24 changes: 24 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,30 @@
"@createProfile": {
"description": "Submit button text on signup screen"
},
"analyticsConsentTitle": "Help improve White Noise",
"@analyticsConsentTitle": {
"description": "Title for the optional product analytics consent checkbox"
},
"analyticsConsentDescription": "Share privacy-preserving usage analytics. We never send message content, contacts, public keys, relay URLs, group ids, message ids, or profile data. You can turn this off anytime.",
"analyticsConsentSettingsDescription": "Share anonymous usage data to help us find bugs and improve the app. Messages, contacts, and keys are never included.",
"analyticsPromptTitle": "Help improve White Noise?",
"analyticsPromptNotNow": "Not now",
"analyticsPromptShare": "Share analytics",
"@analyticsConsentDescription": {
"description": "Description for the optional product analytics consent checkbox"
},
"@analyticsConsentSettingsDescription": {
"description": "Description for the product analytics setting row"
},
"@analyticsPromptTitle": {
"description": "Title for the product analytics prompt on the empty chat list"
},
"@analyticsPromptNotNow": {
"description": "Decline button for the product analytics prompt"
},
"@analyticsPromptShare": {
"description": "Opt-in button for the product analytics prompt"
},
"chooseName": "Name",
"@chooseName": {
"description": "Label for name input field"
Expand Down
6 changes: 6 additions & 0 deletions lib/l10n/app_es.arb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
"nsecPlaceholder": "nsec...",
"setupProfile": "Configurar perfil",
"createProfile": "Crear perfil",
"analyticsConsentTitle": "Ayuda a mejorar White Noise",
"analyticsConsentDescription": "Comparte analíticas de uso que preservan la privacidad. Nunca enviamos contenido de mensajes, contactos, claves públicas, URLs de relés, IDs de grupos, IDs de mensajes ni datos del perfil. Puedes desactivarlo cuando quieras.",
"analyticsConsentSettingsDescription": "Comparte datos de uso anónimos para ayudarnos a encontrar errores y mejorar la app. Nunca se incluyen mensajes, contactos ni claves.",
"analyticsPromptTitle": "¿Ayudar a mejorar White Noise?",
"analyticsPromptNotNow": "Ahora no",
"analyticsPromptShare": "Compartir analíticas",
"chooseName": "Nombre",
"enterYourName": "Introduce tu nombre",
"introduceYourself": "Acerca de",
Expand Down
6 changes: 6 additions & 0 deletions lib/l10n/app_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
"nsecPlaceholder": "nsec...",
"setupProfile": "Configurer le profil",
"createProfile": "Créer le profil",
"analyticsConsentTitle": "Aidez-nous à améliorer White Noise",
"analyticsConsentDescription": "Partagez des analyses d'utilisation respectueuses de la confidentialité. Nous n'envoyons jamais le contenu des messages, les contacts, les clés publiques, les URL de relais, les identifiants de groupes, les identifiants de messages ni les données de profil. Vous pouvez désactiver cette option à tout moment.",
"analyticsConsentSettingsDescription": "Partagez des données d'utilisation anonymes pour nous aider à trouver des bugs et à améliorer l'app. Les messages, contacts et clés ne sont jamais inclus.",
"analyticsPromptTitle": "Aider à améliorer White Noise ?",
"analyticsPromptNotNow": "Pas maintenant",
"analyticsPromptShare": "Partager les analyses",
"chooseName": "Nom",
"enterYourName": "Entrez votre nom",
"introduceYourself": "À propos",
Expand Down
6 changes: 6 additions & 0 deletions lib/l10n/app_it.arb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
"nsecPlaceholder": "nsec...",
"setupProfile": "Configura profilo",
"createProfile": "Crea profilo",
"analyticsConsentTitle": "Aiutaci a migliorare White Noise",
"analyticsConsentDescription": "Condividi analisi d'uso che tutelano la privacy. Non inviamo mai contenuti dei messaggi, contatti, chiavi pubbliche, URL dei relay, ID dei gruppi, ID dei messaggi o dati del profilo. Puoi disattivarlo in qualsiasi momento.",
"analyticsConsentSettingsDescription": "Condividi dati d'uso anonimi per aiutarci a trovare bug e migliorare l'app. Messaggi, contatti e chiavi non sono mai inclusi.",
"analyticsPromptTitle": "Aiutare a migliorare White Noise?",
"analyticsPromptNotNow": "Non ora",
"analyticsPromptShare": "Condividi analisi",
"chooseName": "Nome",
"enterYourName": "Inserisci il tuo nome",
"introduceYourself": "Informazioni",
Expand Down
6 changes: 6 additions & 0 deletions lib/l10n/app_pt.arb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
"nsecPlaceholder": "nsec...",
"setupProfile": "Configurar perfil",
"createProfile": "Criar perfil",
"analyticsConsentTitle": "Ajude a melhorar o White Noise",
"analyticsConsentDescription": "Compartilhe análises de uso que preservam a privacidade. Nunca enviamos conteúdo de mensagens, contatos, chaves públicas, URLs de relays, IDs de grupos, IDs de mensagens ou dados de perfil. Você pode desativar isso a qualquer momento.",
"analyticsConsentSettingsDescription": "Compartilhe dados de uso anônimos para nos ajudar a encontrar bugs e melhorar o app. Mensagens, contatos e chaves nunca são incluídos.",
"analyticsPromptTitle": "Ajudar a melhorar o White Noise?",
"analyticsPromptNotNow": "Agora não",
"analyticsPromptShare": "Compartilhar análises",
"chooseName": "Nome",
"enterYourName": "Digite seu nome",
"introduceYourself": "Sobre",
Expand Down
6 changes: 6 additions & 0 deletions lib/l10n/app_ru.arb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
"nsecPlaceholder": "nsec...",
"setupProfile": "Настройка профиля",
"createProfile": "Создать профиль",
"analyticsConsentTitle": "Помогите улучшить White Noise",
"analyticsConsentDescription": "Делитесь обезличенной аналитикой использования с сохранением конфиденциальности. Мы никогда не отправляем содержимое сообщений, контакты, публичные ключи, URL реле, идентификаторы групп, идентификаторы сообщений или данные профиля. Вы можете отключить это в любое время.",
"analyticsConsentSettingsDescription": "Делитесь анонимными данными об использовании, чтобы помочь нам находить ошибки и улучшать приложение. Сообщения, контакты и ключи никогда не включаются.",
"analyticsPromptTitle": "Помочь улучшить White Noise?",
"analyticsPromptNotNow": "Не сейчас",
"analyticsPromptShare": "Поделиться аналитикой",
"chooseName": "Имя",
"enterYourName": "Введите ваше имя",
"introduceYourself": "О себе",
Expand Down
6 changes: 6 additions & 0 deletions lib/l10n/app_tr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
"nsecPlaceholder": "nsec...",
"setupProfile": "Profil oluştur",
"createProfile": "Profil oluştur",
"analyticsConsentTitle": "White Noise'u iyileştirmeye yardım edin",
"analyticsConsentDescription": "Gizliliği koruyan kullanım analizlerini paylaşın. Mesaj içeriklerini, kişileri, açık anahtarları, röle URL'lerini, grup kimliklerini, mesaj kimliklerini veya profil verilerini asla göndermeyiz. Bunu istediğiniz zaman kapatabilirsiniz.",
"analyticsConsentSettingsDescription": "Hataları bulmamıza ve uygulamayı iyileştirmemize yardımcı olmak için anonim kullanım verilerini paylaşın. Mesajlar, kişiler ve anahtarlar hiçbir zaman dahil edilmez.",
"analyticsPromptTitle": "White Noise'u iyileştirmeye yardım etmek ister misiniz?",
"analyticsPromptNotNow": "Şimdi değil",
"analyticsPromptShare": "Analizleri paylaş",
"chooseName": "İsim",
"enterYourName": "Adınızı girin",
"introduceYourself": "Hakkında",
Expand Down
6 changes: 6 additions & 0 deletions lib/l10n/app_zh.arb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
"nsecPlaceholder": "nsec...",
"setupProfile": "设置个人资料",
"createProfile": "创建个人资料",
"analyticsConsentTitle": "帮助改进 White Noise",
"analyticsConsentDescription": "分享保护隐私的使用分析。我们绝不会发送消息内容、联系人、公钥、中继 URL、群组 ID、消息 ID 或个人资料数据。您可以随时关闭。",
"analyticsConsentSettingsDescription": "分享匿名使用数据,帮助我们发现问题并改进应用。消息、联系人和密钥绝不会包含在内。",
"analyticsPromptTitle": "帮助改进 White Noise?",
"analyticsPromptNotNow": "暂不",
"analyticsPromptShare": "分享分析数据",
"chooseName": "名称",
"enterYourName": "输入您的名称",
"introduceYourself": "简介",
Expand Down
6 changes: 6 additions & 0 deletions lib/l10n/app_zh_Hant.arb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
"nsecPlaceholder": "nsec...",
"setupProfile": "設定個人檔案",
"createProfile": "建立個人檔案",
"analyticsConsentTitle": "協助改進 White Noise",
"analyticsConsentDescription": "分享保護隱私的使用分析。我們絕不會傳送訊息內容、聯絡人、公鑰、中繼站 URL、群組 ID、訊息 ID 或個人檔案資料。您可以隨時關閉。",
"analyticsConsentSettingsDescription": "分享匿名使用資料,協助我們找出問題並改進應用程式。訊息、聯絡人和金鑰絕不會包含在內。",
"analyticsPromptTitle": "協助改進 White Noise?",
"analyticsPromptNotNow": "暫時不要",
"analyticsPromptShare": "分享分析資料",
"chooseName": "名稱",
"enterYourName": "輸入您的名稱",
"introduceYourself": "簡介",
Expand Down
36 changes: 36 additions & 0 deletions lib/l10n/generated/app_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,42 @@ abstract class AppLocalizations {
/// **'Create profile'**
String get createProfile;

/// Title for the optional product analytics consent checkbox
///
/// In en, this message translates to:
/// **'Help improve White Noise'**
String get analyticsConsentTitle;

/// Description for the optional product analytics consent checkbox
///
/// In en, this message translates to:
/// **'Share privacy-preserving usage analytics. We never send message content, contacts, public keys, relay URLs, group ids, message ids, or profile data. You can turn this off anytime.'**
String get analyticsConsentDescription;

/// Description for the product analytics setting row
///
/// In en, this message translates to:
/// **'Share anonymous usage data to help us find bugs and improve the app. Messages, contacts, and keys are never included.'**
String get analyticsConsentSettingsDescription;

/// Title for the product analytics prompt on the empty chat list
///
/// In en, this message translates to:
/// **'Help improve White Noise?'**
String get analyticsPromptTitle;

/// Decline button for the product analytics prompt
///
/// In en, this message translates to:
/// **'Not now'**
String get analyticsPromptNotNow;

/// Opt-in button for the product analytics prompt
///
/// In en, this message translates to:
/// **'Share analytics'**
String get analyticsPromptShare;

/// Label for name input field
///
/// In en, this message translates to:
Expand Down
20 changes: 20 additions & 0 deletions lib/l10n/generated/app_localizations_de.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,26 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get createProfile => 'Profil erstellen';

@override
String get analyticsConsentTitle => 'Hilf mit, White Noise zu verbessern';

@override
String get analyticsConsentDescription =>
'Teile datenschutzfreundliche Nutzungsanalysen. Wir senden niemals Nachrichteninhalte, Kontakte, öffentliche Schlüssel, Relay-URLs, Gruppen-IDs, Nachrichten-IDs oder Profildaten. Du kannst dies jederzeit deaktivieren.';

@override
String get analyticsConsentSettingsDescription =>
'Teile anonyme Nutzungsdaten, damit wir Fehler finden und die App verbessern können. Nachrichten, Kontakte und Schlüssel werden nie einbezogen.';

@override
String get analyticsPromptTitle => 'Möchtest du helfen, White Noise zu verbessern?';

@override
String get analyticsPromptNotNow => 'Nicht jetzt';

@override
String get analyticsPromptShare => 'Analysedaten teilen';

@override
String get chooseName => 'Name';

Expand Down
20 changes: 20 additions & 0 deletions lib/l10n/generated/app_localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,26 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get createProfile => 'Create profile';

@override
String get analyticsConsentTitle => 'Help improve White Noise';

@override
String get analyticsConsentDescription =>
'Share privacy-preserving usage analytics. We never send message content, contacts, public keys, relay URLs, group ids, message ids, or profile data. You can turn this off anytime.';

@override
String get analyticsConsentSettingsDescription =>
'Share anonymous usage data to help us find bugs and improve the app. Messages, contacts, and keys are never included.';

@override
String get analyticsPromptTitle => 'Help improve White Noise?';

@override
String get analyticsPromptNotNow => 'Not now';

@override
String get analyticsPromptShare => 'Share analytics';

@override
String get chooseName => 'Name';

Expand Down
20 changes: 20 additions & 0 deletions lib/l10n/generated/app_localizations_es.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,26 @@ class AppLocalizationsEs extends AppLocalizations {
@override
String get createProfile => 'Crear perfil';

@override
String get analyticsConsentTitle => 'Ayuda a mejorar White Noise';

@override
String get analyticsConsentDescription =>
'Comparte analíticas de uso que preservan la privacidad. Nunca enviamos contenido de mensajes, contactos, claves públicas, URLs de relés, IDs de grupos, IDs de mensajes ni datos del perfil. Puedes desactivarlo cuando quieras.';

@override
String get analyticsConsentSettingsDescription =>
'Comparte datos de uso anónimos para ayudarnos a encontrar errores y mejorar la app. Nunca se incluyen mensajes, contactos ni claves.';

@override
String get analyticsPromptTitle => '¿Ayudar a mejorar White Noise?';

@override
String get analyticsPromptNotNow => 'Ahora no';

@override
String get analyticsPromptShare => 'Compartir analíticas';

@override
String get chooseName => 'Nombre';

Expand Down
20 changes: 20 additions & 0 deletions lib/l10n/generated/app_localizations_fr.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,26 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get createProfile => 'Créer le profil';

@override
String get analyticsConsentTitle => 'Aidez-nous à améliorer White Noise';

@override
String get analyticsConsentDescription =>
'Partagez des analyses d\'utilisation respectueuses de la confidentialité. Nous n\'envoyons jamais le contenu des messages, les contacts, les clés publiques, les URL de relais, les identifiants de groupes, les identifiants de messages ni les données de profil. Vous pouvez désactiver cette option à tout moment.';

@override
String get analyticsConsentSettingsDescription =>
'Partagez des données d\'utilisation anonymes pour nous aider à trouver des bugs et à améliorer l\'app. Les messages, contacts et clés ne sont jamais inclus.';

@override
String get analyticsPromptTitle => 'Aider à améliorer White Noise ?';

@override
String get analyticsPromptNotNow => 'Pas maintenant';

@override
String get analyticsPromptShare => 'Partager les analyses';

@override
String get chooseName => 'Nom';

Expand Down
20 changes: 20 additions & 0 deletions lib/l10n/generated/app_localizations_it.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,26 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get createProfile => 'Crea profilo';

@override
String get analyticsConsentTitle => 'Aiutaci a migliorare White Noise';

@override
String get analyticsConsentDescription =>
'Condividi analisi d\'uso che tutelano la privacy. Non inviamo mai contenuti dei messaggi, contatti, chiavi pubbliche, URL dei relay, ID dei gruppi, ID dei messaggi o dati del profilo. Puoi disattivarlo in qualsiasi momento.';

@override
String get analyticsConsentSettingsDescription =>
'Condividi dati d\'uso anonimi per aiutarci a trovare bug e migliorare l\'app. Messaggi, contatti e chiavi non sono mai inclusi.';

@override
String get analyticsPromptTitle => 'Aiutare a migliorare White Noise?';

@override
String get analyticsPromptNotNow => 'Non ora';

@override
String get analyticsPromptShare => 'Condividi analisi';

@override
String get chooseName => 'Nome';

Expand Down
Loading
Loading