import 'package:flutter/material.dart'; import '../data/models.dart'; import '../state/app_state.dart'; import 'download_service.dart'; import 'downloads_page.dart'; typedef EnqueueDownload = Future Function({ required TitleRecord title, required MediaSource source, EpisodeRecord? episode, }); /// The primary action always queues inside Reelbox, never an external app. class DownloadButton extends StatefulWidget { const DownloadButton({ super.key, required this.title, required this.source, this.episode, this.enqueue, this.openDownloads, }); final TitleRecord title; final MediaSource source; final EpisodeRecord? episode; final EnqueueDownload? enqueue; final void Function(BuildContext context)? openDownloads; @override State createState() => _DownloadButtonState(); } class _DownloadButtonState extends State { bool _starting = false; Future _download() async { if (_starting) return; setState(() => _starting = true); try { final host = Uri.tryParse(widget.source.url)?.host.toLowerCase() ?? ''; if (RegExp( 'youtube|embed', caseSensitive: false, ).hasMatch(widget.source.type) || host == 'youtu.be' || host == 'youtube.com' || host.endsWith('.youtube.com')) { throw UnsupportedError( tr( context, 'Embedded sources cannot be downloaded. Choose a direct media source.', 'منابع جاسازی‌شده قابل دانلود نیستند. یک منبع رسانه مستقیم انتخاب کنید.', ), ); } await (widget.enqueue ?? DownloadService.instance.enqueue)( title: widget.title, source: widget.source, episode: widget.episode, ); if (!mounted) return; if (widget.openDownloads case final open?) { open(context); } else { Navigator.of( context, ).push(MaterialPageRoute(builder: (_) => const DownloadsPage())); } } catch (error) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( '${tr(context, 'Could not start download', 'شروع دانلود ممکن نشد')}: ${downloadErrorMessage(error)}', ), ), ); } } finally { if (mounted) setState(() => _starting = false); } } @override Widget build(BuildContext context) => FilledButton.icon( onPressed: widget.source.url.isEmpty || _starting ? null : _download, icon: _starting ? const SizedBox.square( dimension: 18, child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.download_outlined), label: Text(tr(context, 'Download in Reelbox', 'دانلود در ریلباکس')), ); }