creek

The AI Image Editor of 2030

lib/ui/pages/share_handler_page.dart (5475B)


  1import 'dart:io';
  2import 'package:flutter/material.dart';
  3import 'package:creekui/services/download_service.dart';
  4import 'package:creekui/services/instagram_download_service.dart';
  5import 'package:creekui/services/image_service.dart';
  6import 'package:creekui/ui/styles/variables.dart';
  7import 'package:creekui/ui/widgets/primary_button.dart';
  8import 'package:creekui/ui/widgets/app_bar.dart';
  9import 'share_to_moodboard_page.dart';
 10import 'share_to_file_page.dart';
 11
 12class ShareHandlerPage extends StatefulWidget {
 13  final String sharedText;
 14  final String destination;
 15
 16  const ShareHandlerPage({
 17    super.key,
 18    required this.sharedText,
 19    required this.destination,
 20  });
 21
 22  @override
 23  State<ShareHandlerPage> createState() => _ShareHandlerPageState();
 24}
 25
 26class _ShareHandlerPageState extends State<ShareHandlerPage> {
 27  final _downloadService = DownloadService();
 28  final _instagramService = InstagramDownloadService();
 29  final _imageService = ImageService();
 30
 31  bool _hasError = false;
 32  String? _errorMessage;
 33
 34  @override
 35  void initState() {
 36    super.initState();
 37    _processSharedContent();
 38  }
 39
 40  Future<void> _processSharedContent() async {
 41    final sharedContent = widget.sharedText.trim();
 42    List<File> tempFiles = [];
 43
 44    try {
 45      // CASE A: Local File Path
 46      if (await File(sharedContent).exists()) {
 47        tempFiles.add(File(sharedContent));
 48      }
 49      // CASE B: URL
 50      else {
 51        final urlRegExp = RegExp(r'(https?://\S+)');
 52        final match = urlRegExp.firstMatch(sharedContent);
 53
 54        if (match != null) {
 55          final url = match.group(0)!;
 56          if (url.contains('instagram.com')) {
 57            // Instagram Logic
 58            final downloadedPaths = await _instagramService
 59                .downloadInstagramImage(url);
 60            if (downloadedPaths != null && downloadedPaths.isNotEmpty) {
 61              tempFiles.addAll(downloadedPaths.map((path) => File(path)));
 62            }
 63          } else {
 64            // Generic Download Logic
 65            final savedPath = await _downloadService.downloadAndSaveImage(url);
 66            if (savedPath != null) {
 67              tempFiles.add(File(savedPath));
 68            }
 69          }
 70        } else {
 71          throw Exception("Invalid content: Not a valid file path or URL.");
 72        }
 73      }
 74
 75      // Success: Route based on Destination
 76      if (tempFiles.isNotEmpty) {
 77        if (!mounted) return;
 78        if (widget.destination == 'files') {
 79          // Files
 80          Navigator.pushReplacement(
 81            context,
 82            MaterialPageRoute(
 83              builder: (_) => ShareToFilePage(sharedImage: tempFiles.first),
 84            ),
 85          );
 86        } else {
 87          // Moodboard
 88          List<File> permanentFiles = [];
 89          for (var file in tempFiles) {
 90            final id = await _imageService.saveImage(file, 0, tags: []);
 91            final savedImage = await _imageService.getImage(id);
 92            if (savedImage != null) {
 93              permanentFiles.add(File(savedImage.filePath));
 94            }
 95          }
 96          if (mounted) {
 97            Navigator.pushReplacement(
 98              context,
 99              MaterialPageRoute(
100                builder:
101                    (_) => ShareToMoodboardPage(imageFiles: permanentFiles),
102              ),
103            );
104          }
105        }
106      } else {
107        throw Exception("Could not retrieve any media files.");
108      }
109    } catch (e) {
110      if (mounted) {
111        setState(() {
112          _hasError = true;
113          _errorMessage = e.toString();
114        });
115      }
116    }
117  }
118
119  @override
120  Widget build(BuildContext context) {
121    return Scaffold(
122      backgroundColor: Variables.background,
123      appBar: const CommonAppBar(title: "Processing", showBack: false),
124      body: Center(
125        child:
126            _hasError
127                ? Padding(
128                  padding: const EdgeInsets.all(24.0),
129                  child: Column(
130                    mainAxisAlignment: MainAxisAlignment.center,
131                    children: [
132                      const Icon(
133                        Icons.error_outline,
134                        color: Colors.red,
135                        size: 50,
136                      ),
137                      const SizedBox(height: 16),
138                      Text(
139                        "Error processing media",
140                        style: Variables.headerStyle.copyWith(fontSize: 18),
141                      ),
142                      const SizedBox(height: 8),
143                      Text(
144                        _errorMessage ?? "Unknown Error",
145                        textAlign: TextAlign.center,
146                        style: const TextStyle(color: Colors.grey),
147                      ),
148                      const SizedBox(height: 24),
149                      SizedBox(
150                        width: 200,
151                        child: PrimaryButton(
152                          text: "Close",
153                          onPressed: () => Navigator.pop(context),
154                        ),
155                      ),
156                    ],
157                  ),
158                )
159                : const Column(
160                  mainAxisAlignment: MainAxisAlignment.center,
161                  children: [
162                    CircularProgressIndicator(color: Variables.textPrimary),
163                    SizedBox(height: 20),
164                    Text("Downloading media..."),
165                  ],
166                ),
167      ),
168    );
169  }
170}