Skip to content

Kaelith69/Emo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

11 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Emo Your AI Emotional Support Companion Flutter Β· Gemini 1.5 Flash Β· Cross-Platform Β· AMOLED Dark

"A pocket-sized friend who actually listens. Powered by AI, fueled by good vibes." ✨


Flutter Dart Gemini API License: MIT Platform Version


πŸ€” So What Even Is This?

You know that friend who always knows what to say when you're having a rough day? Emo is that friend β€” except it runs on your phone, never sleeps, never judges you, and is powered by Google's Gemini AI instead of 10 years of therapy.

Emo is a cross-platform Flutter app that gives you a safe space to type out how you're feeling, and replies with genuinely warm, empathetic, emoji-peppered responses. Think of it as a diary that talks back β€” in the most supportive way possible.

It maintains conversational context (so it remembers what you just said), saves the bot's best responses locally for you to revisit, and runs on literally every platform Flutter supports. It's dark-themed, snappy, and built with love (and http.post).


🎬 Live Demo

Place a demo GIF here once you've recorded one: assets/demo.gif

Demo

What the GIF should show:

  • Typing a message into the chat input ("I'm having a stressful day")
  • The loading spinner while Gemini thinks
  • The empathetic reply appearing as a message bubble
  • Opening the drawer to see saved messages
  • Deleting a saved message with the trash icon

Keep it around 5–10 seconds, looping. Nobody wants to download a 50MB GIF.


🧩 System Overview

Emo is a single-screen Flutter app with three main logical layers:

Layer What it does
UI Layer Chat bubbles, text input, send button, drawer panel
Logic Layer _sendMessage() builds the prompt, calls Gemini, updates state
Storage Layer shared_preferences persists bot responses between sessions

The app is intentionally kept simple β€” one file, one screen, zero over-engineering. It's a reminder that not every project needs a BLoC + repository pattern + dependency injection to be genuinely useful.


🎯 Features

Feature Description
πŸ’¬ Contextual Chat Remembers your last message and the bot's last response to maintain natural conversation flow
πŸ€— Emotional Support AI Prompt-engineered to give brief, caring, emoji-friendly replies β€” not generic chatbot fluff
πŸŒ‘ AMOLED Dark UI Pure #121212 background β€” your battery and your eyes will thank you
πŸ’Ύ Saved Messages Bot responses you love get persisted locally via shared_preferences
πŸ—‘οΈ Delete Saved Messages Swipe open the drawer, tap the trash icon β€” message gone, no drama
🌐 Truly Cross-Platform Android, iOS, Web, Linux, macOS, Windows β€” one codebase, all the places
⚑ Gemini 1.5 Flash Fast, intelligent responses via Google's generative AI β€” not some janky rule-based bot
πŸ”„ Auto-scroll Chat auto-scrolls to the latest message because manually scrolling is so 2010

πŸ“Š Capability Overview

Capability Overview

AI Empathy Quality Response Speed Platform Coverage Local Persistence Context Awareness UI Responsiveness

90% 85% 100% 80% 75% 95%


πŸ—οΈ Architecture

Application Architecture MyApp MyHomePage (Stateful) _sendMessage() Gemini API call + context Message model MessageBubble widget MyDrawer (Stateful) Saved messages panel Gemini 1.5 Flash REST API (http pkg) SharedPreferences Local persistence SharedPreferences Load + delete messages UI / Widget Layer Logic Layer Storage / Network

State management: Plain StatefulWidget + setState β€” no BLoC, no Riverpod, no Redux. This is a conscious choice. The app is single-screen. Don't over-engineer it.

Persistence: shared_preferences stores bot responses as a string list. Lightweight, zero-config, perfect for this use case.

Networking: http package makes a POST to the Gemini REST endpoint. No fancy GraphQL, no gRPC. Just good ol' HTTP.

Typography: google_fonts loads Playfair Display for the app title. Because serif fonts in a dark AMOLED theme hit different.


🌊 Data Flow

Message Data Flow User Types TextField input Prompt Built + context injected Gemini API POST β†’ response Reply Displayed + auto-scroll β‘  β‘‘ β‘’ β‘£ πŸ’Ύ Auto-saved to shared_preferences conversation context

πŸš€ Installation

What You Need

  • Flutter SDK β‰₯ 3.0.0 (check with flutter --version)
  • A Google Gemini API key β€” free tier available at Google AI Studio
  • Dart SDK β‰₯ 3.0.0 (comes with Flutter, relax)
  • A device or emulator to run it on (or just use flutter run -d chrome)

Steps

# 1. Clone the repo (you know the drill)
git clone https://github.com/Kaelith69/Emo.git
cd Emo

# 2. Get dependencies
flutter pub get

# 3. Open lib/main.dart and swap in your API key
#    (line ~18, look for _kApiKey)

# 4. Run it
flutter run

# Or target a specific platform:
flutter run -d android
flutter run -d ios
flutter run -d chrome
flutter run -d windows
flutter run -d linux
flutter run -d macos

API Key Configuration

Open lib/main.dart and replace the placeholder:

// lib/main.dart β€” line ~18
const String _kApiKey = 'YOUR_GEMINI_API_KEY';

