✨ Major Features: - Dark mode toggle with app-wide theme switching - Sort inventory by Expiration Date, Name, or Location - Toggle between Grid and List view for inventory - Export inventory data to CSV with share functionality - Custom sage leaf app icon with adaptive icon support 🔄 FOSS Compliance (F-Droid Ready): - Replaced Firebase with Supabase (open-source backend) - Anonymous authentication (no user accounts required) - Cloud-first with hosted Supabase as default - Optional self-hosting support - 100% FOSS-compliant dependencies 🎨 UI/UX Improvements: - Dynamic version display from package.json (was hardcoded) - Added edit buttons for household and user names - Removed non-functional search button - Replaced Recipes placeholder with Settings button - Improved settings organization with clear sections 📦 Dependencies: Added: - supabase_flutter: ^2.8.4 (FOSS backend sync) - package_info_plus: ^8.1.0 (dynamic version) - csv: ^6.0.0 (data export) - share_plus: ^10.1.2 (file sharing) - image: ^4.5.4 (dev, icon generation) Removed: - firebase_core (replaced with Supabase) - cloud_firestore (replaced with Supabase) 🗑️ Cleanup: - Removed Firebase setup files and google-services.json - Removed unimplemented features (Recipes, Search) - Removed firebase_household_service.dart - Removed inventory_sync_service.dart (replaced with Supabase) 📄 New Files: - lib/features/household/services/supabase_household_service.dart - web/privacy-policy.html (Play Store requirement) - web/terms-of-service.html (Play Store requirement) - PLAY_STORE_LISTING.md (marketing copy) - tool/generate_icons.dart (icon generation script) - assets/icon/sage_leaf.png (1024x1024) - assets/icon/sage_leaf_foreground.png (adaptive icon) 🐛 Bug Fixes: - Fixed version display showing hardcoded "1.0.0" - Fixed Sort By and Default View showing static text - Fixed ConsumerWidget build signatures - Fixed Location.displayName import issues - Added clearAllData method to Hive database 📊 Stats: +1,728 additions, -756 deletions across 42 files 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
100 lines
2.7 KiB
Dart
100 lines
2.7 KiB
Dart
import 'package:hive_flutter/hive_flutter.dart';
|
|
import '../../features/inventory/models/food_item.dart';
|
|
import '../../features/settings/models/app_settings.dart';
|
|
import '../../features/settings/models/household.dart';
|
|
|
|
/// Singleton class to manage Hive database
|
|
class HiveDatabase {
|
|
static bool _initialized = false;
|
|
|
|
/// Initialize Hive
|
|
static Future<void> init() async {
|
|
if (_initialized) return;
|
|
|
|
await Hive.initFlutter();
|
|
|
|
// Register adapters
|
|
Hive.registerAdapter(FoodItemAdapter());
|
|
Hive.registerAdapter(LocationAdapter());
|
|
Hive.registerAdapter(ExpirationStatusAdapter());
|
|
Hive.registerAdapter(AppSettingsAdapter());
|
|
Hive.registerAdapter(HouseholdAdapter());
|
|
|
|
_initialized = true;
|
|
}
|
|
|
|
/// Get the food items box
|
|
static Future<Box<FoodItem>> getFoodBox() async {
|
|
if (!Hive.isBoxOpen('foodItems')) {
|
|
return await Hive.openBox<FoodItem>('foodItems');
|
|
}
|
|
return Hive.box<FoodItem>('foodItems');
|
|
}
|
|
|
|
/// Get the settings box
|
|
static Future<Box<AppSettings>> getSettingsBox() async {
|
|
if (!Hive.isBoxOpen('appSettings')) {
|
|
return await Hive.openBox<AppSettings>('appSettings');
|
|
}
|
|
return Hive.box<AppSettings>('appSettings');
|
|
}
|
|
|
|
/// Get or create app settings
|
|
static Future<AppSettings> getSettings() async {
|
|
final box = await getSettingsBox();
|
|
if (box.isEmpty) {
|
|
final settings = AppSettings();
|
|
await box.add(settings);
|
|
return settings;
|
|
}
|
|
return box.getAt(0)!;
|
|
}
|
|
|
|
/// Get the households box
|
|
static Future<Box<Household>> getHouseholdsBox() async {
|
|
if (!Hive.isBoxOpen('households')) {
|
|
return await Hive.openBox<Household>('households');
|
|
}
|
|
return Hive.box<Household>('households');
|
|
}
|
|
|
|
/// Get household by ID
|
|
static Future<Household?> getHousehold(String id) async {
|
|
final box = await getHouseholdsBox();
|
|
return box.values.firstWhere(
|
|
(h) => h.id == id,
|
|
orElse: () => throw Exception('Household not found'),
|
|
);
|
|
}
|
|
|
|
/// Save household
|
|
static Future<void> saveHousehold(Household household) async {
|
|
final box = await getHouseholdsBox();
|
|
await box.put(household.id, household);
|
|
}
|
|
|
|
/// Clear all food items
|
|
static Future<void> clearAll() async {
|
|
final box = await getFoodBox();
|
|
await box.clear();
|
|
}
|
|
|
|
/// Clear ALL data (food, settings, households)
|
|
static Future<void> clearAllData() async {
|
|
final foodBox = await getFoodBox();
|
|
final settingsBox = await getSettingsBox();
|
|
final householdsBox = await getHouseholdsBox();
|
|
|
|
await foodBox.clear();
|
|
await settingsBox.clear();
|
|
await householdsBox.clear();
|
|
|
|
print('✅ All data cleared from Hive');
|
|
}
|
|
|
|
/// Close all boxes
|
|
static Future<void> closeAll() async {
|
|
await Hive.close();
|
|
}
|
|
}
|