Files
Sage/lib/main.dart
Dani 7ab641a3c8 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>
2025-10-04 22:27:42 -04:00

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')),
),
),
);
}
}