creek

The AI Image Editor of 2030

lib/main.dart (4508B)


  1import 'dart:async';
  2import 'package:flutter/material.dart';
  3import 'package:flutter_dotenv/flutter_dotenv.dart';
  4import 'package:receive_sharing_intent/receive_sharing_intent.dart';
  5import 'package:creekui/services/theme_service.dart';
  6import 'package:creekui/ui/pages/share_handler_page.dart';
  7import 'package:creekui/ui/pages/home_page.dart';
  8import 'package:creekui/services/analysis_queue_manager.dart';
  9import 'package:flutter/services.dart';
 10
 11void main() async {
 12  WidgetsFlutterBinding.ensureInitialized();
 13  await dotenv.load(fileName: ".env");
 14  AnalysisQueueManager().processQueue();
 15  runApp(const MyApp());
 16}
 17
 18class MyApp extends StatefulWidget {
 19  const MyApp({super.key});
 20
 21  @override
 22  State<MyApp> createState() => _MyAppState();
 23}
 24
 25class _MyAppState extends State<MyApp> {
 26  late StreamSubscription _intentStreamSubscription;
 27  final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
 28
 29  bool _isReady = false;
 30
 31  @override
 32  void initState() {
 33    super.initState();
 34    _initApp();
 35  }
 36
 37  Future<void> _initApp() async {
 38    // 1. Load Theme
 39    try {
 40      await themeService.loadTheme();
 41    } catch (e) {
 42      debugPrint("Theme load error (ignoring): $e");
 43    }
 44
 45    // 2. Setup Share Listeneer
 46    try {
 47      _intentStreamSubscription = ReceiveSharingIntent.instance
 48          .getMediaStream()
 49          .listen((List<SharedMediaFile> value) {
 50            if (value.isNotEmpty) {
 51              _handleShare(value.first.path);
 52            }
 53          }, onError: (err) => debugPrint("Share error: $err"));
 54
 55      // 3. Cold Start
 56      ReceiveSharingIntent.instance.getInitialMedia().then((
 57        List<SharedMediaFile> value,
 58      ) {
 59        if (value.isNotEmpty) {
 60          _handleShare(value.first.path);
 61          ReceiveSharingIntent.instance.reset();
 62        }
 63      });
 64    } catch (e) {
 65      debugPrint("Share intent error: $e");
 66    }
 67
 68    themeService.addListener(_updateTheme);
 69
 70    if (mounted) setState(() => _isReady = true);
 71  }
 72
 73  Future<void> _handleShare(String content) async {
 74    final context = _navigatorKey.currentState?.overlay?.context;
 75    if (context == null) return;
 76
 77    // 1. Determine destination (Files vs Moodboards)
 78    String shareDestination = 'moodboards'; // Default
 79    try {
 80      const platform = MethodChannel('com.creek.ui/methods');
 81      final result = await platform.invokeMethod<String>('getShareSource');
 82      if (result != null) shareDestination = result;
 83    } catch (e) {
 84      debugPrint("Error getting share source: $e");
 85    }
 86
 87    // 2. Pass destination to the Handler Page
 88    _navigatorKey.currentState?.push(
 89      MaterialPageRoute(
 90        builder:
 91            (_) => ShareHandlerPage(
 92              sharedText: content,
 93              destination: shareDestination, // Pass the destination here
 94            ),
 95      ),
 96    );
 97  }
 98
 99  void _updateTheme() {
100    if (mounted) setState(() {});
101  }
102
103  @override
104  void dispose() {
105    _intentStreamSubscription.cancel();
106    themeService.removeListener(_updateTheme);
107    super.dispose();
108  }
109
110  @override
111  Widget build(BuildContext context) {
112    if (!_isReady) {
113      return const MaterialApp(
114        debugShowCheckedModeBanner: false,
115        home: Scaffold(
116          backgroundColor: Colors.white,
117          body: Center(child: CircularProgressIndicator()),
118        ),
119      );
120    }
121
122    return MaterialApp(
123      navigatorKey: _navigatorKey,
124      debugShowCheckedModeBanner: false,
125
126      // Theme Configuration
127      // themeMode: themeService.mode,
128      themeMode: ThemeMode.light,
129
130      theme: ThemeData(
131        fontFamily: 'GeneralSans',
132        colorScheme: ColorScheme.fromSeed(
133          seedColor: Colors.blue,
134          brightness: Brightness.light,
135        ),
136        useMaterial3: true,
137        scaffoldBackgroundColor: Colors.white,
138        appBarTheme: const AppBarTheme(
139          backgroundColor: Colors.white,
140          foregroundColor: Colors.black,
141          surfaceTintColor: Colors.transparent,
142        ),
143      ),
144      darkTheme: ThemeData(
145        fontFamily: 'GeneralSans',
146        colorScheme: ColorScheme.fromSeed(
147          seedColor: Colors.blue,
148          brightness: Brightness.dark,
149        ),
150        useMaterial3: true,
151        scaffoldBackgroundColor: Colors.grey[900],
152        appBarTheme: AppBarTheme(
153          backgroundColor: Colors.grey[900],
154          foregroundColor: Colors.white,
155          surfaceTintColor: Colors.transparent,
156        ),
157      ),
158      home: const HomePage(),
159    );
160  }
161}