⚠️ Seriously though: Do not commit a real API key. Use environment variables, --dart-define, or a secrets manager for production builds. Future self will thank you.

# One approach with --dart-define at build time:
flutter run --dart-define=GEMINI_KEY=your_actual_key_here

πŸ“– Usage

  1. Launch the app β€” you'll see the Emo title and a chat input at the bottom
  2. Type how you're feeling β€” be honest, it won't judge you
  3. Hit Send (or press Enter) β€” the spinner appears while Gemini processes
  4. Read the reply β€” warm, empathetic, emoji-packed goodness
  5. Open the drawer (menu icon, top-left) to see all saved bot responses
  6. Delete saved messages you no longer need with the πŸ—‘οΈ icon
  7. Keep chatting β€” context from your last exchange is included automatically

Gemini API Details

Property Value
Provider Google Generative AI
Model gemini-1.5-flash
Endpoint POST /v1beta/models/gemini-1.5-flash:generateContent
Temperature 0.9 (creative, warm, not robotic)
Candidate count 1

Request body shape:

{
  "contents": [{ "parts": [{ "text": "<crafted prompt with context>" }] }],
  "generationConfig": { "temperature": 0.9, "candidateCount": 1 }
}

Response extraction:

candidates[0]['content']['parts'][0]['text']

πŸ“ Project Structure

Emo/
β”œβ”€β”€ lib/
β”‚   └── main.dart           ← The whole app. Yep, one file.
β”‚       β”œβ”€β”€ MyApp           ← MaterialApp root, dark theme config
β”‚       β”œβ”€β”€ MyHomePage      ← Stateful chat screen
β”‚       β”‚   β”œβ”€β”€ _sendMessage()    ← Builds prompt, calls Gemini, updates UI
β”‚       β”‚   β”œβ”€β”€ _addMessage()     ← Appends to message list + auto-scrolls
β”‚       β”‚   └── _saveMessage()    ← Persists bot reply to SharedPreferences
β”‚       β”œβ”€β”€ Message         ← Immutable data model (text + isUser flag)
β”‚       β”œβ”€β”€ MessageBubble   ← Stateless chat bubble (user: purple, bot: dark)
β”‚       └── MyDrawer        ← Stateful saved-messages side panel
β”œβ”€β”€ test/
β”‚   └── widget_test.dart    ← Widget tests (render, send, drawer, empty input)
β”œβ”€β”€ android/                ← Android-specific config
β”œβ”€β”€ ios/                    ← iOS-specific config
β”œβ”€β”€ web/                    ← Web build files
β”œβ”€β”€ linux/                  ← Linux desktop
β”œβ”€β”€ macos/                  ← macOS desktop
β”œβ”€β”€ windows/                ← Windows desktop
β”œβ”€β”€ pubspec.yaml            ← Dependencies & metadata
β”œβ”€β”€ analysis_options.yaml   ← Dart linter config
└── assets/
    └── demo.gif            ← (Add your demo GIF here)

πŸ“¦ Dependencies

Package Version Purpose
flutter SDK UI framework
google_fonts ^6.0.0 Playfair Display for the app title
http ^1.1.0 HTTP client for Gemini API calls
shared_preferences ^2.2.1 Local persistence of bot responses
cupertino_icons ^1.0.2 iOS-style icons

πŸ“ˆ Performance

Performance Snapshot ~1s Cold Start Flutter release build 1–3s API Response Gemini 1.5 Flash avg 6 Platforms One codebase 4 Widget Tests All passing βœ“

πŸ”’ Privacy

  • No data leaves your device except the text you explicitly type and send
  • API calls go directly to Google's Generative AI API β€” only your message + conversation context is transmitted
  • No analytics, no tracking, no telemetry β€” none of that nonsense is in this codebase
  • Local storage uses shared_preferences β€” stored on-device only, never synced to a server
  • API key is stored in the source code (placeholder by default) β€” you are responsible for securing it in production

See SECURITY.md for vulnerability reporting.


πŸ—ΊοΈ Roadmap

  • Secure API key loading via --dart-define or environment variable
  • Message search within saved messages
  • Light mode / system theme support
  • Multi-turn structured conversation history (not just last-message context)
  • Export chat history to a text or JSON file
  • Daily affirmation push notifications
  • Haptic feedback on send
  • Accessibility improvements (screen reader support)

πŸ§ͺ Tests

flutter test

The test suite covers:

  • βœ… App renders title and chat input
  • βœ… Send button is enabled initially, disabled during loading
  • βœ… Empty input does not trigger a send (no phantom blank messages)
  • βœ… Drawer opens and shows the "Saved Messages" header

🀝 Contributing

Pull requests are welcome β€” check out CONTRIBUTING.md for the full rundown.

Short version: fork β†’ branch β†’ commit β†’ PR. Be kind, write tests, don't commit API keys.


πŸ“„ License

Distributed under the MIT License. See LICENSE for details.

Β© 2025 Sayanth T M


Built with ❀️, Flutter, and an unhealthy amount of caffeine
πŸ› Report a bug Β· 🀝 Contribute Β· πŸ“š Wiki

About

Emo is your always-there friend powered by Google Gemini AI, a cross platform Flutter app where you vent freely and get warm empathetic emoji filled replies, with context memory, saved responses, and a fast dark themed experience.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors