Ahora el Batch se pueden añadir tags
This commit is contained in:
@@ -6,7 +6,6 @@ import 'package:energy_media/models/media/media_models.dart';
|
|||||||
import 'package:energy_media/theme/theme.dart';
|
import 'package:energy_media/theme/theme.dart';
|
||||||
import 'package:energy_media/helpers/globals.dart';
|
import 'package:energy_media/helpers/globals.dart';
|
||||||
import 'package:energy_media/widgets/premium_button.dart';
|
import 'package:energy_media/widgets/premium_button.dart';
|
||||||
import 'package:energy_media/pages/videos/widgets/premium_upload_dialog.dart';
|
|
||||||
import 'package:energy_media/pages/videos/widgets/premium_batch_upload_dialog.dart';
|
import 'package:energy_media/pages/videos/widgets/premium_batch_upload_dialog.dart';
|
||||||
import 'package:energy_media/pages/videos/widgets/video_player_dialog.dart';
|
import 'package:energy_media/pages/videos/widgets/video_player_dialog.dart';
|
||||||
import 'package:energy_media/pages/videos/widgets/gestor_videos_widgets/empty_state_widget.dart';
|
import 'package:energy_media/pages/videos/widgets/gestor_videos_widgets/empty_state_widget.dart';
|
||||||
@@ -132,7 +131,7 @@ class _GestorVideosPageState extends State<GestorVideosPage> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: provider.mediaFiles.isEmpty
|
child: provider.mediaFiles.isEmpty
|
||||||
? EmptyStateWidget(
|
? EmptyStateWidget(
|
||||||
onUploadPressed: () => _showUploadDialog(provider),
|
onUploadPressed: () => _showBatchUploadDialog(provider),
|
||||||
)
|
)
|
||||||
: ListView.builder(
|
: ListView.builder(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
@@ -177,7 +176,7 @@ class _GestorVideosPageState extends State<GestorVideosPage> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (isMobile) ...[
|
if (isMobile) ...[
|
||||||
// Vista móvil: solo botón centrado con diseño mejorado
|
// Vista móvil: botón único para subir videos
|
||||||
Center(
|
Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
@@ -200,64 +199,6 @@ class _GestorVideosPageState extends State<GestorVideosPage> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: Material(
|
|
||||||
color: Colors.transparent,
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () => _showUploadDialog(provider),
|
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 24, vertical: 16),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
const Icon(
|
|
||||||
Icons.cloud_upload_rounded,
|
|
||||||
color: Color(0xFF0B0B0D),
|
|
||||||
size: 24,
|
|
||||||
),
|
|
||||||
const Gap(12),
|
|
||||||
Text(
|
|
||||||
'Subir Video',
|
|
||||||
style: const TextStyle(
|
|
||||||
color: Color(0xFF0B0B0D),
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
fontFamily: 'Poppins',
|
|
||||||
letterSpacing: 0.5,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Gap(12),
|
|
||||||
// Botón subida masiva móvil
|
|
||||||
Center(
|
|
||||||
child: Container(
|
|
||||||
width: double.infinity,
|
|
||||||
constraints: const BoxConstraints(maxWidth: 300),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: const LinearGradient(
|
|
||||||
begin: Alignment.topLeft,
|
|
||||||
end: Alignment.bottomRight,
|
|
||||||
colors: [
|
|
||||||
Color(0xFF6B2F8A),
|
|
||||||
Color(0xFF4EC9F5),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: const Color(0xFF6B2F8A).withOpacity(0.4),
|
|
||||||
blurRadius: 12,
|
|
||||||
offset: const Offset(0, 4),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Material(
|
child: Material(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
@@ -270,15 +211,15 @@ class _GestorVideosPageState extends State<GestorVideosPage> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(
|
||||||
Icons.cloud_upload_outlined,
|
Icons.cloud_upload_rounded,
|
||||||
color: Colors.white,
|
color: Color(0xFF0B0B0D),
|
||||||
size: 24,
|
size: 24,
|
||||||
),
|
),
|
||||||
Gap(12),
|
Gap(12),
|
||||||
Text(
|
Text(
|
||||||
'Subida Masiva',
|
'Subir Videos',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: Color(0xFF0B0B0D),
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
fontFamily: 'Poppins',
|
fontFamily: 'Poppins',
|
||||||
@@ -337,16 +278,9 @@ class _GestorVideosPageState extends State<GestorVideosPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
PremiumButton(
|
PremiumButton(
|
||||||
text: 'Subir Video',
|
text: 'Subir Videos',
|
||||||
icon: Icons.cloud_upload,
|
icon: Icons.cloud_upload_rounded,
|
||||||
onPressed: () => _showUploadDialog(provider),
|
|
||||||
),
|
|
||||||
const Gap(12),
|
|
||||||
PremiumButton(
|
|
||||||
text: 'Subida Masiva',
|
|
||||||
icon: Icons.cloud_upload_outlined,
|
|
||||||
onPressed: () => _showBatchUploadDialog(provider),
|
onPressed: () => _showBatchUploadDialog(provider),
|
||||||
backgroundColor: const Color(0xFF6B2F8A),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -1325,19 +1259,6 @@ class _GestorVideosPageState extends State<GestorVideosPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _showUploadDialog(VideosProvider provider) async {
|
|
||||||
await showDialog(
|
|
||||||
context: context,
|
|
||||||
barrierDismissible: false,
|
|
||||||
builder: (context) => PremiumUploadDialog(
|
|
||||||
provider: provider,
|
|
||||||
onSuccess: () {
|
|
||||||
_loadData();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _showBatchUploadDialog(VideosProvider provider) async {
|
Future<void> _showBatchUploadDialog(VideosProvider provider) async {
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class BatchVideoItem {
|
|||||||
String fileName;
|
String fileName;
|
||||||
String title;
|
String title;
|
||||||
String description;
|
String description;
|
||||||
|
List<String> tags;
|
||||||
Uint8List videoBytes;
|
Uint8List videoBytes;
|
||||||
Uint8List? posterBytes;
|
Uint8List? posterBytes;
|
||||||
String? posterFileName;
|
String? posterFileName;
|
||||||
@@ -31,6 +32,7 @@ class BatchVideoItem {
|
|||||||
required this.title,
|
required this.title,
|
||||||
required this.videoBytes,
|
required this.videoBytes,
|
||||||
this.description = '',
|
this.description = '',
|
||||||
|
this.tags = const [],
|
||||||
this.posterBytes,
|
this.posterBytes,
|
||||||
this.posterFileName,
|
this.posterFileName,
|
||||||
this.blobUrl,
|
this.blobUrl,
|
||||||
@@ -126,6 +128,7 @@ class _PremiumBatchUploadDialogState extends State<PremiumBatchUploadDialog> {
|
|||||||
videoBytes: bytes,
|
videoBytes: bytes,
|
||||||
blobUrl: blobUrl,
|
blobUrl: blobUrl,
|
||||||
durationSeconds: duration,
|
durationSeconds: duration,
|
||||||
|
tags: [], // Lista mutable para tags
|
||||||
);
|
);
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -299,6 +302,7 @@ class _PremiumBatchUploadDialogState extends State<PremiumBatchUploadDialog> {
|
|||||||
title: video.title,
|
title: video.title,
|
||||||
description: video.description.isEmpty ? null : video.description,
|
description: video.description.isEmpty ? null : video.description,
|
||||||
durationSeconds: video.durationSeconds,
|
durationSeconds: video.durationSeconds,
|
||||||
|
tags: video.tags.isNotEmpty ? video.tags : null,
|
||||||
);
|
);
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
@@ -482,7 +486,7 @@ class _PremiumBatchUploadDialogState extends State<PremiumBatchUploadDialog> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const Text(
|
const Text(
|
||||||
'Subida Masiva de Videos',
|
'Subir Videos',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
@@ -493,7 +497,7 @@ class _PremiumBatchUploadDialogState extends State<PremiumBatchUploadDialog> {
|
|||||||
const Gap(4),
|
const Gap(4),
|
||||||
Text(
|
Text(
|
||||||
_videoQueue.isEmpty
|
_videoQueue.isEmpty
|
||||||
? 'Selecciona múltiples videos para subir'
|
? 'Selecciona uno o varios videos'
|
||||||
: '${_videoQueue.length} video(s) en cola',
|
: '${_videoQueue.length} video(s) en cola',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white.withOpacity(0.8),
|
color: Colors.white.withOpacity(0.8),
|
||||||
@@ -884,6 +888,110 @@ class _PremiumBatchUploadDialogState extends State<PremiumBatchUploadDialog> {
|
|||||||
isDense: true,
|
isDense: true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const Gap(8),
|
||||||
|
// Tags
|
||||||
|
_buildTagsField(video, isEditable),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildTagsField(BatchVideoItem video, bool isEditable) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// Mostrar tags existentes como chips
|
||||||
|
if (video.tags.isNotEmpty)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 8),
|
||||||
|
child: Wrap(
|
||||||
|
spacing: 6,
|
||||||
|
runSpacing: 6,
|
||||||
|
children: video.tags.map((tag) {
|
||||||
|
return Container(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
const Color(0xFF4EC9F5).withOpacity(0.2),
|
||||||
|
const Color(0xFFFFB733).withOpacity(0.2),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
border: Border.all(
|
||||||
|
color: const Color(0xFF4EC9F5).withOpacity(0.3),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
tag,
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppTheme.of(context).primaryText,
|
||||||
|
fontFamily: 'Poppins',
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (isEditable) ...[
|
||||||
|
const Gap(4),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
video.tags = List.from(video.tags)..remove(tag);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Icon(
|
||||||
|
Icons.close_rounded,
|
||||||
|
size: 14,
|
||||||
|
color: AppTheme.of(context).tertiaryText,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Campo para agregar nuevo tag
|
||||||
|
TextField(
|
||||||
|
enabled: isEditable,
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppTheme.of(context).primaryText,
|
||||||
|
fontFamily: 'Poppins',
|
||||||
|
fontSize: 13,
|
||||||
|
),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'Agregar tag y presiona Enter',
|
||||||
|
hintStyle: TextStyle(
|
||||||
|
color: AppTheme.of(context).tertiaryText,
|
||||||
|
),
|
||||||
|
prefixIcon: Icon(
|
||||||
|
Icons.label_rounded,
|
||||||
|
color: const Color(0xFFFFB733),
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
filled: true,
|
||||||
|
fillColor: AppTheme.of(context).secondaryBackground,
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide.none,
|
||||||
|
),
|
||||||
|
contentPadding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
|
||||||
|
isDense: true,
|
||||||
|
),
|
||||||
|
onSubmitted: (value) {
|
||||||
|
final tag = value.trim();
|
||||||
|
if (tag.isNotEmpty && !video.tags.contains(tag)) {
|
||||||
|
setState(() {
|
||||||
|
video.tags = List.from(video.tags)..add(tag);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user