v1.3.0+4: FOSS Compliance + Dark Mode + Enhanced Settings
✨ 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>
This commit is contained in:
@@ -1,26 +1,49 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:firebase_core/firebase_core.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 Firebase (gracefully handle if not configured)
|
||||
try {
|
||||
await Firebase.initializeApp();
|
||||
print('✅ Firebase initialized successfully');
|
||||
} catch (e) {
|
||||
print('⚠️ Firebase initialization failed: $e');
|
||||
print('Household sharing will not work without Firebase configuration.');
|
||||
print('See FIREBASE_SETUP.md for setup instructions.');
|
||||
}
|
||||
|
||||
// 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(),
|
||||
@@ -28,18 +51,34 @@ void main() async {
|
||||
);
|
||||
}
|
||||
|
||||
class SageApp extends StatelessWidget {
|
||||
class SageApp extends ConsumerWidget {
|
||||
const SageApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Sage 🌿',
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: AppTheme.lightTheme,
|
||||
darkTheme: AppTheme.darkTheme,
|
||||
themeMode: ThemeMode.light, // We'll make this dynamic later
|
||||
home: const HomeScreen(),
|
||||
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')),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user