Files
energymedia_content_manager/assets/referencia/videos_provider.txt
2025-07-16 13:53:23 -07:00

1250 lines
38 KiB
Plaintext

import 'dart:convert';
import 'dart:typed_data';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:file_picker/_internal/file_picker_web.dart';
import 'package:file_picker/file_picker.dart';
import 'package:image_picker/image_picker.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:pluto_grid/pluto_grid.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:path/path.dart' as p;
import 'package:cbluna_crm_lu/helpers/globals.dart';
import 'package:cbluna_crm_lu/models/content_manager/ad_by_genre.dart';
import 'package:cbluna_crm_lu/pages/widgets/toasts/msj_toast.dart';
import '../../lib/models/content_manager/all_ads_one_table_model.dart';
import '../../lib/pages/widgets/video_player_caro.dart';
class VideosProvider extends ChangeNotifier {
List<PlutoGridStateManager> listStateManager = [];
PlutoGridStateManager? stateManager;
final controllerBusqueda = TextEditingController();
String parametroBusqueda = "";
TextEditingController modeloController = TextEditingController();
String? videoCoverFile;
String? videoName;
String? videoUrl;
String? videoPath;
String fileExtension = '';
String resolucion = "1";
String area = "7";
Uint8List? webVideo;
String? categoryImgFileName;
Uint8List? categoryImageToUpload;
String? categoryName;
bool noImageToUpload = true;
//-------
late final TextEditingController filasController;
//-------
List<List<dynamic>> listPagos = [];
final controllerCount = TextEditingController();
int countI = 0;
int countF = 19;
final controllerBusquedaFiltro = TextEditingController();
bool filtroAvanzado = false;
bool filtroSimple = false;
///////////////////////////////////////////
var tableTop1Gourp = AutoSizeGroup();
var tableTopGroup = AutoSizeGroup();
var tableContentGroup = AutoSizeGroup();
final busquedaVideoController = TextEditingController();
///////////////////////////////////////////
late MsjToast toastMessage;
///
///
List<AdsByGenre> adsByGenre = [];
List<List<PlutoRow>> rows = [];
List<PlutoRow> rows_ = [];
List<PlutoRow> allVideoRows = [];
List<String> listaQrsSeleccionados = [];
//----------------------------------------------Paginador variables
int seccionActual = 1;
int totalSecciones = 1;
int totalFilas = 0;
int from = 0;
int hasta = 20;
//----------------------------------------------Calendario Programacion
FilePickerResult? docProveedor;
//----------------------------------------------Video data
String? videoCoverFileNameNoModif;
List<String> videoCategories = [];
List<int> videoCategoriesId = [];
List<String> selectedVideoCategories = [];
List<int> selectedVideoCategoriesId = [];
List<String> videoCategoriesImages = [];
String? posterPath;
String tituloVideo = '';
String descripcionVideo = '';
String videoOutlink = '';
String videoPatner = '';
Uint8List? videoPoster;
int videoPoints = 0;
Duration duracionVideo = Duration.zero;
int duratinVideoSeconds = 0;
List<String> videoPriority = [];
String? videoPosterPath;
//----------------------------------------------VideoYables
bool showFullVideoTable = true;
List<AllAdsOneTableModel> videos = [];
String selectePriority = "baja";
int warningCountTablaVideos = 0;
bool showWarningsOnTable = false;
int? selectedVideoId;
//----------------------------------------------
VideosProvider() {
getVideoPrioritiesList();
getCategories();
refreshVideoTablet();
}
updateState(AdsByGenre expandir) {
expandir.isExpanded = !expandir.isExpanded;
notifyListeners();
}
getVideoData(Duration? duracion, int? duracionSegundos) async {
duracionVideo = duracion ?? Duration.zero;
duratinVideoSeconds = duracionSegundos ?? 0;
}
setVideoTableFullOrCategories(int index) {
switch (index) {
case 0:
showFullVideoTable = true;
getAllAdsOnOneTable();
break;
case 1:
showFullVideoTable = false;
getAdsByCategories();
break;
default:
showFullVideoTable = false;
getAdsByCategories();
}
notifyListeners();
return;
}
getAdsByCategories() async {
try {
final query = supabaseLU.rpc('lu_buscar_videos_por_genero', params: {
'busqueda': busquedaVideoController.text,
});
final res = await query.select();
if (res == null) {
return;
}
adsByGenre = (res as List<dynamic>)
.map((ad) => AdsByGenre.fromJson(jsonEncode(ad)))
.toList();
rows_ = [];
rows_.clear();
rows.clear();
for (var genre in adsByGenre) {
adsByGenre[adsByGenre.indexOf(genre)].videoCount = genre.videos.length;
for (var video in genre.videos) {
rows_.add(PlutoRow(cells: {
'video_id': PlutoCell(value: video.videoId.toString()),
'posterPath': PlutoCell(
value: video.posterFileName != null
? "${supabase.storage.from('lectores_urb/imagenes/videos/posters').getPublicUrl(video.posterFileName)}?${DateTime.now().millisecondsSinceEpoch}"
: ''),
'status': PlutoCell(value: video.status ?? 'neutra'),
'priority': PlutoCell(value: video.priority),
'title': PlutoCell(value: video.title),
'urlAd': PlutoCell(value: video.urlAd ?? ''),
'overview': PlutoCell(value: video.overview),
'points': PlutoCell(value: 1),
'expirationDate': PlutoCell(value: video.expirationDate ?? ''),
'created_at': PlutoCell(value: video.createdAt ?? ''),
'durationVideo': PlutoCell(value: video.duration ?? ''),
'video_url': PlutoCell(
value: video.videoUrl != null
? "${supabase.storage.from('lectores_urb/videos/cm_videos').getPublicUrl(video.videoFileName.toString())}?${DateTime.now().millisecondsSinceEpoch}"
: ''),
'editar': PlutoCell(value: video.videoId),
'eliminar': PlutoCell(value: video.videoId),
'video_file_name': PlutoCell(value: video.videoFileName.toString()),
'poster_file_name':
PlutoCell(value: video.posterFileName.toString()),
'patner': PlutoCell(value: video.partner ?? ''),
'categories': PlutoCell(value: video.categories ?? ''),
'video_status': PlutoCell(value: video.videoStatus),
}));
}
rows.add(rows_);
rows_ = [];
}
showWarningsOnTable = false;
notifyListeners();
return;
} catch (e) {
print('error en getAdsByCategories(): ${e.toString()}');
}
notifyListeners();
return;
}
getAdsByCategoriesWarnings() async {
try {
final query = supabaseLU.rpc('lu_buscar_videos_por_genero', params: {
'busqueda': busquedaVideoController.text,
});
final res = await query.select();
if (res == null) {
return;
}
adsByGenre = (res as List<dynamic>)
.map((ad) => AdsByGenre.fromJson(jsonEncode(ad)))
.toList();
rows_ = [];
rows_.clear();
rows.clear();
for (var genre in adsByGenre) {
genre.videoCount = 0;
for (var video in genre.videos!) {
if (video.categories[0] == [null] ||
video.categories[0].isEmpty ||
video.categories[0] == [""] ||
video.categories[0] == ["null"] ||
video.urlAd == null ||
video.urlAd == "" ||
video.urlAd == "null" ||
video.overview == "" ||
video.overview == "null" ||
video.partner == "" ||
video.partner == null) {
rows_.add(PlutoRow(cells: {
'video_id': PlutoCell(value: video.videoId.toString()),
'posterPath': PlutoCell(
value: video.posterFileName != null
? "${supabase.storage.from('lectores_urb/imagenes/videos/posters').getPublicUrl(video.posterFileName)}?${DateTime.now().millisecondsSinceEpoch}"
: 'https://placehold.co/150x150'),
'status': PlutoCell(value: video.status ?? 'neutra'),
'priority': PlutoCell(value: video.priority ?? '4'),
'title': PlutoCell(value: video.title),
'urlAd': PlutoCell(value: video.urlAd ?? ''),
'overview': PlutoCell(value: video.overview),
'points': PlutoCell(value: video.points ?? ''),
'expirationDate': PlutoCell(value: video.expirationDate ?? ''),
'created_at': PlutoCell(value: video.createdAt ?? ''),
'durationVideo': PlutoCell(value: video.duration ?? ''),
'video_url': PlutoCell(
value: video.videoUrl != null
? "${supabase.storage.from('lectores_urb/videos/cm_videos').getPublicUrl(video.videoFileName.toString())}?${DateTime.now().millisecondsSinceEpoch}"
: ''),
'editar': PlutoCell(value: video.videoId),
'eliminar': PlutoCell(value: video.videoId),
'video_file_name':
PlutoCell(value: video.videoFileName.toString()),
'poster_file_name':
PlutoCell(value: video.posterFileName.toString()),
'patner': PlutoCell(value: video.partner ?? ''),
'categories': PlutoCell(value: video.categories ?? ''),
'video_status': PlutoCell(value: video.videoStatus),
}));
genre.videoCount += 1;
}
}
rows.add(rows_);
rows_ = [];
}
showWarningsOnTable = true;
notifyListeners();
return;
} catch (e) {
print('error en getAdsCategoriesWarning: ${e.toString()}');
}
}
getAllAdsOnOneTable([bool warningMode = false]) async {
try {
final String query = busquedaVideoController.text.trim();
final res = await supabaseLU.rpc('lu_buscar_videos', params: {
'busqueda': query.isEmpty ? null : query,
'warningmode': false,
});
if (res == null) {
print("--X---Error: respuesta nula al llamar RPC.");
return;
}
try {
videos = (res as List<dynamic>)
.map((ad) => AllAdsOneTableModel.fromJson(jsonEncode(ad)))
.toList();
} catch (e) {
print("Error al parsear lista de videos: ${e.toString()}");
}
allVideoRows.clear();
// El warning count total lo devuelve cada fila, tomamos el primero
warningCountTablaVideos =
videos.isNotEmpty ? videos.first.warningCount : 0;
for (AllAdsOneTableModel video in videos) {
allVideoRows.add(PlutoRow(cells: {
'video_id': PlutoCell(value: video.id),
'poster_path': PlutoCell(
value: video.posterFileName != null
? "${supabase.storage.from('lectores_urb/imagenes/videos/posters').getPublicUrl(video.posterFileName)}?${DateTime.now().millisecondsSinceEpoch}"
: 'https://placehold.co/150x150'),
'priority': PlutoCell(value: video.priority),
'title': PlutoCell(value: video.title),
'url_ad': PlutoCell(value: video.urlAd ?? ''),
'overview': PlutoCell(value: video.overview),
'points': PlutoCell(value: video.points),
'expiration_date': PlutoCell(value: video.expirationDate),
'created_at': PlutoCell(value: video.createdAt),
'duration_video': PlutoCell(value: video.durationVideo),
'video_url': PlutoCell(
value: video.video.isNotEmpty
? "${video.video}?${DateTime.now().millisecondsSinceEpoch}"
: '',
),
'editar': PlutoCell(value: video.id),
'eliminar': PlutoCell(value: video.id),
'video_file_name': PlutoCell(value: video.videoFileName ?? ''),
'poster_file_name': PlutoCell(value: video.posterFileName ?? ''),
'partner': PlutoCell(value: video.partner ?? ''),
'categories': PlutoCell(value: video.categories),
'video_status': PlutoCell(value: video.videoStatus),
'qr_codes': PlutoCell(
value: video.qrCodes.expand((entry) {
try {
final details = entry['details'];
// Verifica si 'details' está presente y tiene la clave 'qrs'
if (details != null &&
details is Map<String, dynamic> &&
details['qrs'] is List) {
return (details['qrs'] as List)
.map((qrsEntry) => qrsEntry['qrs_concat'])
.whereType<String>();
}
} catch (e) {
// Si ocurre un error al intentar acceder a los datos, lo manejamos de forma silenciosa
print('Error al acceder a QR details: $e');
}
return []; // Devuelve una lista vacía en caso de error o datos inválidos
}).join('\n'), // o ', ' si prefieres en una sola línea
),
'qr_codes_list': PlutoCell(
value: video.qrCodes.expand((entry) {
try {
final details = entry['details'];
if (details != null &&
details is Map<String, dynamic> &&
details['qrs'] is List) {
return (details['qrs'] as List)
.map((qrsEntry) => qrsEntry['qrs_concat'])
.whereType<String>();
}
} catch (e) {
print('Error al acceder a QR details (lista): $e');
}
return [];
}).toList(), // ← clave aquí
),
}));
}
showWarningsOnTable = false;
notifyListeners();
} catch (e) {
print('Error en getAllAdsOnOneTable: ${e.toString()}');
notifyListeners();
}
}
getAllAdsOnOneTableWarnings() async {
try {
final res = await supabaseLU.from('videos_view').select();
if (res == null) {
print("--X---Error: ${res.error}");
return;
}
videos = (res as List<dynamic>)
.map((ad) => AllAdsOneTableModel.fromJson(jsonEncode(ad)))
.toList();
allVideoRows.clear();
for (AllAdsOneTableModel video in videos) {
if (video.categories[0] == [null] ||
video.categories[0] == null ||
video.categories[0] == [] ||
video.categories[0] == [""] ||
video.categories[0] == ["null"] ||
video.urlAd == "" ||
video.urlAd == null ||
video.urlAd == "null" ||
video.overview == "" ||
video.overview == "null" ||
video.partner == "" ||
video.partner == null) {
allVideoRows.add(PlutoRow(cells: {
'id': PlutoCell(value: video.id),
'posterPath': PlutoCell(
value: video.posterFileName != null
? "${supabase.storage.from('lectores_urb/imagenes/videos/posters').getPublicUrl(video.posterFileName)}?${DateTime.now().millisecondsSinceEpoch}"
: 'https://placehold.co/150x150'),
'priority': PlutoCell(value: video.priority ?? '4'),
'title': PlutoCell(value: video.title ?? ''),
'urlAd': PlutoCell(value: video.urlAd.toString() ?? ''),
'overview': PlutoCell(value: video.overview ?? ''),
'points': PlutoCell(value: video.points ?? ''),
'expirationDate': PlutoCell(value: video.expirationDate ?? ''),
'created_at': PlutoCell(value: video.createdAt ?? ''),
'durationVideo': PlutoCell(value: video.durationVideo ?? ''),
'video_url': PlutoCell(
value:
"${supabase.storage.from('lectores_urb/videos/cm_videos').getPublicUrl(video.videoFileName.toString())}?${DateTime.now().millisecondsSinceEpoch}"),
'editar': PlutoCell(value: video.id),
'eliminar': PlutoCell(value: video.id),
'video_file_name': PlutoCell(value: video.videoFileName ?? ''),
'poster_file_name': PlutoCell(value: video.posterFileName ?? ''),
'patner': PlutoCell(value: video.partner ?? ''),
'categories': PlutoCell(value: video.categories ?? ''),
'video_status': PlutoCell(value: video.videoStatus),
}));
}
}
showWarningsOnTable = true;
notifyListeners();
return;
} catch (e) {
print('error en getAllAdsOnOneTableWarnings: ${e.toString()}');
}
notifyListeners();
return;
}
Future<List<String>> getCategories() async {
try {
final res = await supabaseLU
.from('video_genero')
.select('name, id, poster_image_file')
.eq('visible', true)
.order('name', ascending: true);
videoCategories = (res as List<dynamic>)
.map((category) => category['name'] as String)
.toList();
videoCategoriesId = (res as List<dynamic>)
.map((category) => category['id'] as int)
.toList();
videoCategoriesImages = (res as List<dynamic>)
.map((category) => category['poster_image_file'] as String)
.toList();
return videoCategories;
} catch (e) {
print("ERROR en getVideosVinculados: " + e.toString());
notifyListeners();
return [];
}
}
//usando el id del video cambiar su estado "video_status" a true o false
cambiarEstadoVideo(int idVideo, bool estado) async {
await supabaseLU
.from('videos')
.update({'video_status': estado})
.eq('id', idVideo)
.select();
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
Widget? getPosterImage(dynamic image,
{double height = 180, BoxFit boxFit = BoxFit.cover}) {
if (image == null) {
return Image.asset('assets/images/placeholder_no_image.jpg');
} else if (image is Uint8List) {
return Image.memory(
image,
height: height,
width: double.infinity,
fit: boxFit,
);
} else if (image is String) {
return Image.network(
image,
height: height,
width: double.infinity,
filterQuality: FilterQuality.high,
fit: boxFit,
);
} else {
return Image.asset('assets/images/placeholder_no_image.jpg');
}
}
Widget? getCategoryImage(dynamic image,
{double height = 180, BoxFit boxFit = BoxFit.cover}) {
if (image == null) {
noImageToUpload = true;
return Image.asset('assets/images/placeholder_upload_image.png');
} else if (image is Uint8List) {
noImageToUpload = false;
return Image.memory(
image,
height: height,
width: double.infinity,
fit: boxFit,
);
} else if (image is String) {
noImageToUpload = false;
return Image.network(
"${supabase.storage.from('lectores_urb/imagenes/videos/categories').getPublicUrl(image)}?${DateTime.now().millisecondsSinceEpoch}",
height: height,
width: double.infinity,
filterQuality: FilterQuality.high,
fit: boxFit,
);
} else {
noImageToUpload = true;
return Image.asset('assets/images/placeholder_upload_image.png');
}
}
//get video widget VideoScreenNew;
Widget? getVideoWidget(dynamic image,
{double height = 180, width = 500, BoxFit boxFit = BoxFit.contain}) {
if (videoPath == null) {
return Image.asset('assets/images/placeholder_no_video.png',
width: width, height: height, fit: boxFit);
} else {
return VideoScreenNew(
videoUrl: videoPath,
);
}
}
/////////////CATEGORY///////////////////////
Future<void> selectCategoryImage() async {
categoryImgFileName = null;
categoryImageToUpload = null;
FilePickerResult? picker = await FilePickerWeb.platform
.pickFiles(type: FileType.custom, allowedExtensions: ['jpg', 'png']);
//get and load pdf
if (picker != null) {
var now = DateTime.now();
var formatter = DateFormat('yyyyMMddHHmmss');
var timestamp = formatter.format(now);
categoryImgFileName = 'category-$timestamp-${picker.files.single.name}';
categoryImageToUpload = picker.files.single.bytes;
noImageToUpload = false;
} else {
categoryImgFileName = null;
categoryImageToUpload = null;
}
notifyListeners();
return;
}
uploadCategoryImage() async {
if (categoryImageToUpload != null && categoryImgFileName != null) {
await supabase.storage
.from('lectores_urb/imagenes/videos/categories')
.uploadBinary(
categoryImgFileName!,
categoryImageToUpload!,
fileOptions: const FileOptions(
cacheControl: '3600',
upsert: false,
),
);
return;
}
return null;
}
Future<bool> registrarNuevaCategoria() async {
await uploadCategoryImage();
final res = await supabaseLU.from('video_genero').insert(
{
'name': categoryName,
'poster_image_file': categoryImgFileName,
},
).select();
if (res == null) {
print("Error al registrar categoria");
print(res.error!.message);
return false;
}
return true;
}
/////////////ACTUALIZAR CATEGORIA///////////////////////
Future<bool> updateCategory(int idCategory, String? name) async {
if (categoryImageToUpload == null) {
final res = await supabaseLU
.from('video_genero')
.update(
{
'name': name.toString(),
},
)
.eq('id', idCategory)
.select();
if (res == null) {
print("Error al registrar updateCategory1");
print(res.error!.message);
return false;
}
return true;
}
//---------------------------------------------------------------
final getFileName = await supabaseLU
.from('video_genero')
.select('poster_image_file')
.eq('id', idCategory)
.single();
if (getFileName['poster_image_file'] != null &&
categoryImageToUpload != null) {
await supabase.storage
.from('lectores_urb/imagenes/videos/categories')
.updateBinary(
getFileName['poster_image_file'],
categoryImageToUpload!,
fileOptions: const FileOptions(
cacheControl: '3600',
upsert: false,
),
);
} else {
print("NO EXISTE SUBIR");
await supabase.storage
.from('lectores_urb/imagenes/videos/categories')
.uploadBinary(
categoryImgFileName!,
categoryImageToUpload!,
fileOptions: const FileOptions(
cacheControl: '3600',
upsert: false,
),
);
await supabaseLU
.from('video_genero')
.update(
{
'poster_image_file': categoryImgFileName,
},
)
.eq('id', idCategory)
.select();
}
//---------------------------------------------------------------
return true;
}
/////////////BORRAR CATEGORIA///////////////////////
Future<bool> deleteCategory(int idCategory, String? filename) async {
await supabaseLU
.from('video_in_genero')
.delete()
.eq('genero_id', idCategory)
.select();
await supabase.storage
.from('lectores_urb')
.remove(["imagenes/videos/categories/$filename"]);
await supabaseLU
.from('video_genero')
.delete()
.eq('id', idCategory)
.select();
categoryImgFileName = null;
resetAllvideoData();
getCategories();
refreshVideoTablet();
return true;
}
//---------------ATUALIZAR VIDEOS------------------
Future<bool> updateVideoData(
int idVideo,
String title,
String description,
String partner,
String outlink,
int points,
List<int> selectedVideoCategoriesId, {
String? videoImage,
String? posterImage,
String? posterFileName,
List<String>? qrList,
}) async {
/* print("updateVideoData");
print("idVideo: $idVideo");
print("title: $title");
print("description: $description");
print("partner: $partner");
print("outlink: $outlink");
print("points: $points");
print("selectedVideoCategoriesId: $selectedVideoCategoriesId");
print("posterFileName: $posterFileName");
print("posterImage: $posterImage");
print("videoImage: $videoImage");
print("qrList: $qrList"); */
if (qrList != null) {
final existingQrs = await getQrsByVideoId(idVideo);
// Eliminar los QRs que no están en qrList
for (String qr in existingQrs) {
if (!qrList.contains(qr)) {
await supabaseLU
.from('video_in_qr')
.delete()
.eq('id_qr_fk', qr)
.eq('id_video_fk', idVideo)
.select();
}
}
// Agregar nuevos QRs
for (String qr in qrList) {
if (!existingQrs.contains(qr)) {
await supabaseLU.from('video_in_qr').insert({
'id_qr_fk': qr,
'id_video_fk': idVideo,
}).select();
}
}
}
final priorityrecibe = await getPriorityId(selectePriority);
final res = await supabaseLU
.from('videos')
.update(
{
'title': title.toString(),
'overview': description.toString(),
'url_ad': outlink.toString(),
'partner': partner.toString(),
'points': 1,
'priority': priorityrecibe,
'video_status': true,
},
)
.eq('id', idVideo)
.select();
if (res == null) {
print("Error al registrar updateVideoTitulo");
print(res.error!.message);
resetAllvideoData();
return false;
}
if (webVideo != null) {
final getFileName = await supabaseLU
.from('videos')
.select('video_file_name')
.eq('id', idVideo)
.single();
print("getFileName: $getFileName");
if (getFileName['video_file_name'] != null) {
await supabase.storage
.from('lectores_urb/videos/cm_videos')
.updateBinary(
getFileName['video_file_name'],
webVideo!,
fileOptions: const FileOptions(
cacheControl: '3600',
upsert: false,
),
);
webVideo = null;
}
}
if (videoPoster != null) {
await supabase.storage
.from('lectores_urb/imagenes/videos/posters')
.updateBinary(videoCoverFileNameNoModif.toString(), videoPoster!);
}
await supabaseLU
.from('video_in_genero')
.delete()
.eq('video_id', idVideo)
.select();
await registrarCategoriasDelVideoUsandoId(
idVideo, selectedVideoCategoriesId);
resetAllvideoData();
refreshVideoTablet();
return true;
}
/////////////VIDEOS///////////////////////
getVideoPrioritiesList() async {
final res = await supabaseLU.from('video_priority').select("name");
videoPriority = (res as List<dynamic>)
.map((priority) => priority['name'] as String)
.toList();
return videoPriority;
}
Future<String?> uploadPosterImage() async {
if (videoPoster != null && videoCoverFile != null) {
await supabase.storage
.from('lectores_urb/imagenes/videos/posters')
.uploadBinary(
'$videoName-$videoCoverFile',
videoPoster!,
fileOptions: const FileOptions(
cacheControl: '3600',
upsert: false,
),
);
final res = await supabase.storage
.from('lectores_urb/imagenes/videos/posters')
.getPublicUrl('$videoName-$videoCoverFile');
posterPath = res;
return videoCoverFile;
}
return null;
}
Future<void> selectPosterImage() async {
videoCoverFile = null;
videoPoster = null;
FilePickerResult? picker = await FilePickerWeb.platform
.pickFiles(type: FileType.custom, allowedExtensions: ['jpg', 'png']);
//get and load pdf
if (picker != null) {
var now = DateTime.now();
var formatter = DateFormat('yyyyMMddHHmmss');
var timestamp = formatter.format(now);
videoCoverFile = 'poster-$timestamp-${picker.files.single.name}';
videoPoster = picker.files.single.bytes;
} else {
videoCoverFile = null;
videoPoster = null;
}
notifyListeners();
return;
}
Future<bool> selectVideo() async {
videoName = "";
final ImagePicker picker = ImagePicker();
final XFile? pickedVideo = await picker.pickVideo(
source: ImageSource.gallery,
);
if (pickedVideo == null) return false;
fileExtension = p.extension(pickedVideo.name);
videoPath = pickedVideo.path;
videoName = pickedVideo.name;
videoName = videoName!.replaceAll(fileExtension, "");
webVideo = await pickedVideo.readAsBytes();
return true;
}
Future<bool> uploadVideo(List<int> categoryID, {List<String>? qrList}) async {
try {
if (webVideo != null && videoName != null) {
final files = await supabase.storage
.from('lectores_urb')
.list(path: 'videos/cm_videos');
// Verificar si el archivo ya existe
final fileExists =
files.any((file) => file.name == '$videoName$fileExtension');
if (fileExists) {
toastMessage = MsjToast(
message: 'video already exists',
color: Color.fromARGB(255, 236, 187, 50),
);
return false;
}
if (videoCoverFile == null) {
toastMessage = MsjToast(
message: 'No poster selected, upload an image to continue',
color: Color.fromARGB(255, 236, 187, 50),
);
return false;
}
//check if videoCoverFile ya existe en storage
final filesPoster = await supabase.storage
.from('lectores_urb')
.list(path: 'imagenes/videos/posters');
// Verificar si el archivo ya existe
final fileExistsPoster = filesPoster
.any((file) => file.name == '$videoName-$videoCoverFile');
if (fileExistsPoster) {
toastMessage = MsjToast(
message: 'poster file name already exists, (change the name)',
color: Color.fromARGB(255, 236, 187, 50),
);
return false;
}
final storageResponse = await supabase.storage
.from('lectores_urb/videos/cm_videos')
.uploadBinary(
'$videoName$fileExtension',
webVideo!,
fileOptions: const FileOptions(
cacheControl: '3600',
upsert: false,
),
);
if (storageResponse == null) return false;
dynamic res = supabase.storage
.from('lectores_urb/videos/cm_videos')
.getPublicUrl('$videoName$fileExtension');
videoUrl = res;
if (await registrarVideo2(categoryID, qrList: qrList)) {
return true;
} else {
return false;
}
}
return false;
} catch (e) {
print("Error en uploadVideo: $e");
return false;
}
}
//get priority id using name
Future<int> getPriorityId(String priorityName) async {
final res = await supabaseLU
.from('video_priority')
.select("id")
.eq("name", priorityName)
.limit(1);
if (res == null) {
print("Error al obtener id de prioridad");
print(res.error!.message);
return 0;
}
return res[0]['id'];
}
Future<bool> registrarCategoriasDelVideoUsandoId(
int idVideo, List<int> listaIdsCategorias) async {
try {
await supabaseLU.rpc('lu_añadir_generos_al_video', params: {
'lista_id_generos': listaIdsCategorias,
'videoid': idVideo
}).select();
return true;
} catch (e) {
print("Error al registrar Categorias del video");
print(e.toString());
return false;
}
}
Future<bool> obtenerIdVideoUsandoNombreArchivoStorage(
String videoPath) async {
//obtiene el id del video recien registrado usando su archivo cargado
final res = await supabaseLU
.from('videos')
.select("id")
.eq("video_file_name", videoPath)
.limit(1);
if (res == null) {
print("Error al al obtener id del video");
print(res.error!.message);
return false;
}
await registrarCategoriasDelVideoUsandoId(
res[0]['id'], selectedVideoCategoriesId);
return true;
}
Future<bool> deleteVideo2(
int idVideo, String videoFileName, String posterFileName) async {
try {
// Llamada al RPC para eliminar el video y obtener los nombres de archivos
final res = await supabaseLU
.rpc('lu_borrar_video', params: {'id_video': idVideo});
// Validar la respuesta
if (res == null || res.isEmpty) {
print("El video no pudo ser eliminado o no existe.");
refreshVideoTablet();
return false;
}
await supabaseLU.from('videos').delete().eq('id', idVideo).select();
await eliminarVideo(videoFileName, posterFileName);
refreshVideoTablet();
return true;
} catch (e) {
print("Error al eliminar el video: ${e.toString()}");
refreshVideoTablet();
return false;
}
}
Future<bool> eliminarVideo(
String videoFileName, String posterFileName) async {
await supabase.storage
.from('lectores_urb')
.remove(['videos/cm_videos/$videoFileName']);
await supabase.storage
.from('lectores_urb')
.remove(['imagenes/videos/posters/$posterFileName']);
return true;
}
Future<List<Map<String, dynamic>>> getGroupedQRCodesByCustomer() async {
try {
// Llamada al RPC en Supabase
final res = await supabaseLU.rpc('get_qr_codes_grouped_by_customer');
// Validar el resultado
if (res == null || res.isEmpty) {
print("No se encontraron datos agrupados.");
return [];
}
// Convertir los resultados en una lista de Map
return List<Map<String, dynamic>>.from(res).map((group) {
return {
'row_number': group['row_number'],
'customer_fk': group['customer_fk'],
'customer_name': group['customer_name'],
'details': group['details'], // JSONB con los detalles
};
}).toList();
} catch (e) {
print("Error en getGroupedQRCodesByCustomer: ${e.toString()}");
return []; // Retornar una lista vacía en caso de error
}
}
Future<List<String>> getQrsByVideoId(int videoId) async {
try {
final response = await supabaseLU
.from('video_in_qr')
.select('id_qr_fk')
.eq('id_video_fk', videoId);
if (response == null) {
print('Error al obtener getQrsByCouponId()');
return [];
}
return List<String>.from(
(response as List<dynamic>).map((item) => item['id_qr_fk']),
);
} catch (e) {
print("Error en getQrsByVideoId: ${e.toString()}");
return []; // Retornar una lista vacía en caso de error
}
}
void resetAllvideoData() {
videoPoster = null;
videoCoverFile = null;
videoPath = null;
videoName = null;
selectedVideoCategoriesId = [];
selectedVideoCategories = [];
categoryImgFileName = null;
categoryImageToUpload = null;
noImageToUpload = true;
selectePriority = "baja";
videoOutlink = "";
videoPoints = 0;
descripcionVideo = "";
videoPatner = "";
videoUrl = null;
webVideo = null;
posterPath = null;
videoPosterPath = null;
tituloVideo = "";
return;
}
void clearPosterImage() {
videoPoster = null;
videoCoverFile = null;
videoPosterPath = null;
notifyListeners();
return;
}
void clearControllers() {
modeloController.clear();
notifyListeners();
}
void updatestateManager() {
print(videoName);
notifyListeners();
}
void clearVideo() {
videoPath = null;
webVideo = null;
notifyListeners();
}
void refreshVideoTablet() {
print(showWarningsOnTable);
if (showWarningsOnTable && warningCountTablaVideos > 0) {
showFullVideoTable == true
? getAllAdsOnOneTableWarnings()
: getAdsByCategoriesWarnings();
} else {
showFullVideoTable == true ? getAllAdsOnOneTable() : getAdsByCategories();
}
}
Future<bool> registrarVideo2(List<int> categoryIds,
{List<String>? qrList}) async {
await uploadPosterImage();
final priorityrecibe = await getPriorityId(selectePriority);
final res = await supabaseLU.rpc(
'lu_registrar_videos_master',
params: {
'p_title': tituloVideo,
'p_overview': descripcionVideo,
'p_video_url': videoUrl,
'p_url_ad': videoOutlink,
'p_poster_path': posterPath ??
"https://u-supabase.virtalus.cbluna-dev.com/storage/v1/object/public/assets/placeholder_no_image.jpg",
'p_poster_file_name': '$videoName-$videoCoverFile',
'p_video_file_name': '$videoName$fileExtension',
'p_duration_video': duratinVideoSeconds,
'p_partner': videoPatner,
'p_priority': priorityrecibe,
'p_qr_list': qrList,
'p_category_ids': categoryIds
},
).select();
if (res == null) {
print("Error al registrar video");
print(res.error!.message);
return false;
}
if (await obtenerIdVideoUsandoNombreArchivoStorage(
'$videoName$fileExtension')) {
videoName = "";
descripcionVideo = "";
refreshVideoTablet();
return true;
} else {
videoName = "";
descripcionVideo = "";
refreshVideoTablet();
return false;
}
}
}