Provider de ajustes finalizado, dependencias actualizadas y algunas opciones unidas al provider

parent 0647b9a0
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:prueba_multimedia/modelo/archivo.dart';
import 'package:uuid/uuid.dart';
......@@ -18,6 +17,49 @@ class Carpeta extends ElementoSeleccionable {
List<InfoFormato> get formatos => List.unmodifiable(_formatos);
bool get incluyeSubcarpetas => _incluirSubcarpetas;
Carpeta({required super.id, required Directory directory, bool incluirSubcarpetas = false}):
_directory = directory,
_incluirSubcarpetas = incluirSubcarpetas,
super(nombre: directory.path.split('/').last, icon: const Icon(Icons.folder_outlined))
{
final fsEntities = directory.listSync(recursive: false, followLinks: false);
// Guardamos los archivos
for(var file in fsEntities.whereType<File>()) {
Archivo archivo = Archivo(id: Uuid().v1(), file: file);
_elementos.add(archivo);
final f = InfoFormato(
formato: archivo.formatoOriginal,
carpeta: this,
seleccionado: true,
subCarpeta: false
);
if(!_formatos.contains(f)){
_formatos.add(f);
}
}
// Guardamos los archivos de las subcarpetas
// Ahora mismo solo consultamos un nivel de subcarpetas y no mas
for(var directory in fsEntities.whereType<Directory>()) {
final files = directory.listSync(recursive: true, followLinks: false)
.whereType<File>();
for (var file in files) {
Archivo archivo = Archivo(id: Uuid().v1(), file: file);
_elementosSubcarpetas.add(archivo);
final i = InfoFormato(
formato: archivo.formatoOriginal,
carpeta: this,
seleccionado: incluirSubcarpetas,
subCarpeta: true);
if(!_formatos.contains(i)){
_formatos.add(i);
}
}
}
}
/// Un getter que da todos los archivos según los filtros elegidos
List<Archivo> get elementosSeleccionados {
final seleccionado = <Archivo>[];
......@@ -34,13 +76,13 @@ class Carpeta extends ElementoSeleccionable {
{
if (noEsSubcarpeta) {
formatosSeleccionados.putIfAbsent(
infoFormato.formatoOriginal,
() => infoFormato.formatoDestino!
infoFormato.formatoOriginal,
() => infoFormato.formatoDestino!
);
} else if (_incluirSubcarpetas) {
formatosSeleccionadosSubcarpetas.putIfAbsent(
infoFormato.formatoOriginal,
() => infoFormato.formatoDestino!
() => infoFormato.formatoDestino!
);
}
}
......@@ -77,46 +119,6 @@ class Carpeta extends ElementoSeleccionable {
return seleccionados;
}
Carpeta({required super.id, required Directory directory}):
_directory = directory,
super(nombre: directory.path.split('/').last, icon: const Icon(Icons.folder_outlined))
{
final fsEntities = directory.listSync(recursive: false, followLinks: false);
// Guardamos los archivos
for(var file in fsEntities.whereType<File>()) {
Archivo archivo = Archivo(id: Uuid().v1(), file: file);
_elementos.add(archivo);
final f = InfoFormato(
formato: archivo.formatoOriginal,
carpeta: this,
subCarpeta: false
);
if(!_formatos.contains(f)){
_formatos.add(f);
}
}
// Guardamos los archivos de las subcarpetas
// Ahora mismo solo consultamos un nivel de subcarpetas y no mas
for(var directory in fsEntities.whereType<Directory>()) {
final files = directory.listSync(recursive: false, followLinks: false)
.whereType<File>();
for (var file in files) {
Archivo archivo = Archivo(id: Uuid().v1(), file: file);
_elementosSubcarpetas.add(archivo);
final i = InfoFormato(
formato: archivo.formatoOriginal,
carpeta: this,
subCarpeta: true);
if(!_formatos.contains(i)){
_formatos.add(i);
}
}
}
}
InfoFormato? getInfoFormato({required Formato formato}){
for(InfoFormato i in _formatos){
if(i.formatoOriginal == formato){
......
import 'dart:io';
import 'package:ffmpeg_kit_flutter/ffmpeg_kit.dart';
import 'package:ffmpeg_kit_flutter/ffmpeg_session.dart';
import 'package:ffmpeg_kit_flutter/return_code.dart';
import 'package:ffmpeg_kit_flutter_new/ffmpeg_kit.dart';
import 'package:ffmpeg_kit_flutter_new/ffmpeg_session.dart';
import 'package:ffmpeg_kit_flutter_new/return_code.dart';
import 'package:path_provider/path_provider.dart';
import 'package:prueba_multimedia/modelo/modelo.dart';
......
......@@ -35,18 +35,16 @@ class ListaSeleccionables extends ChangeNotifier {
return false;
}
bool addCarpeta(Directory directory){
bool addCarpeta(Directory directory, bool incluirSubcarpetasPorDefecto){
final newCarpeta = Carpeta(
id: const Uuid().v1(),
directory: directory
directory: directory,
incluirSubcarpetas: incluirSubcarpetasPorDefecto
);
if(newCarpeta.formatos.isNotEmpty){
_seleccionables.add(
Carpeta(
id: const Uuid().v1(),
directory: directory
)
newCarpeta
);
notifyListeners();
return true;
......@@ -56,7 +54,12 @@ class ListaSeleccionables extends ChangeNotifier {
}
void reinsertar(int index, ElementoSeleccionable element){
_seleccionables.insert(index, element);
if(index > _seleccionables.length){
_seleccionables.add(element);
}
else{
_seleccionables.insert(index, element);
}
notifyListeners();
}
......
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class ProviderAjustes extends ChangeNotifier {
int _modoConversion = 1;
int _incluirSubcarpetas = 1;
String _carpetaSalida = "";
bool _cargando = true;
static const modoConversionKey = 'modoConversion';
static const incluirSubcarpetasKey = 'incluirSubcarpetas';
static const carpetaSalidaKey = 'carpetaSalida';
int get modoConversion => _modoConversion;
int get incluirSubcarpetas => _incluirSubcarpetas;
String get carpetaSalida => _carpetaSalida;
bool get cargando => _cargando;
bool get expand => _cargando || _modoConversion != 0;
ProviderAjustes() {
_cargarValoresAnteriores();
}
Future<void> _cargarValoresAnteriores() async {
final prefs = await SharedPreferences.getInstance();
_modoConversion = await prefs.getInt(modoConversionKey) ?? 0;
_incluirSubcarpetas = await prefs.getInt(incluirSubcarpetasKey) ?? 1;
_carpetaSalida = await prefs.getString(carpetaSalidaKey) ?? '';
if(_carpetaSalida.isNotEmpty){
final directory = Directory(carpetaSalida);
if(!(await directory.exists())){
_carpetaSalida = '';
}
}
_cargando = false;
notifyListeners();
}
void setModoConversion(int valor) {
_modoConversion = valor;
notifyListeners();
_actualizarModoConversion();
}
void setIncluirSubcarpetas(int valor) {
_incluirSubcarpetas = valor;
notifyListeners();
_actualizarIncluirSubcarpetasn();
}
void setCarpetaSalida(String valor) {
_carpetaSalida = valor;
notifyListeners();
_actualizarCarpetaSalida();
}
Future<void> _actualizarModoConversion() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setInt(modoConversionKey, _modoConversion);
}
Future<void> _actualizarIncluirSubcarpetasn() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setInt(incluirSubcarpetasKey, _incluirSubcarpetas);
}
Future<void> _actualizarCarpetaSalida() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(carpetaSalidaKey, _carpetaSalida);
}
}
\ No newline at end of file
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:prueba_multimedia/modelo/provider_ajustes.dart';
import 'package:prueba_multimedia/widgets/action_button.dart';
class PaginaAjustes extends StatefulWidget {
static const opcionesModoConversion = <String>[
"Copiar", "Comprimir", "Preguntar siempre"
"Preguntar siempre", "Copiar", "Comprimir"
];
static const opcionesIncluirSubcarpetas = <String>[
"Siempre", "Nunca"
"Sí", "No"
];
// Si hemos elegido una carpeta entonces se tendría que mostrar
static const opcionesCarpetaSalida = <String>[
"Elegir", "Preguntar siempre"
];
const PaginaAjustes({super.key});
final ProviderAjustes provider;
const PaginaAjustes({super.key, required this.provider});
@override
State<PaginaAjustes> createState() => _PaginaAjustesState();
......@@ -22,7 +30,21 @@ class _PaginaAjustesState extends State<PaginaAjustes> {
// Indices de los valores seleccionados de cada opcion
int modoConversion = 0;
int incluirSubcarpeta = 0;
int carpetaSalida = 0;
int carpetaSalidaIndex = 0;
String carpetaSalida = '';
@override
void initState() {
if(!widget.provider.cargando){
setState(() {
modoConversion = widget.provider.modoConversion;
incluirSubcarpeta = widget.provider.incluirSubcarpetas;
carpetaSalida = widget.provider.carpetaSalida;
carpetaSalidaIndex = (widget.provider.carpetaSalida.isEmpty)? 1 : 0;
});
}
super.initState();
}
@override
Widget build(BuildContext context) {
......@@ -47,6 +69,7 @@ class _PaginaAjustesState extends State<PaginaAjustes> {
PaginaAjustes.opcionesModoConversion.asMap().forEach(
(index, opcion) => callbacks.add(() {
setState(() {modoConversion = index;});
widget.provider.setModoConversion(index);
Navigator.pop(context);
})
);
......@@ -67,6 +90,7 @@ class _PaginaAjustesState extends State<PaginaAjustes> {
PaginaAjustes.opcionesIncluirSubcarpetas.asMap().forEach(
(index, opcion) => callbacks.add(() {
setState(() {incluirSubcarpeta = index;});
widget.provider.setIncluirSubcarpetas(index);
Navigator.pop(context);
})
);
......@@ -77,7 +101,7 @@ class _PaginaAjustesState extends State<PaginaAjustes> {
);
},
child: ListTile(
title: const Text("Incluir subcarpetas"),
title: const Text("Incluir subcarpetas por defecto"),
subtitle: Text(PaginaAjustes.opcionesIncluirSubcarpetas[incluirSubcarpeta]),
),
),
......@@ -85,20 +109,30 @@ class _PaginaAjustesState extends State<PaginaAjustes> {
onTap: () {
var callbacks = <VoidCallback>[];
PaginaAjustes.opcionesCarpetaSalida.asMap().forEach(
(index, opcion) => callbacks.add(() {
setState(() {carpetaSalida = index;});
Navigator.pop(context);
})
);
(index, opcion) => (index == 0)?
callbacks.add(() => _elegirCarpetaSalida(context, index, 1)) :
callbacks.add(() {
setState(() {
carpetaSalida = '';
carpetaSalidaIndex = index;
});
widget.provider.setCarpetaSalida('');
Navigator.pop(context);
})
);
mostrarDialogoOpciones(
opciones: PaginaAjustes.opcionesCarpetaSalida,
callbacks: callbacks,
seleccionado: carpetaSalida
seleccionado: carpetaSalidaIndex
);
},
child: ListTile(
title: const Text("Carpeta de salida"),
subtitle: Text(PaginaAjustes.opcionesCarpetaSalida[carpetaSalida]),
subtitle: Text(
(carpetaSalida.isEmpty)?
PaginaAjustes.opcionesCarpetaSalida[carpetaSalidaIndex] :
carpetaSalida
),
),
),
InkWell(
......@@ -113,6 +147,13 @@ class _PaginaAjustesState extends State<PaginaAjustes> {
"Convertex",
style: textTheme.titleLarge,
),
const SizedBox(height: 16.0,),
Text(
"Desarrollado por:",
style: textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.bold
),
),
const SizedBox(height: 8.0,),
Text(
"Diego Pérez Peña",
......@@ -130,7 +171,7 @@ class _PaginaAjustesState extends State<PaginaAjustes> {
});
},
child: ListTile(
title: const Text("Creadores"),
title: const Text("Acerca de..."),
),
),
],
......@@ -170,4 +211,58 @@ class _PaginaAjustesState extends State<PaginaAjustes> {
);
}
Future<void> _elegirCarpetaSalida(BuildContext context, int indice, int indicePorDefecto) async {
if(await ActionButton.comprobacionPermisoArchivos(context)){
FilePicker.platform.getDirectoryPath().then((path) {
if (path != null) {
var directory = Directory(path);
setState(() {
carpetaSalida = directory.absolute.path;
carpetaSalidaIndex = indice;
});
widget.provider.setCarpetaSalida(directory.absolute.path);
}
else {
setState(() {
carpetaSalida = '';
carpetaSalidaIndex = indicePorDefecto;
});
widget.provider.setCarpetaSalida('');
}
});
}
else {
setState(() {
carpetaSalida = '';
carpetaSalidaIndex = indicePorDefecto;
});
widget.provider.setCarpetaSalida('');
}
Navigator.pop(context);
}
Future<void> _mostrarNotificacion(String text, bool opcion) async{
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text(text),
actions: [
if(opcion) TextButton(
onPressed: () {
Navigator.of(context).pop();
openAppSettings();
},
child: const Text('SÍ'),
),
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: (opcion)? const Text('NO') : const Text('OK'),
)
]
);
}
);
}
}
import 'dart:async';
import 'dart:io';
import 'package:ffmpeg_kit_flutter/ffmpeg_kit.dart';
import 'package:ffmpeg_kit_flutter/ffmpeg_session.dart';
import 'package:ffmpeg_kit_flutter/ffprobe_kit.dart';
import 'package:ffmpeg_kit_flutter/ffprobe_session.dart';
import 'package:ffmpeg_kit_flutter_new/ffmpeg_kit.dart';
import 'package:ffmpeg_kit_flutter_new/ffmpeg_session.dart';
import 'package:ffmpeg_kit_flutter_new/ffprobe_kit.dart';
import 'package:ffmpeg_kit_flutter_new/ffprobe_session.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
......
import 'package:flutter/material.dart';
import 'package:open_file/open_file.dart';
import 'package:provider/provider.dart';
import 'package:prueba_multimedia/modelo/provider_ajustes.dart';
import 'package:prueba_multimedia/widgets/widgets.dart';
import 'package:prueba_multimedia/modelo/modelo.dart';
import 'package:prueba_multimedia/paginas/paginas.dart';
......@@ -19,7 +20,6 @@ class PaginaPrincipal extends StatelessWidget {
action: SnackBarAction(
label: 'VER',
onPressed: () async {
// TODO: Cambiar esta dirección por la de los ajustes
await OpenFile.open('/storage/emulated/0/Pictures/Screenshots');
},
),
......@@ -36,15 +36,25 @@ class PaginaPrincipal extends StatelessWidget {
),
backgroundColor: Theme.of(context).primaryColor,
actions: [
IconButton(
icon: Icon(
Icons.settings_outlined,
color: Colors.white,
),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder:
(context) => PaginaAjustes()
));
Consumer<ProviderAjustes>(
builder: (context, ajustes, child) {
return IconButton(
icon: Icon(
Icons.settings_outlined,
color: Colors.white,
),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(
builder: (context) {
return PaginaAjustes(
provider: ajustes
);
}
)
);
}
);
}
)
]
......@@ -56,10 +66,10 @@ class PaginaPrincipal extends StatelessWidget {
}
Widget _construirCuerpo(BuildContext context) {
return Consumer<ListaSeleccionables>(
builder: (context, manager, child) {
if (manager.seleccionables.isNotEmpty) {
return PaginaPrincipalLlena(listaSeleccionables: manager);
return Consumer2<ListaSeleccionables, ProviderAjustes>(
builder: (context, lista, ajustes, child) {
if (lista.seleccionables.isNotEmpty) {
return PaginaPrincipalLlena(listaSeleccionables: lista);
} else {
return PaginaPrincipalVacia();
}
......@@ -68,13 +78,13 @@ class PaginaPrincipal extends StatelessWidget {
}
Widget _construitFAB(BuildContext context, VoidCallback function){
return Consumer<ListaSeleccionables>(
builder: (context, manager, child) {
if (manager.convirtiendo) {
return Consumer2<ListaSeleccionables, ProviderAjustes>(
builder: (context, lista, ajustes, child) {
if (lista.convirtiendo) {
return Padding (
padding: const EdgeInsets.all(16.0),
child: ConvertexProgressBar(
progress: manager.progress,
progress: lista.progress,
textColor: Colors.black,
completedBackground: Colors.purpleAccent.shade100,
)
......@@ -83,8 +93,9 @@ class PaginaPrincipal extends StatelessWidget {
return Padding (
padding: const EdgeInsets.all(16.0),
child: ConVertexFabBar(
allowConversion: manager.seleccionables.isNotEmpty,
allowConversion: lista.seleccionables.isNotEmpty,
onConvertSuccess: function,
providerAjustes: ajustes,
)
);
}
......
......@@ -51,9 +51,13 @@ class PaginaPrincipalLlena extends StatelessWidget {
),
onDismissed: (direction) {
listaSeleccionables.borraSeleccionable(index);
String nombreCarp = seleccionables[index].nombre;
if(nombreCarp.length > 60){
nombreCarp = '${nombreCarp.substring(0, 61)}...';
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('${seleccionables[index].nombre} borrado'),
content: Text('$nombreCarp borrado'),
action: SnackBarAction(
label: 'Deshacer',
onPressed: () {
......
......@@ -3,12 +3,14 @@ import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:prueba_multimedia/modelo/modelo.dart';
import 'package:prueba_multimedia/modelo/provider_ajustes.dart';
class ActionButton extends StatelessWidget {
final ActionButtonTypes tipoBoton;
final ListaSeleccionables manager;
final BuildContext context;
final VoidCallback? onSuccess;
final ProviderAjustes providerAjustes;
final bool disabled;
const ActionButton({
......@@ -17,7 +19,9 @@ class ActionButton extends StatelessWidget {
required this.manager,
required this.context,
this.onSuccess,
required this.disabled});
required this.disabled,
required this.providerAjustes
});
void Function()? getCallback() {
if(disabled) return null;
......@@ -72,47 +76,31 @@ class ActionButton extends StatelessWidget {
}
void carpetaAction() async {
// Comprobación de permisos
final granted = await Permission.manageExternalStorage.isGranted;
if(!granted){
final permanently = await Permission.manageExternalStorage.isPermanentlyDenied;
if(permanently){
_mostrarNotificacion('El acceso al almacenamiento del dispositivo ha sido denegado permanentemente.\n'
'¿Desea abrir la configuración para modificar el permiso?', true);
return;
}
else{
await _mostrarNotificacion('ConVertex no tiene permiso para acceder a sus archivos. Por favor, para usar esta función, active el permiso a continuación.', false);
if(await Permission.manageExternalStorage.request().isDenied){
_mostrarNotificacion('Se ha denegado el permiso de acceso al almacenamiento. Sin dicho permiso, ConVertex no puede acceder a los archivos dentro de sus carpetas.\n'
'Por favor, ceda el permiso para usar esta función.', false);
return;
}
}
}
FilePicker.platform.getDirectoryPath().then( (path) {
if (path != null) {
var directory = Directory(path);
final res = manager.addCarpeta(directory);
if(res){
if(context.mounted && onSuccess != null){
onSuccess!();
if(await comprobacionPermisoArchivos(context)){
FilePicker.platform.getDirectoryPath().then( (path) {
if (path != null) {
bool inc = (!providerAjustes.cargando && providerAjustes.incluirSubcarpetas == 0)? true : false;
var directory = Directory(path);
final res = manager.addCarpeta(directory, inc);
if(res){
if(context.mounted && onSuccess != null){
onSuccess!();
}
}
}
else{
else{
if (context.mounted) {
_mostrarSnackBar('La carpeta seleccionada no contiene archivos de formatos multimedia conoocidos');
}
}
} // Mensaje indicando que se seleccione una carpeta
else {
// Comprobar que el widget no ha sido destruido por ser asíncrono
if (context.mounted) {
_mostrarSnackBar('La carpeta seleccionada no contiene archivos de formatos multimedia conoocidos');
_mostrarSnackBar('No se ha seleccionado ninguna carpeta');
}
}
} // Mensaje indicando que se seleccione una carpeta
else {
// Comprobar que el widget no ha sido destruido por ser asíncrono
if (context.mounted) {
_mostrarSnackBar('No se ha seleccionado ninguna carpeta');
}
}
});
});
}
}
void enlaceAction() {
......@@ -120,7 +108,7 @@ class ActionButton extends StatelessWidget {
}
void copiarAction() async {
if(await comprobacionesPrevias()){
if(await _comprobacionesPreviasConversion(context)){
actualizadorProgreso();
// Averiguamos donde colocar los archivos de salida
......@@ -149,7 +137,7 @@ class ActionButton extends StatelessWidget {
}
void comprimirAction() async {
if(await comprobacionesPrevias()){
if(await _comprobacionesPreviasConversion(context)){
actualizadorProgreso();
// TODO: Código de compresión
......@@ -157,7 +145,7 @@ class ActionButton extends StatelessWidget {
}
void reemplazarAction() async {
if(await comprobacionesPrevias()){
if(await _comprobacionesPreviasConversion(context)){
actualizadorProgreso();
// Convertimos los archivos como tal
......@@ -190,12 +178,36 @@ class ActionButton extends StatelessWidget {
}
}
Future<bool> comprobacionesPrevias() async {
Future<bool> _comprobacionesPreviasConversion(BuildContext context) async {
if(!await comprobacionPermisoArchivos(context)){
return false;
}
// TODO: Me gustaría añadir aquí una notificación para avisar al usuario de si quiere realmente convertir una carpeta muy grande
return true;
}
Future<void> _mostrarNotificacion(String text, bool opcion) async{
static Future<bool> comprobacionPermisoArchivos(BuildContext context) async {
final granted = await Permission.manageExternalStorage.isGranted;
if(!granted){
final permanently = await Permission.manageExternalStorage.isPermanentlyDenied;
if(permanently) {
_mostrarNotificacion(context, 'El acceso al almacenamiento del dispositivo ha sido denegado permanentemente.\n'
'¿Desea abrir la configuración para modificar el permiso?', true);
return false;
}
else {
await _mostrarNotificacion(context, 'ConVertex no tiene permiso para acceder a sus archivos. Por favor, para usar esta función, active el permiso a continuación.', false);
if(await Permission.manageExternalStorage.request().isDenied){
_mostrarNotificacion(context, 'Se ha denegado el permiso de acceso al almacenamiento. Sin dicho permiso, ConVertex no puede acceder a los archivos dentro de sus carpetas.\n'
'Por favor, ceda el permiso para usar esta función.', false);
return false;
}
}
}
return true;
}
static Future<void> _mostrarNotificacion(BuildContext context, String text, bool opcion) async{
await showDialog(
context: context,
builder: (context) {
......
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:prueba_multimedia/modelo/modelo.dart';
import 'package:prueba_multimedia/modelo/provider_ajustes.dart';
import 'package:prueba_multimedia/widgets/widgets.dart';
class ConVertexFabBar extends StatefulWidget {
final bool allowConversion;
final VoidCallback onConvertSuccess;
final ProviderAjustes providerAjustes;
const ConVertexFabBar({
super.key,
required this.allowConversion,
required this.onConvertSuccess
required this.onConvertSuccess,
required this.providerAjustes
});
@override
......@@ -82,6 +85,7 @@ class _ConVertexFabBarState extends State<ConVertexFabBar> {
context: context,
disabled: !widget.allowConversion && type.isConvertir(),
onSuccess: widget.onConvertSuccess,
providerAjustes: widget.providerAjustes,
);
}).toList();
}
......@@ -167,7 +171,8 @@ class _ConVertexFabBarState extends State<ConVertexFabBar> {
manager: manager,
context: context,
onSuccess: closeButtons,
disabled: false
disabled: false,
providerAjustes: widget.providerAjustes,
);
}).toList();
}
......
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:prueba_multimedia/modelo/provider_ajustes.dart';
import 'package:prueba_multimedia/paginas/paginas.dart';
import 'package:prueba_multimedia/modelo/modelo.dart';
......@@ -21,7 +22,8 @@ class ConvertexPrototipoApp extends StatelessWidget {
themeMode: ThemeMode.system,
home: MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => ListaSeleccionables())
ChangeNotifierProvider(create: (context) => ListaSeleccionables()),
ChangeNotifierProvider(create: (context) => ProviderAjustes())
],
child: PaginaPrincipal(),
),
......
......@@ -5,12 +5,16 @@
import FlutterMacOS
import Foundation
import ffmpeg_kit_flutter_new
import file_picker
import open_file_mac
import path_provider_foundation
import shared_preferences_foundation
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FFmpegKitFlutterPlugin.register(with: registry.registrar(forPlugin: "FFmpegKitFlutterPlugin"))
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
OpenFilePlugin.register(with: registry.registrar(forPlugin: "OpenFilePlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
}
......@@ -81,14 +81,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.3"
ffmpeg_kit_flutter:
ffmpeg_kit_flutter_android:
dependency: transitive
description:
name: ffmpeg_kit_flutter_android
sha256: "1bcd2e18169862d9782f019e3e83f92a41a12692deb25e0e767ecd44518c0f7e"
url: "https://pub.dev"
source: hosted
version: "1.4.0"
ffmpeg_kit_flutter_new:
dependency: "direct main"
description:
name: ffmpeg_kit_flutter
sha256: "843aae41823ca94a0988d975b4b6cdc6948744b9b7e2707d81a3a9cd237b0100"
name: ffmpeg_kit_flutter_new
sha256: dbaf0f4963b08a034a4f787276c1e12efc36a56670693f1721e46f95554f0979
url: "https://pub.dev"
source: hosted
version: "6.0.3"
version: "1.6.1"
ffmpeg_kit_flutter_platform_interface:
dependency: transitive
description:
......@@ -97,6 +105,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.2.1"
file:
dependency: transitive
description:
name: file
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
url: "https://pub.dev"
source: hosted
version: "7.0.1"
file_picker:
dependency: "direct main"
description:
......@@ -400,6 +416,62 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.1.2"
shared_preferences:
dependency: "direct main"
description:
name: shared_preferences
sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5"
url: "https://pub.dev"
source: hosted
version: "2.5.3"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: "20cbd561f743a342c76c151d6ddb93a9ce6005751e7aa458baad3858bfbfb6ac"
url: "https://pub.dev"
source: hosted
version: "2.4.10"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
url: "https://pub.dev"
source: hosted
version: "2.5.4"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
url: "https://pub.dev"
source: hosted
version: "2.4.3"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
sky_engine:
dependency: transitive
description: flutter
......
......@@ -37,10 +37,11 @@ dependencies:
provider: ^6.1.2
file_picker: ^9.0.2
uuid: ^4.5.1
ffmpeg_kit_flutter: ^6.0.3
path_provider: ^2.1.5
permission_handler: ^12.0.0+1
open_file: ^3.5.10
ffmpeg_kit_flutter_new: ^1.6.1
shared_preferences: ^2.5.3
dev_dependencies:
flutter_test:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment