Skip to content

6arshid/bluetoosh

Repository files navigation

Bluetoosh πŸ“‘

"Offline Bluetooth Messenger"

A retro 8-bit styled, fully offline peer-to-peer messenger that works entirely over Bluetooth. No internet. No servers. No cloud. Just Bluetooth.


Screenshots

Splash Nearby Chat Settings
(placeholder) (placeholder) (placeholder) (placeholder)

Features

  • Retro 8-bit UI β€” "Press Start 2P" font, pixel art avatars, scanline overlay
  • BLE + Classic Bluetooth β€” via flutter_blue_plus
  • Mesh discovery β€” via Google Nearby Connections (nearby_connections)
  • One-to-one chat over Bluetooth
  • Group chat with admin controls (add/remove members)
  • Media sharing β€” images, videos, documents, voice notes (chunked transfer)
  • Voice calls over Bluetooth (8kHz PCM streaming)
  • Video calls β€” low-fps JPEG slideshow mode (~2fps, Bluetooth bandwidth trade-off)
  • AES-256 encrypted storage (keys in flutter_secure_storage)
  • Delete My Data β€” full wipe with pixel skull animation
  • 100% offline β€” works with zero internet connectivity

Tech Stack

Layer Technology
Framework Flutter 3.x (Dart 3)
Bluetooth flutter_blue_plus + nearby_connections
Database hive + hive_flutter
Encryption encrypt (AES-256-CBC) + flutter_secure_storage
State provider
Fonts google_fonts (Press Start 2P)
Media file_picker, image_picker, record, audioplayers, camera

Project Structure

lib/
β”œβ”€β”€ main.dart                     # App entry, init DB + encryption
β”œβ”€β”€ app.dart                      # App widget + providers
β”œβ”€β”€ core/
β”‚   β”œβ”€β”€ constants/colors.dart     # Retro color palette
β”‚   β”œβ”€β”€ theme/pixel_theme.dart    # 8-bit ThemeData
β”‚   └── utils/pixel_avatar_generator.dart  # Procedural pixel avatars
β”œβ”€β”€ features/
β”‚   β”œβ”€β”€ bluetooth/
β”‚   β”‚   β”œβ”€β”€ services/bluetooth_service.dart  # BLE connection manager
β”‚   β”‚   β”œβ”€β”€ services/peer_discovery.dart     # Nearby Connections mesh
β”‚   β”‚   └── models/peer.dart
β”‚   β”œβ”€β”€ chat/
β”‚   β”‚   β”œβ”€β”€ screens/splash_screen.dart
β”‚   β”‚   β”œβ”€β”€ screens/onboarding_screen.dart
β”‚   β”‚   β”œβ”€β”€ screens/chat_list_screen.dart
β”‚   β”‚   β”œβ”€β”€ screens/chat_screen.dart
β”‚   β”‚   β”œβ”€β”€ screens/nearby_users_screen.dart
β”‚   β”‚   β”œβ”€β”€ widgets/pixel_message_bubble.dart
β”‚   β”‚   └── models/message.dart
β”‚   β”œβ”€β”€ groups/
β”‚   β”‚   β”œβ”€β”€ screens/group_screen.dart
β”‚   β”‚   β”œβ”€β”€ screens/create_group_screen.dart
β”‚   β”‚   β”œβ”€β”€ screens/add_members_screen.dart
β”‚   β”‚   └── models/group.dart
β”‚   β”œβ”€β”€ calls/
β”‚   β”‚   β”œβ”€β”€ screens/voice_call_screen.dart
β”‚   β”‚   β”œβ”€β”€ screens/video_call_screen.dart
β”‚   β”‚   β”œβ”€β”€ services/audio_stream.dart
β”‚   β”‚   └── services/video_stream.dart
β”‚   β”œβ”€β”€ media/
β”‚   β”‚   β”œβ”€β”€ services/media_transfer.dart    # Chunked BT file transfer
β”‚   β”‚   └── services/file_handler.dart
β”‚   β”œβ”€β”€ home/
β”‚   β”‚   └── home_screen.dart
β”‚   └── settings/
β”‚       └── screens/
β”‚           β”œβ”€β”€ settings_screen.dart
β”‚           └── delete_data_screen.dart     # Pixel skull wipe
β”œβ”€β”€ storage/
β”‚   β”œβ”€β”€ local_db.dart             # Hive database wrapper
β”‚   └── encryption_service.dart   # AES-256 encrypt/decrypt
└── shared/
    └── widgets/
        β”œβ”€β”€ pixel_button.dart       # Press-down pixel button
        β”œβ”€β”€ pixel_dialog.dart       # 8-bit dialog
        β”œβ”€β”€ pixel_text_field.dart   # Pixel input field
        β”œβ”€β”€ pixel_progress_bar.dart # Stepped progress bar + spinner
        └── scanline_overlay.dart   # CRT scanline + signal bars

Build & Setup

Prerequisites

  • Flutter SDK β‰₯ 3.3.0
  • Dart β‰₯ 3.3.0
  • Android Studio / Xcode

Install dependencies

flutter pub get

Run code generation (Hive adapters)

dart run build_runner build --delete-conflicting-outputs

Run on device

# Android
flutter run --release

# iOS (requires Mac + Xcode)
flutter run --release -d ios

Build APK

flutter build apk --release --split-per-abi

Build iOS IPA

flutter build ios --release

Android Setup Notes

  • Min SDK: 21 (Android 5.0)
  • Target SDK: 34
  • Compile SDK: 34
  • Bluetooth permissions are declared in AndroidManifest.xml
  • For Android 12+, BLUETOOTH_SCAN / BLUETOOTH_CONNECT / BLUETOOTH_ADVERTISE are required

android/app/build.gradle additions needed:

android {
    compileSdkVersion 34
    defaultConfig {
        applicationId "com.bluetoosh.messenger"
        minSdkVersion 21
        targetSdkVersion 34
    }
}

iOS Setup Notes

  • Deployment target: iOS 13.0+
  • Add NSBluetoothAlwaysUsageDescription (already in Info.plist)
  • Background Bluetooth modes enabled in Info.plist
  • Enable Background Modes capability in Xcode: βœ… Uses Bluetooth LE accessories βœ… Acts as a Bluetooth LE accessory βœ… Audio, AirPlay, and Picture in Picture

Video Call Trade-off

True real-time video over Bluetooth is impractical due to bandwidth constraints (~720 Kbps for BT Classic, even less for BLE). Bluetoosh implements a low-fps JPEG slideshow mode:

  • Resolution: 240p (low camera preset)
  • Frame rate: ~2fps (one frame every 500ms)
  • Encoding: JPEG (camera's native output)
  • Audio: separate 8kHz PCM stream

This allows functional "video" communication while staying within Bluetooth bandwidth limits.


Privacy & Security

  • All messages encrypted with AES-256-CBC before being stored in Hive
  • Encryption key stored in flutter_secure_storage (iOS Keychain / Android EncryptedSharedPreferences)
  • Media files saved to app-private directory under /Bluetoosh/Media/
  • Delete My Data button permanently erases:
    • All Hive database boxes
    • All media files
    • All encryption keys
    • User profile
  • No analytics, no crash reporting, no network calls

Comments in Persian / English

Key files contain bilingual comments:

  • lib/main.dart β€” Persian + English
  • lib/storage/local_db.dart β€” Persian + English
  • lib/features/bluetooth/services/bluetooth_service.dart β€” Persian + English

License

MIT Β© Bluetoosh Contributors