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

parent 0647b9a0
import 'dart:io'; import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:prueba_multimedia/modelo/archivo.dart'; import 'package:prueba_multimedia/modelo/archivo.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
...@@ -18,6 +17,49 @@ class Carpeta extends ElementoSeleccionable { ...@@ -18,6 +17,49 @@ class Carpeta extends ElementoSeleccionable {
List<InfoFormato> get formatos => List.unmodifiable(_formatos); List<InfoFormato> get formatos => List.unmodifiable(_formatos);
bool get incluyeSubcarpetas => _incluirSubcarpetas; 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 /// Un getter que da todos los archivos según los filtros elegidos
List<Archivo> get elementosSeleccionados { List<Archivo> get elementosSeleccionados {
final seleccionado = <Archivo>[]; final seleccionado = <Archivo>[];
...@@ -77,46 +119,6 @@ class Carpeta extends ElementoSeleccionable { ...@@ -77,46 +119,6 @@ class Carpeta extends ElementoSeleccionable {
return seleccionados; 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}){ InfoFormato? getInfoFormato({required Formato formato}){
for(InfoFormato i in _formatos){ for(InfoFormato i in _formatos){
if(i.formatoOriginal == formato){ if(i.formatoOriginal == formato){
......
import 'dart:io'; import 'dart:io';
import 'package:ffmpeg_kit_flutter/ffmpeg_kit.dart'; import 'package:ffmpeg_kit_flutter_new/ffmpeg_kit.dart';
import 'package:ffmpeg_kit_flutter/ffmpeg_session.dart'; import 'package:ffmpeg_kit_flutter_new/ffmpeg_session.dart';
import 'package:ffmpeg_kit_flutter/return_code.dart'; import 'package:ffmpeg_kit_flutter_new/return_code.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:prueba_multimedia/modelo/modelo.dart'; import 'package:prueba_multimedia/modelo/modelo.dart';
......
...@@ -35,18 +35,16 @@ class ListaSeleccionables extends ChangeNotifier { ...@@ -35,18 +35,16 @@ class ListaSeleccionables extends ChangeNotifier {
return false; return false;
} }
bool addCarpeta(Directory directory){ bool addCarpeta(Directory directory, bool incluirSubcarpetasPorDefecto){
final newCarpeta = Carpeta( final newCarpeta = Carpeta(
id: const Uuid().v1(), id: const Uuid().v1(),
directory: directory directory: directory,
incluirSubcarpetas: incluirSubcarpetasPorDefecto
); );
if(newCarpeta.formatos.isNotEmpty){ if(newCarpeta.formatos.isNotEmpty){
_seleccionables.add( _seleccionables.add(
Carpeta( newCarpeta
id: const Uuid().v1(),
directory: directory
)
); );
notifyListeners(); notifyListeners();
return true; return true;
...@@ -56,7 +54,12 @@ class ListaSeleccionables extends ChangeNotifier { ...@@ -56,7 +54,12 @@ class ListaSeleccionables extends ChangeNotifier {
} }
void reinsertar(int index, ElementoSeleccionable element){ void reinsertar(int index, ElementoSeleccionable element){
if(index > _seleccionables.length){
_seleccionables.add(element);
}
else{
_seleccionables.insert(index, element); _seleccionables.insert(index, element);
}
notifyListeners(); 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: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 { class PaginaAjustes extends StatefulWidget {
static const opcionesModoConversion = <String>[ static const opcionesModoConversion = <String>[
"Copiar", "Comprimir", "Preguntar siempre" "Preguntar siempre", "Copiar", "Comprimir"
]; ];
static const opcionesIncluirSubcarpetas = <String>[ static const opcionesIncluirSubcarpetas = <String>[
"Siempre", "Nunca" "Sí", "No"
]; ];
// Si hemos elegido una carpeta entonces se tendría que mostrar // Si hemos elegido una carpeta entonces se tendría que mostrar
static const opcionesCarpetaSalida = <String>[ static const opcionesCarpetaSalida = <String>[
"Elegir", "Preguntar siempre" "Elegir", "Preguntar siempre"
]; ];
const PaginaAjustes({super.key}); final ProviderAjustes provider;
const PaginaAjustes({super.key, required this.provider});
@override @override
State<PaginaAjustes> createState() => _PaginaAjustesState(); State<PaginaAjustes> createState() => _PaginaAjustesState();
...@@ -22,7 +30,21 @@ class _PaginaAjustesState extends State<PaginaAjustes> { ...@@ -22,7 +30,21 @@ class _PaginaAjustesState extends State<PaginaAjustes> {
// Indices de los valores seleccionados de cada opcion // Indices de los valores seleccionados de cada opcion
int modoConversion = 0; int modoConversion = 0;
int incluirSubcarpeta = 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -47,6 +69,7 @@ class _PaginaAjustesState extends State<PaginaAjustes> { ...@@ -47,6 +69,7 @@ class _PaginaAjustesState extends State<PaginaAjustes> {
PaginaAjustes.opcionesModoConversion.asMap().forEach( PaginaAjustes.opcionesModoConversion.asMap().forEach(
(index, opcion) => callbacks.add(() { (index, opcion) => callbacks.add(() {
setState(() {modoConversion = index;}); setState(() {modoConversion = index;});
widget.provider.setModoConversion(index);
Navigator.pop(context); Navigator.pop(context);
}) })
); );
...@@ -67,6 +90,7 @@ class _PaginaAjustesState extends State<PaginaAjustes> { ...@@ -67,6 +90,7 @@ class _PaginaAjustesState extends State<PaginaAjustes> {
PaginaAjustes.opcionesIncluirSubcarpetas.asMap().forEach( PaginaAjustes.opcionesIncluirSubcarpetas.asMap().forEach(
(index, opcion) => callbacks.add(() { (index, opcion) => callbacks.add(() {
setState(() {incluirSubcarpeta = index;}); setState(() {incluirSubcarpeta = index;});
widget.provider.setIncluirSubcarpetas(index);
Navigator.pop(context); Navigator.pop(context);
}) })
); );
...@@ -77,7 +101,7 @@ class _PaginaAjustesState extends State<PaginaAjustes> { ...@@ -77,7 +101,7 @@ class _PaginaAjustesState extends State<PaginaAjustes> {
); );
}, },
child: ListTile( child: ListTile(
title: const Text("Incluir subcarpetas"), title: const Text("Incluir subcarpetas por defecto"),
subtitle: Text(PaginaAjustes.opcionesIncluirSubcarpetas[incluirSubcarpeta]), subtitle: Text(PaginaAjustes.opcionesIncluirSubcarpetas[incluirSubcarpeta]),
), ),
), ),
...@@ -85,20 +109,30 @@ class _PaginaAjustesState extends State<PaginaAjustes> { ...@@ -85,20 +109,30 @@ class _PaginaAjustesState extends State<PaginaAjustes> {
onTap: () { onTap: () {
var callbacks = <VoidCallback>[]; var callbacks = <VoidCallback>[];
PaginaAjustes.opcionesCarpetaSalida.asMap().forEach( PaginaAjustes.opcionesCarpetaSalida.asMap().forEach(
(index, opcion) => callbacks.add(() { (index, opcion) => (index == 0)?
setState(() {carpetaSalida = index;}); callbacks.add(() => _elegirCarpetaSalida(context, index, 1)) :
callbacks.add(() {
setState(() {
carpetaSalida = '';
carpetaSalidaIndex = index;
});
widget.provider.setCarpetaSalida('');
Navigator.pop(context); Navigator.pop(context);
}) })
); );
mostrarDialogoOpciones( mostrarDialogoOpciones(
opciones: PaginaAjustes.opcionesCarpetaSalida, opciones: PaginaAjustes.opcionesCarpetaSalida,
callbacks: callbacks, callbacks: callbacks,
seleccionado: carpetaSalida seleccionado: carpetaSalidaIndex
); );
}, },
child: ListTile( child: ListTile(
title: const Text("Carpeta de salida"), title: const Text("Carpeta de salida"),
subtitle: Text(PaginaAjustes.opcionesCarpetaSalida[carpetaSalida]), subtitle: Text(
(carpetaSalida.isEmpty)?
PaginaAjustes.opcionesCarpetaSalida[carpetaSalidaIndex] :
carpetaSalida
),
), ),
), ),
InkWell( InkWell(
...@@ -113,6 +147,13 @@ class _PaginaAjustesState extends State<PaginaAjustes> { ...@@ -113,6 +147,13 @@ class _PaginaAjustesState extends State<PaginaAjustes> {
"Convertex", "Convertex",
style: textTheme.titleLarge, style: textTheme.titleLarge,
), ),
const SizedBox(height: 16.0,),
Text(
"Desarrollado por:",
style: textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.bold
),
),
const SizedBox(height: 8.0,), const SizedBox(height: 8.0,),
Text( Text(
"Diego Pérez Peña", "Diego Pérez Peña",
...@@ -130,7 +171,7 @@ class _PaginaAjustesState extends State<PaginaAjustes> { ...@@ -130,7 +171,7 @@ class _PaginaAjustesState extends State<PaginaAjustes> {
}); });
}, },
child: ListTile( child: ListTile(
title: const Text("Creadores"), title: const Text("Acerca de..."),
), ),
), ),
], ],
...@@ -170,4 +211,58 @@ class _PaginaAjustesState extends State<PaginaAjustes> { ...@@ -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:async';
import 'dart:io'; import 'dart:io';
import 'package:ffmpeg_kit_flutter/ffmpeg_kit.dart'; import 'package:ffmpeg_kit_flutter_new/ffmpeg_kit.dart';
import 'package:ffmpeg_kit_flutter/ffmpeg_session.dart'; import 'package:ffmpeg_kit_flutter_new/ffmpeg_session.dart';
import 'package:ffmpeg_kit_flutter/ffprobe_kit.dart'; import 'package:ffmpeg_kit_flutter_new/ffprobe_kit.dart';
import 'package:ffmpeg_kit_flutter/ffprobe_session.dart'; import 'package:ffmpeg_kit_flutter_new/ffprobe_session.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:open_file/open_file.dart'; import 'package:open_file/open_file.dart';
import 'package:provider/provider.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/widgets/widgets.dart';
import 'package:prueba_multimedia/modelo/modelo.dart'; import 'package:prueba_multimedia/modelo/modelo.dart';
import 'package:prueba_multimedia/paginas/paginas.dart'; import 'package:prueba_multimedia/paginas/paginas.dart';
...@@ -19,7 +20,6 @@ class PaginaPrincipal extends StatelessWidget { ...@@ -19,7 +20,6 @@ class PaginaPrincipal extends StatelessWidget {
action: SnackBarAction( action: SnackBarAction(
label: 'VER', label: 'VER',
onPressed: () async { onPressed: () async {
// TODO: Cambiar esta dirección por la de los ajustes
await OpenFile.open('/storage/emulated/0/Pictures/Screenshots'); await OpenFile.open('/storage/emulated/0/Pictures/Screenshots');
}, },
), ),
...@@ -36,15 +36,25 @@ class PaginaPrincipal extends StatelessWidget { ...@@ -36,15 +36,25 @@ class PaginaPrincipal extends StatelessWidget {
), ),
backgroundColor: Theme.of(context).primaryColor, backgroundColor: Theme.of(context).primaryColor,
actions: [ actions: [
IconButton( Consumer<ProviderAjustes>(
builder: (context, ajustes, child) {
return IconButton(
icon: Icon( icon: Icon(
Icons.settings_outlined, Icons.settings_outlined,
color: Colors.white, color: Colors.white,
), ),
onPressed: () { onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: Navigator.push(context,
(context) => PaginaAjustes() MaterialPageRoute(
)); builder: (context) {
return PaginaAjustes(
provider: ajustes
);
}
)
);
}
);
} }
) )
] ]
...@@ -56,10 +66,10 @@ class PaginaPrincipal extends StatelessWidget { ...@@ -56,10 +66,10 @@ class PaginaPrincipal extends StatelessWidget {
} }
Widget _construirCuerpo(BuildContext context) { Widget _construirCuerpo(BuildContext context) {
return Consumer<ListaSeleccionables>( return Consumer2<ListaSeleccionables, ProviderAjustes>(
builder: (context, manager, child) { builder: (context, lista, ajustes, child) {
if (manager.seleccionables.isNotEmpty) { if (lista.seleccionables.isNotEmpty) {
return PaginaPrincipalLlena(listaSeleccionables: manager); return PaginaPrincipalLlena(listaSeleccionables: lista);
} else { } else {
return PaginaPrincipalVacia(); return PaginaPrincipalVacia();
} }
...@@ -68,13 +78,13 @@ class PaginaPrincipal extends StatelessWidget { ...@@ -68,13 +78,13 @@ class PaginaPrincipal extends StatelessWidget {
} }
Widget _construitFAB(BuildContext context, VoidCallback function){ Widget _construitFAB(BuildContext context, VoidCallback function){
return Consumer<ListaSeleccionables>( return Consumer2<ListaSeleccionables, ProviderAjustes>(
builder: (context, manager, child) { builder: (context, lista, ajustes, child) {
if (manager.convirtiendo) { if (lista.convirtiendo) {
return Padding ( return Padding (
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: ConvertexProgressBar( child: ConvertexProgressBar(
progress: manager.progress, progress: lista.progress,
textColor: Colors.black, textColor: Colors.black,
completedBackground: Colors.purpleAccent.shade100, completedBackground: Colors.purpleAccent.shade100,
) )
...@@ -83,8 +93,9 @@ class PaginaPrincipal extends StatelessWidget { ...@@ -83,8 +93,9 @@ class PaginaPrincipal extends StatelessWidget {
return Padding ( return Padding (
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: ConVertexFabBar( child: ConVertexFabBar(
allowConversion: manager.seleccionables.isNotEmpty, allowConversion: lista.seleccionables.isNotEmpty,
onConvertSuccess: function, onConvertSuccess: function,
providerAjustes: ajustes,
) )
); );
} }
......
...@@ -51,9 +51,13 @@ class PaginaPrincipalLlena extends StatelessWidget { ...@@ -51,9 +51,13 @@ class PaginaPrincipalLlena extends StatelessWidget {
), ),
onDismissed: (direction) { onDismissed: (direction) {
listaSeleccionables.borraSeleccionable(index); listaSeleccionables.borraSeleccionable(index);
String nombreCarp = seleccionables[index].nombre;
if(nombreCarp.length > 60){
nombreCarp = '${nombreCarp.substring(0, 61)}...';
}
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text('${seleccionables[index].nombre} borrado'), content: Text('$nombreCarp borrado'),
action: SnackBarAction( action: SnackBarAction(
label: 'Deshacer', label: 'Deshacer',
onPressed: () { onPressed: () {
......
...@@ -3,12 +3,14 @@ import 'package:flutter/material.dart'; ...@@ -3,12 +3,14 @@ import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:prueba_multimedia/modelo/modelo.dart'; import 'package:prueba_multimedia/modelo/modelo.dart';
import 'package:prueba_multimedia/modelo/provider_ajustes.dart';
class ActionButton extends StatelessWidget { class ActionButton extends StatelessWidget {
final ActionButtonTypes tipoBoton; final ActionButtonTypes tipoBoton;
final ListaSeleccionables manager; final ListaSeleccionables manager;
final BuildContext context; final BuildContext context;
final VoidCallback? onSuccess; final VoidCallback? onSuccess;
final ProviderAjustes providerAjustes;
final bool disabled; final bool disabled;
const ActionButton({ const ActionButton({
...@@ -17,7 +19,9 @@ class ActionButton extends StatelessWidget { ...@@ -17,7 +19,9 @@ class ActionButton extends StatelessWidget {
required this.manager, required this.manager,
required this.context, required this.context,
this.onSuccess, this.onSuccess,
required this.disabled}); required this.disabled,
required this.providerAjustes
});
void Function()? getCallback() { void Function()? getCallback() {
if(disabled) return null; if(disabled) return null;
...@@ -72,29 +76,12 @@ class ActionButton extends StatelessWidget { ...@@ -72,29 +76,12 @@ class ActionButton extends StatelessWidget {
} }
void carpetaAction() async { void carpetaAction() async {
// Comprobación de permisos if(await comprobacionPermisoArchivos(context)){
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) { FilePicker.platform.getDirectoryPath().then( (path) {
if (path != null) { if (path != null) {
bool inc = (!providerAjustes.cargando && providerAjustes.incluirSubcarpetas == 0)? true : false;
var directory = Directory(path); var directory = Directory(path);
final res = manager.addCarpeta(directory); final res = manager.addCarpeta(directory, inc);
if(res){ if(res){
if(context.mounted && onSuccess != null){ if(context.mounted && onSuccess != null){
onSuccess!(); onSuccess!();
...@@ -114,13 +101,14 @@ class ActionButton extends StatelessWidget { ...@@ -114,13 +101,14 @@ class ActionButton extends StatelessWidget {
} }
}); });
} }
}
void enlaceAction() { void enlaceAction() {
} }
void copiarAction() async { void copiarAction() async {
if(await comprobacionesPrevias()){ if(await _comprobacionesPreviasConversion(context)){
actualizadorProgreso(); actualizadorProgreso();
// Averiguamos donde colocar los archivos de salida // Averiguamos donde colocar los archivos de salida
...@@ -149,7 +137,7 @@ class ActionButton extends StatelessWidget { ...@@ -149,7 +137,7 @@ class ActionButton extends StatelessWidget {
} }
void comprimirAction() async { void comprimirAction() async {
if(await comprobacionesPrevias()){ if(await _comprobacionesPreviasConversion(context)){
actualizadorProgreso(); actualizadorProgreso();
// TODO: Código de compresión // TODO: Código de compresión
...@@ -157,7 +145,7 @@ class ActionButton extends StatelessWidget { ...@@ -157,7 +145,7 @@ class ActionButton extends StatelessWidget {
} }
void reemplazarAction() async { void reemplazarAction() async {
if(await comprobacionesPrevias()){ if(await _comprobacionesPreviasConversion(context)){
actualizadorProgreso(); actualizadorProgreso();
// Convertimos los archivos como tal // Convertimos los archivos como tal
...@@ -190,12 +178,36 @@ class ActionButton extends StatelessWidget { ...@@ -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 // 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; 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( await showDialog(
context: context, context: context,
builder: (context) { builder: (context) {
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:prueba_multimedia/modelo/modelo.dart'; import 'package:prueba_multimedia/modelo/modelo.dart';
import 'package:prueba_multimedia/modelo/provider_ajustes.dart';
import 'package:prueba_multimedia/widgets/widgets.dart'; import 'package:prueba_multimedia/widgets/widgets.dart';
class ConVertexFabBar extends StatefulWidget { class ConVertexFabBar extends StatefulWidget {
final bool allowConversion; final bool allowConversion;
final VoidCallback onConvertSuccess; final VoidCallback onConvertSuccess;
final ProviderAjustes providerAjustes;
const ConVertexFabBar({ const ConVertexFabBar({
super.key, super.key,
required this.allowConversion, required this.allowConversion,
required this.onConvertSuccess required this.onConvertSuccess,
required this.providerAjustes
}); });
@override @override
...@@ -82,6 +85,7 @@ class _ConVertexFabBarState extends State<ConVertexFabBar> { ...@@ -82,6 +85,7 @@ class _ConVertexFabBarState extends State<ConVertexFabBar> {
context: context, context: context,
disabled: !widget.allowConversion && type.isConvertir(), disabled: !widget.allowConversion && type.isConvertir(),
onSuccess: widget.onConvertSuccess, onSuccess: widget.onConvertSuccess,
providerAjustes: widget.providerAjustes,
); );
}).toList(); }).toList();
} }
...@@ -167,7 +171,8 @@ class _ConVertexFabBarState extends State<ConVertexFabBar> { ...@@ -167,7 +171,8 @@ class _ConVertexFabBarState extends State<ConVertexFabBar> {
manager: manager, manager: manager,
context: context, context: context,
onSuccess: closeButtons, onSuccess: closeButtons,
disabled: false disabled: false,
providerAjustes: widget.providerAjustes,
); );
}).toList(); }).toList();
} }
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.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/paginas/paginas.dart';
import 'package:prueba_multimedia/modelo/modelo.dart'; import 'package:prueba_multimedia/modelo/modelo.dart';
...@@ -21,7 +22,8 @@ class ConvertexPrototipoApp extends StatelessWidget { ...@@ -21,7 +22,8 @@ class ConvertexPrototipoApp extends StatelessWidget {
themeMode: ThemeMode.system, themeMode: ThemeMode.system,
home: MultiProvider( home: MultiProvider(
providers: [ providers: [
ChangeNotifierProvider(create: (context) => ListaSeleccionables()) ChangeNotifierProvider(create: (context) => ListaSeleccionables()),
ChangeNotifierProvider(create: (context) => ProviderAjustes())
], ],
child: PaginaPrincipal(), child: PaginaPrincipal(),
), ),
......
...@@ -5,12 +5,16 @@ ...@@ -5,12 +5,16 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import ffmpeg_kit_flutter_new
import file_picker import file_picker
import open_file_mac import open_file_mac
import path_provider_foundation import path_provider_foundation
import shared_preferences_foundation
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FFmpegKitFlutterPlugin.register(with: registry.registrar(forPlugin: "FFmpegKitFlutterPlugin"))
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin")) FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
OpenFilePlugin.register(with: registry.registrar(forPlugin: "OpenFilePlugin")) OpenFilePlugin.register(with: registry.registrar(forPlugin: "OpenFilePlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
} }
...@@ -81,14 +81,22 @@ packages: ...@@ -81,14 +81,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.3" 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" dependency: "direct main"
description: description:
name: ffmpeg_kit_flutter name: ffmpeg_kit_flutter_new
sha256: "843aae41823ca94a0988d975b4b6cdc6948744b9b7e2707d81a3a9cd237b0100" sha256: dbaf0f4963b08a034a4f787276c1e12efc36a56670693f1721e46f95554f0979
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.0.3" version: "1.6.1"
ffmpeg_kit_flutter_platform_interface: ffmpeg_kit_flutter_platform_interface:
dependency: transitive dependency: transitive
description: description:
...@@ -97,6 +105,14 @@ packages: ...@@ -97,6 +105,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.2.1" version: "0.2.1"
file:
dependency: transitive
description:
name: file
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
url: "https://pub.dev"
source: hosted
version: "7.0.1"
file_picker: file_picker:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -400,6 +416,62 @@ packages: ...@@ -400,6 +416,62 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.1.2" 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: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
......
...@@ -37,10 +37,11 @@ dependencies: ...@@ -37,10 +37,11 @@ dependencies:
provider: ^6.1.2 provider: ^6.1.2
file_picker: ^9.0.2 file_picker: ^9.0.2
uuid: ^4.5.1 uuid: ^4.5.1
ffmpeg_kit_flutter: ^6.0.3
path_provider: ^2.1.5 path_provider: ^2.1.5
permission_handler: ^12.0.0+1 permission_handler: ^12.0.0+1
open_file: ^3.5.10 open_file: ^3.5.10
ffmpeg_kit_flutter_new: ^1.6.1
shared_preferences: ^2.5.3
dev_dependencies: dev_dependencies:
flutter_test: 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