✨ 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>
85 lines
2.7 KiB
Dart
85 lines
2.7 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:supabase_flutter/supabase_flutter.dart';
|
|
import 'core/constants/app_theme.dart';
|
|
import 'data/local/hive_database.dart';
|
|
import 'features/home/screens/home_screen.dart';
|
|
import 'features/settings/models/app_settings.dart';
|
|
|
|
// Provider to watch settings for dark mode
|
|
final settingsProvider = StreamProvider<AppSettings>((ref) async* {
|
|
final settings = await HiveDatabase.getSettings();
|
|
yield settings;
|
|
// Listen for changes (this will update when settings change)
|
|
while (true) {
|
|
await Future.delayed(const Duration(milliseconds: 500));
|
|
final updatedSettings = await HiveDatabase.getSettings();
|
|
yield updatedSettings;
|
|
}
|
|
});
|
|
|
|
void main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
// Initialize Hive database
|
|
await HiveDatabase.init();
|
|
|
|
// Initialize Supabase (FOSS Firebase alternative!)
|
|
// Cloud-first with optional self-hosting!
|
|
final settings = await HiveDatabase.getSettings();
|
|
|
|
// Default to hosted Supabase, or use custom server if configured
|
|
final supabaseUrl = settings.supabaseUrl ?? 'https://pxjvvduzlqediugxyasu.supabase.co';
|
|
final supabaseKey = settings.supabaseAnonKey ??
|
|
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InB4anZ2ZHV6bHFlZGl1Z3h5YXN1Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTk2MTUwNjQsImV4cCI6MjA3NTE5MTA2NH0.gPScm4q4PUDDqnFezYRQnVntiqq-glSIwzSWBhQyzwU';
|
|
|
|
await Supabase.initialize(
|
|
url: supabaseUrl,
|
|
anonKey: supabaseKey,
|
|
);
|
|
|
|
if (settings.supabaseUrl != null) {
|
|
print('✅ Using custom Supabase server: ${settings.supabaseUrl}');
|
|
} else {
|
|
print('✅ Using hosted Sage sync server (Supabase FOSS backend)');
|
|
}
|
|
|
|
runApp(
|
|
const ProviderScope(
|
|
child: SageApp(),
|
|
),
|
|
);
|
|
}
|
|
|
|
class SageApp extends ConsumerWidget {
|
|
const SageApp({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final settingsAsync = ref.watch(settingsProvider);
|
|
|
|
return settingsAsync.when(
|
|
data: (settings) => MaterialApp(
|
|
title: 'Sage 🌿',
|
|
debugShowCheckedModeBanner: false,
|
|
theme: AppTheme.lightTheme,
|
|
darkTheme: AppTheme.darkTheme,
|
|
themeMode: settings.darkModeEnabled ? ThemeMode.dark : ThemeMode.light,
|
|
home: const HomeScreen(),
|
|
),
|
|
loading: () => const MaterialApp(
|
|
debugShowCheckedModeBanner: false,
|
|
home: Scaffold(
|
|
body: Center(child: CircularProgressIndicator()),
|
|
),
|
|
),
|
|
error: (_, __) => const MaterialApp(
|
|
debugShowCheckedModeBanner: false,
|
|
home: Scaffold(
|
|
body: Center(child: Text('Error loading settings')),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|