![]() |
![]() |
![]() |
| Login Screen | Home Screen | Gallery View |
![]() |
![]() |
![]() |
| Image Generation | Virtual Try-On | Virtual Try-On Output |
Delilah is a production-ready Flutter mobile application that provides AI-powered image generation and editing capabilities. The app connects to a FastAPI backend with Vertex AI for image processing and uses Cloudinary for image storage.
| Feature | Endpoint | Description |
|---|---|---|
| Image Generation | /api/generate |
Generate stunning images from text prompts using Vertex AI Imagen |
| Virtual Try-On | /api/tryon |
Try on clothes virtually by combining person photos with clothing items |
| Image Editing | /api/edit |
Apply filters and semantic modifications to existing images |
| Image Upscale | /api/upscale |
Enhance resolution and remove digital noise from images |
| Product Makeover | /api/product-makeover |
Place products in contextual synthetic backgrounds |
| Fix Old Image | /api/fixoldimage |
Restore old/damaged photos by removing artifacts |
| Gallery | /api/gallery |
View, save, and manage all generated images |
| Wallpaper | - | Set any image as device wallpaper |
- Frontend: Flutter 3.11+ with Dart
- State Management: Riverpod 2.5+
- Routing: GoRouter 14+
- HTTP Client: Dio
- Image Storage: Cloudinary (unsigned uploads)
- Secure Storage: flutter_secure_storage (JWT tokens)
- Image Saving: Gal (gallery access)
- Image Picking: image_picker
lib/
βββ main.dart # App entry point
βββ core/
β βββ config.dart # API URLs and Cloudinary config
β βββ router.dart # GoRouter configuration with navigation
β βββ network/
β β βββ pb_interceptor.dart # HTTP interceptors
β βββ services/
β β βββ cloudinary_service.dart # Cloudinary upload with caching
β β βββ secure_storage.dart # Token persistence
β βββ theme/
β βββ theme_controller.dart # Design tokens (colors, spacing)
β βββ glass_theme.dart # Theme configuration
βββ features/
β βββ auth/ # Authentication
β β βββ data/
β β β βββ auth_repository.dart # Login/register API calls
β β βββ presentation/
β β β βββ login_screen.dart
β β β βββ register_screen.dart
β β βββ providers/
β β βββ auth_provider.dart # Auth state management
β βββ home/
β β βββ presentation/
β β βββ home_screen.dart # Hero section + quick actions
β βββ endpoints/
β β βββ image_generation/ # Generate images from prompts
β β βββ virtual_tryon/ # Virtual clothing try-on
β β βββ image_edit/ # Image editing & filters
β β βββ upscale/ # Image upscaling
β β βββ product_makeover/ # Product background change
β β βββ fix_old_image/ # Photo restoration
β βββ history/
β βββ presentation/
β β βββ history_screen.dart # Gallery with save/wallpaper
β βββ providers/
β βββ history_provider.dart # Gallery API state
βββ shared/
βββ widgets/
β βββ glass_button.dart # Custom styled button
β βββ glass_input.dart # Custom styled input
β βββ async_value_widget.dart
βββ utils/
βββ wallpaper_engine.dart # Android wallpaper setter
The app uses Riverpod with a consistent pattern across all features:
- Provider: Defines the state class (immutable data class)
- Notifier: Handles state mutations and async operations
- Repository: Makes API calls with proper auth headers
- Screen: Consumes state via
ref.watch()and triggers actions viaref.read()
Example pattern:
// State class
class TryOnState {
final File? personImage;
final String? resultUrl;
final bool isGenerating;
// ...
}
// Notifier
class TryOnNotifier extends Notifier<TryOnState> {
Future<void> generate() async {
state = state.copyWith(isGenerating: true);
// API call...
state = state.copyWith(resultUrl: result, isGenerating: false);
}
}
// Provider
final tryOnNotifierProvider = NotifierProvider<TryOnNotifier, TryOnState>(() => TryOnNotifier());The app uses JWT tokens from PocketBase for authentication.
Login: POST /api/auth/login
{"email": "user@example.com", "password": "password"}Response:
{"token": "jwt_token_here"}All endpoints (except login/register) require Authorization: Bearer <token> header.
| Method | Endpoint | Request Body | Response |
|---|---|---|---|
| POST | /api/generate |
{"prompt": "..."} |
{"status": "success", "secure_url": "..."} |
| POST | /api/tryon |
{"person_image_url": "...", "product_image_url": "..."} |
{"status": "success", "secure_url": "..."} |
| POST | /api/edit |
{"image_url": "...", "edit_prompt": "..."} |
{"status": "success", "secure_url": "..."} |
| POST | /api/upscale |
{"image_url": "...", "enhancement_focus": "..."} |
{"status": "success", "secure_url": "..."} |
| POST | /api/product-makeover |
{"product_image_url": "...", "background_context": "..."} |
{"status": "success", "secure_url": "..."} |
| POST | /api/fixoldimage |
{"image_url": "...", "repair_instructions": "..."} |
{"status": "success", "secure_url": "..."} |
| GET | /api/gallery |
- | {"images": [{"secure_url": "...", "public_id": "...", ...}]} |
| DELETE | /api/gallery |
{"public_id": "..."} |
{"success": true} |
Images are uploaded to Cloudinary with folder structure:
delilah_users/<email_cleaned>/<tag>/
Example: delilah_users/user_example_com/generated_studio/
| Color | Hex | Usage |
|---|---|---|
canvasWhite |
#FFFFFF |
Main background |
cohereBlack |
#1A1A1A |
Primary text |
actionBlue |
#4F46E5 |
Primary actions |
softStone |
#F3F4F6 |
Card backgrounds |
hairline |
#E5E7EB |
Borders |
mutedSlate |
#6B7280 |
Secondary text |
deepEnterpriseGreen |
#10B981 |
Success states |
errorRed |
#EF4444 |
Error states |
Uses Unica77 font family (via design tokens in theme_controller.dart):
headlineLarge: 28px, boldtitleMedium: 18px, semiboldbodyMedium: 14px, regularbodySmall: 12px, regular
The app uses a Shell Route pattern with bottom navigation:
Home (default landing)
βββ Quick actions β Generate, Try-On, Edit, Gallery
Tools (modal menu)
βββ Generate Image
βββ Virtual Try-On
βββ Edit Image
βββ Upscale
βββ Product Makeover
βββ Fix Old Image
Gallery
βββ Grid view β Detail sheet β Save/Wallpaper/Delete
Logout β Login screen
- Unauthenticated users are redirected to
/login - Authenticated users on auth pages are redirected to
/home - Back gesture from any tool goes to Home (not exit app)
- Gallery auto-refreshes on first load only
- Flutter 3.11+
- Dart 3.11+
- Android SDK with API 21+
# Get dependencies
flutter pub get
# Run on connected device/emulator
flutter run
# Analyze code
flutter analyze
# Build debug APK
flutter build apk --debug
# Build release APK
flutter build apk --releaseandroid/key.properties
storePassword=
keyPassword=
keyAlias=upload
storeFile=../../keystore/release-key.jks
The release build uses a custom keystore located at ../keystore/release-key.jks.
# Build release (signs with release key)
flutter build apk --releaseINTERNET- API callsSET_WALLPAPER- Set wallpaper featureREAD_EXTERNAL_STORAGE(API β€ 32) - Gallery accessWRITE_EXTERNAL_STORAGE(API β€ 29) - Save to gallery
Images uploaded from device are cached by file path to avoid re-uploading the same image:
final cachedUrl = cloudinary.getCachedUrl(file.path);
if (cachedUrl != null) {
state = state.copyWith(imageUrl: cachedUrl);
return;
}Uses gal package for modern gallery access:
final tempDir = await getTemporaryDirectory();
final tempFile = File('${tempDir.path}/image.jpg');
await tempFile.writeAsBytes(response.bodyBytes);
await Gal.putImage(tempFile.path);
await tempFile.delete();Uses platform channel to set wallpaper with center-crop for proper aspect ratio:
// android/app/src/main/kotlin/.../MainActivity.kt
val wallpaperManager = WallpaperManager.getInstance(applicationContext)
wallpaperManager.setBitmap(bitmap, null, true, WallpaperManager.FLAG_SYSTEM)| Version | Changes |
|---|---|
| 1.0.8 | Added launcher icons, assets folder |
| 1.0.6 | Fixed save image permission error |
| 1.0.5 | Add save/fullscreen to new endpoints, back gesture fix, gallery auto-refresh |
| 1.0.4 | Fix layout overflow in home screen modal |
| 1.0.3 | Add local image picker + Cloudinary upload, create homepage |
| 1.0.2 | Add missing API endpoints (edit, upscale, product-makeover, fixoldimage) |
| 1.0.1 | Add gallery delete functionality |
| 1.0.0 | Initial release with auth, generate, tryon, gallery |
MIT License
- Fork the repository
- Create a feature branch
- Make changes and test
- Run
flutter analyzeto check for issues - Commit with clear description
- Push and create pull request

.png)
.png)


