|
1 | 1 | import 'dart:convert'; |
| 2 | +import 'dart:io'; |
2 | 3 |
|
3 | 4 | import 'package:flutter/material.dart'; |
4 | 5 | import 'package:get/get.dart'; |
| 6 | +import 'package:share_plus/share_plus.dart'; |
5 | 7 |
|
6 | 8 | import '../models/download_job.dart'; |
7 | 9 | import '../services/analytics_service.dart'; |
8 | 10 | import '../services/download_queue_service.dart'; |
9 | 11 | import '../services/notification_service.dart'; |
| 12 | +import '../status_saver/utils/video_play.dart'; |
10 | 13 |
|
11 | 14 | class DownloadQueueScreen extends StatefulWidget { |
12 | 15 | const DownloadQueueScreen({super.key}); |
@@ -41,6 +44,70 @@ class _DownloadQueueScreenState extends State<DownloadQueueScreen> { |
41 | 44 | super.dispose(); |
42 | 45 | } |
43 | 46 |
|
| 47 | + bool _isPlayableVideo(String path) { |
| 48 | + final lower = path.toLowerCase(); |
| 49 | + return lower.endsWith('.mp4') || |
| 50 | + lower.endsWith('.mov') || |
| 51 | + lower.endsWith('.m4v') || |
| 52 | + lower.endsWith('.webm') || |
| 53 | + lower.endsWith('.mkv') || |
| 54 | + lower.endsWith('.3gp'); |
| 55 | + } |
| 56 | + |
| 57 | + Future<void> _shareDownloadedFile(DownloadJob job) async { |
| 58 | + final path = job.filePath; |
| 59 | + if (path == null || path.isEmpty) { |
| 60 | + if (!mounted) return; |
| 61 | + ScaffoldMessenger.of(context).showSnackBar( |
| 62 | + const SnackBar(content: Text('File path unavailable for sharing.')), |
| 63 | + ); |
| 64 | + return; |
| 65 | + } |
| 66 | + |
| 67 | + final file = File(path); |
| 68 | + if (!await file.exists()) { |
| 69 | + if (!mounted) return; |
| 70 | + ScaffoldMessenger.of(context).showSnackBar( |
| 71 | + const SnackBar(content: Text('Downloaded file is missing.')), |
| 72 | + ); |
| 73 | + return; |
| 74 | + } |
| 75 | + |
| 76 | + await SharePlus.instance.share( |
| 77 | + ShareParams( |
| 78 | + files: [XFile(path)], |
| 79 | + text: job.fileName, |
| 80 | + subject: 'Shared from Insta Downloader', |
| 81 | + ), |
| 82 | + ); |
| 83 | + } |
| 84 | + |
| 85 | + Future<void> _playDownloadedVideo(DownloadJob job) async { |
| 86 | + final path = job.filePath; |
| 87 | + if (path == null || path.isEmpty) { |
| 88 | + if (!mounted) return; |
| 89 | + ScaffoldMessenger.of(context).showSnackBar( |
| 90 | + const SnackBar(content: Text('Video path unavailable.')), |
| 91 | + ); |
| 92 | + return; |
| 93 | + } |
| 94 | + |
| 95 | + final file = File(path); |
| 96 | + if (!await file.exists()) { |
| 97 | + if (!mounted) return; |
| 98 | + ScaffoldMessenger.of(context).showSnackBar( |
| 99 | + const SnackBar(content: Text('Video file is missing.')), |
| 100 | + ); |
| 101 | + return; |
| 102 | + } |
| 103 | + |
| 104 | + if (!mounted) return; |
| 105 | + await Navigator.push( |
| 106 | + context, |
| 107 | + MaterialPageRoute(builder: (_) => PlayStatus(videoFile: path)), |
| 108 | + ); |
| 109 | + } |
| 110 | + |
44 | 111 | @override |
45 | 112 | Widget build(BuildContext context) { |
46 | 113 | return DefaultTabController( |
@@ -165,12 +232,30 @@ class _DownloadQueueScreenState extends State<DownloadQueueScreen> { |
165 | 232 | subtitle: Text( |
166 | 233 | '${NotificationService.to.getTypeLabel(job.type)} - ${job.status.name}', |
167 | 234 | ), |
168 | | - trailing: job.status == DownloadStatus.failed |
169 | | - ? IconButton( |
| 235 | + trailing: Row( |
| 236 | + mainAxisSize: MainAxisSize.min, |
| 237 | + children: [ |
| 238 | + if (job.status == DownloadStatus.success && job.filePath != null) |
| 239 | + IconButton( |
| 240 | + tooltip: 'Share', |
| 241 | + icon: const Icon(Icons.share), |
| 242 | + onPressed: () => _shareDownloadedFile(job), |
| 243 | + ), |
| 244 | + if (job.status == DownloadStatus.success && |
| 245 | + job.filePath != null && |
| 246 | + _isPlayableVideo(job.filePath!)) |
| 247 | + IconButton( |
| 248 | + tooltip: 'Play', |
| 249 | + icon: const Icon(Icons.play_circle), |
| 250 | + onPressed: () => _playDownloadedVideo(job), |
| 251 | + ), |
| 252 | + if (job.status == DownloadStatus.failed) |
| 253 | + IconButton( |
170 | 254 | icon: const Icon(Icons.refresh), |
171 | 255 | onPressed: () => queue.retry(job.id), |
172 | | - ) |
173 | | - : null, |
| 256 | + ), |
| 257 | + ], |
| 258 | + ), |
174 | 259 | ); |
175 | 260 | }, |
176 | 261 | ); |
|
0 commit comments