Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Rafa Castillo Passols
/
Prototipo-Multimedia
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
93c9a0c8
authored
May 28, 2025
by
Diego Pérez Peña
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Comentando código y otros cambios
parent
ea0518c7
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
190 additions
and
45 deletions
lib/modelo/conversor.dart
lib/modelo/enlace.dart
lib/paginas/pagina_ajustes.dart
lib/paginas/pagina_configuracion_carpeta.dart
lib/paginas/pagina_conversion.dart
lib/widgets/action_button.dart
lib/widgets/carpeta_widget.dart
lib/widgets/convertex_fab_bar.dart
lib/widgets/convertex_progress_bar.dart
lib/widgets/convertex_prototipo_app.dart
lib/widgets/convertible_widget.dart
lib/widgets/expandable_fab.dart
lib/modelo/conversor.dart
View file @
93c9a0c8
...
@@ -15,7 +15,6 @@ abstract class Conversor {
...
@@ -15,7 +15,6 @@ abstract class Conversor {
ReturnCode
?
returnCode
;
ReturnCode
?
returnCode
;
String
nuevoPath
=
"
$pathSalida
/
${archivo.nombre}
.
${archivo.formatoDestino!.name}
"
;
String
nuevoPath
=
"
$pathSalida
/
${archivo.nombre}
.
${archivo.formatoDestino!.name}
"
;
// TODO: REVISAR EL SACAR FOTOGRAMA. NO PARECE SALIR NADA
bool
conversionVideoAOtro
=
bool
conversionVideoAOtro
=
archivo
.
formatoOriginal
.
tipoMultimedia
==
TipoMultimedia
.
video
archivo
.
formatoOriginal
.
tipoMultimedia
==
TipoMultimedia
.
video
&&
archivo
.
formatoDestino
?.
tipoMultimedia
!=
TipoMultimedia
.
video
;
&&
archivo
.
formatoDestino
?.
tipoMultimedia
!=
TipoMultimedia
.
video
;
...
@@ -55,7 +54,6 @@ abstract class Conversor {
...
@@ -55,7 +54,6 @@ abstract class Conversor {
continue
;
continue
;
}
}
var
campos
=
linea
.
split
(
"="
);
var
campos
=
linea
.
split
(
"="
);
// TODO: Chequear metadatos que falten
try
{
try
{
metadatos
.
add
(
metadatos
.
add
(
Metadato
(
Metadato
(
...
...
lib/modelo/enlace.dart
View file @
93c9a0c8
...
@@ -59,7 +59,6 @@ class Enlace extends Convertible {
...
@@ -59,7 +59,6 @@ class Enlace extends Convertible {
nombre
=
nombre
.
substring
(
1
,
nombre
.
length
-
1
);
nombre
=
nombre
.
substring
(
1
,
nombre
.
length
-
1
);
}
}
// filename* encoding, habría que parsear en UTF8
// filename* encoding, habría que parsear en UTF8
// TODO: parsear en el caso de filename*
else
{
else
{
nombre
=
nombre
.
substring
(
7
);
nombre
=
nombre
.
substring
(
7
);
}
}
...
...
lib/paginas/pagina_ajustes.dart
View file @
93c9a0c8
...
@@ -6,13 +6,17 @@ import 'package:permission_handler/permission_handler.dart';
...
@@ -6,13 +6,17 @@ import 'package:permission_handler/permission_handler.dart';
import
'package:prueba_multimedia/modelo/provider_ajustes.dart'
;
import
'package:prueba_multimedia/modelo/provider_ajustes.dart'
;
import
'package:prueba_multimedia/widgets/action_button.dart'
;
import
'package:prueba_multimedia/widgets/action_button.dart'
;
/// Página de Ajustes de la aplicación
class
PaginaAjustes
extends
StatefulWidget
{
class
PaginaAjustes
extends
StatefulWidget
{
/// Las diferentes opciones del modo de conversión
static
const
opcionesModoConversion
=
<
String
>[
static
const
opcionesModoConversion
=
<
String
>[
"Preguntar siempre"
,
"Copiar"
,
"Comprimir"
"Preguntar siempre"
,
"Copiar"
,
"Comprimir"
];
];
/// Las diferentes opciones de la inclusión de subcarpetas
static
const
opcionesIncluirSubcarpetas
=
<
String
>[
static
const
opcionesIncluirSubcarpetas
=
<
String
>[
"Sí"
,
"No"
"Sí"
,
"No"
];
];
/// Las diferentes opciones de la selección de carpeta de salida
// 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"
...
...
lib/paginas/pagina_configuracion_carpeta.dart
View file @
93c9a0c8
...
@@ -23,8 +23,6 @@ class PaginaConfiguracionCarpeta extends StatefulWidget {
...
@@ -23,8 +23,6 @@ class PaginaConfiguracionCarpeta extends StatefulWidget {
State
<
PaginaConfiguracionCarpeta
>
createState
()
=>
_PaginaConfiguracionCarpetaState
();
State
<
PaginaConfiguracionCarpeta
>
createState
()
=>
_PaginaConfiguracionCarpetaState
();
}
}
// TODO: Se muestran formatos repetidos porque se consideran distintos
// al ser un de subcarpeta y otro no
class
_PaginaConfiguracionCarpetaState
extends
State
<
PaginaConfiguracionCarpeta
>
{
class
_PaginaConfiguracionCarpetaState
extends
State
<
PaginaConfiguracionCarpeta
>
{
final
Map
<
TipoMultimedia
,
List
<
Formato
>>
_formatos
=
{};
final
Map
<
TipoMultimedia
,
List
<
Formato
>>
_formatos
=
{};
final
Map
<
TipoMultimedia
,
bool
?>
_allOfType
=
{};
final
Map
<
TipoMultimedia
,
bool
?>
_allOfType
=
{};
...
...
lib/paginas/pagina_conversion.dart
View file @
93c9a0c8
...
@@ -136,7 +136,6 @@ class _PaginaConversionState extends State<PaginaConversion>
...
@@ -136,7 +136,6 @@ class _PaginaConversionState extends State<PaginaConversion>
selected:
elemento
==
_calidadActual
,
selected:
elemento
==
_calidadActual
,
shape:
StadiumBorder
(),
shape:
StadiumBorder
(),
label:
Text
(
elemento
.
texto
),
label:
Text
(
elemento
.
texto
),
// TODO: CAMBIAR CALIDAD FORMATO
onSelected:
(
_formatoConvertido
!=
null
&&
_formatoConvertido
!.
listCalidades
.
contains
(
elemento
))?
onSelected:
(
_formatoConvertido
!=
null
&&
_formatoConvertido
!.
listCalidades
.
contains
(
elemento
))?
(
selected
)
{
setState
((){
_calidadActual
=
elemento
;});
}
:
null
,
(
selected
)
{
setState
((){
_calidadActual
=
elemento
;});
}
:
null
,
);
);
...
...
lib/widgets/action_button.dart
View file @
93c9a0c8
...
@@ -6,6 +6,7 @@ import 'package:file_picker/file_picker.dart';
...
@@ -6,6 +6,7 @@ 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'
;
/// Clase que representa los botones de acción de la página principal
class
ActionButton
extends
StatelessWidget
{
class
ActionButton
extends
StatelessWidget
{
final
ActionButtonTypes
tipoBoton
;
final
ActionButtonTypes
tipoBoton
;
final
ListaSeleccionables
manager
;
final
ListaSeleccionables
manager
;
...
@@ -174,7 +175,6 @@ class ActionButton extends StatelessWidget {
...
@@ -174,7 +175,6 @@ class ActionButton extends StatelessWidget {
}
}
/// Igual que copiar pero guarda el resultado en un .zip
/// Igual que copiar pero guarda el resultado en un .zip
/// TODO (RAFA): CREAR LOS ARCHIVOS TEMPORALES EN OTRO SITIO
void
comprimirAction
()
async
{
void
comprimirAction
()
async
{
if
(
await
_comprobacionesPreviasConversion
(
context
))
{
if
(
await
_comprobacionesPreviasConversion
(
context
))
{
// Averiguamos donde colocar los archivos de salida
// Averiguamos donde colocar los archivos de salida
...
@@ -216,7 +216,6 @@ class ActionButton extends StatelessWidget {
...
@@ -216,7 +216,6 @@ class ActionButton extends StatelessWidget {
else
if
(
sel
is
Convertible
){
else
if
(
sel
is
Convertible
){
sel
.
convertir
(
directorioSalida
);
sel
.
convertir
(
directorioSalida
);
File
tempFile
=
await
File
(
File
tempFile
=
await
File
(
// TODO: Esto da bug con los enlaces por el nombre
"
$directorioSalida
/
${sel.nombre}
.
${sel.formatoDestino?.name}
"
"
$directorioSalida
/
${sel.nombre}
.
${sel.formatoDestino?.name}
"
).
create
();
).
create
();
resultsZip
.
add
(
resultsZip
.
add
(
...
@@ -272,7 +271,6 @@ class ActionButton extends StatelessWidget {
...
@@ -272,7 +271,6 @@ class ActionButton extends StatelessWidget {
}
}
/// Comprueba si tenemos permisos suficientes
/// Comprueba si tenemos permisos suficientes
// TODO: Añadir aquí una notificación para avisar al usuario de si quiere realmente convertir una carpeta muy grande
Future
<
bool
>
_comprobacionesPreviasConversion
(
BuildContext
context
)
async
{
Future
<
bool
>
_comprobacionesPreviasConversion
(
BuildContext
context
)
async
{
if
(!
await
comprobacionPermisoArchivos
(
context
)){
if
(!
await
comprobacionPermisoArchivos
(
context
)){
return
false
;
return
false
;
...
...
lib/widgets/carpeta_widget.dart
View file @
93c9a0c8
...
@@ -8,7 +8,9 @@ import 'dart:math';
...
@@ -8,7 +8,9 @@ import 'dart:math';
import
'package:uuid/uuid.dart'
;
import
'package:uuid/uuid.dart'
;
import
'package:uuid/v1.dart'
;
import
'package:uuid/v1.dart'
;
/// Widget para mostrar carpetas en la lista de archivos de la página principal
class
CarpetaWidget
extends
StatefulWidget
{
class
CarpetaWidget
extends
StatefulWidget
{
/// Índice de la carpeta en cuestión en la lista de seleccionables
final
int
indice
;
final
int
indice
;
final
Carpeta
carpeta
;
final
Carpeta
carpeta
;
final
ListaSeleccionables
lista
;
final
ListaSeleccionables
lista
;
...
@@ -24,16 +26,22 @@ class _CarpetaWidgetState extends State<CarpetaWidget>
...
@@ -24,16 +26,22 @@ class _CarpetaWidgetState extends State<CarpetaWidget>
with
SingleTickerProviderStateMixin
with
SingleTickerProviderStateMixin
{
{
static
const
double
maxHeight
=
50
;
static
const
double
maxHeight
=
50
;
/// Controlador para la animación de apertura y cierre
late
final
AnimationController
_controller
;
late
final
AnimationController
_controller
;
/// Archivos (o carpetas si es recursivo) que el usuario no ha eliminado
/// Archivos (o carpetas si es recursivo) que el usuario no ha eliminado
/// de la lista y que coinciden con los formatos elegidos
/// de la lista y que coinciden con los formatos elegidos
List
<
InfoFormato
>
seleccionados
=
[];
List
<
InfoFormato
>
seleccionados
=
[];
/// Controla si el widget está abierto o cerrado
bool
open
=
false
;
bool
open
=
false
;
/// Controla la rotación del icono de desplegar / colapsar
double
rotAngle
=
0
;
double
rotAngle
=
0
;
/// Controla la altura de las entradas de formato
double
height
=
0
;
double
height
=
0
;
/// Inicializa el controlador
@override
@override
void
initState
()
{
void
initState
()
{
super
.
initState
();
_controller
=
AnimationController
(
_controller
=
AnimationController
(
duration:
const
Duration
(
milliseconds:
200
),
duration:
const
Duration
(
milliseconds:
200
),
vsync:
this
vsync:
this
...
@@ -44,7 +52,13 @@ class _CarpetaWidgetState extends State<CarpetaWidget>
...
@@ -44,7 +52,13 @@ class _CarpetaWidgetState extends State<CarpetaWidget>
height
=
maxHeight
*
_controller
.
value
;
height
=
maxHeight
*
_controller
.
value
;
});
});
});
});
super
.
initState
();
}
/// Libera los recursos del controlador
@override
void
dispose
()
{
_controller
.
dispose
();
super
.
dispose
();
}
}
@override
@override
...
@@ -74,6 +88,7 @@ class _CarpetaWidgetState extends State<CarpetaWidget>
...
@@ -74,6 +88,7 @@ class _CarpetaWidgetState extends State<CarpetaWidget>
);
);
}
}
/// Construye la entrada de la carpeta
Widget
buildMainContainer
(){
Widget
buildMainContainer
(){
Carpeta
carpeta
=
widget
.
carpeta
;
Carpeta
carpeta
=
widget
.
carpeta
;
// Para el plural indicando los formato(s) seleccionado(s)
// Para el plural indicando los formato(s) seleccionado(s)
...
@@ -164,6 +179,7 @@ class _CarpetaWidgetState extends State<CarpetaWidget>
...
@@ -164,6 +179,7 @@ class _CarpetaWidgetState extends State<CarpetaWidget>
);
);
}
}
/// Construye las entradas de los formatos
List
<
Widget
>
buildSecondaryContainers
(){
List
<
Widget
>
buildSecondaryContainers
(){
Carpeta
carpeta
=
widget
.
carpeta
;
Carpeta
carpeta
=
widget
.
carpeta
;
int
index
=
0
;
int
index
=
0
;
...
@@ -295,6 +311,7 @@ class _CarpetaWidgetState extends State<CarpetaWidget>
...
@@ -295,6 +311,7 @@ class _CarpetaWidgetState extends State<CarpetaWidget>
}
}
}
}
/// Clase encargada de cortar las entradas de los formatos durante la animación
class
_MyRectClipper
extends
CustomClipper
<
Rect
>
{
class
_MyRectClipper
extends
CustomClipper
<
Rect
>
{
final
AnimationController
_controller
;
final
AnimationController
_controller
;
...
...
lib/widgets/convertex_fab_bar.dart
View file @
93c9a0c8
...
@@ -11,9 +11,14 @@ import 'package:prueba_multimedia/paginas/pagina_configuracion.dart';
...
@@ -11,9 +11,14 @@ import 'package:prueba_multimedia/paginas/pagina_configuracion.dart';
import
'package:prueba_multimedia/paginas/pagina_configuracion_carpeta.dart'
;
import
'package:prueba_multimedia/paginas/pagina_configuracion_carpeta.dart'
;
import
'package:prueba_multimedia/widgets/widgets.dart'
;
import
'package:prueba_multimedia/widgets/widgets.dart'
;
/// Widget que representa la barra inferior de botones de acción de la pantalla
/// principal
class
ConVertexFabBar
extends
StatefulWidget
{
class
ConVertexFabBar
extends
StatefulWidget
{
/// Si se permite o no convertir (o sea, si hay o no seleccionables en la lista)
final
bool
allowConversion
;
final
bool
allowConversion
;
/// Acción que deben realizar los botones de conversión al finalizar
final
VoidCallback
onConvertSuccess
;
final
VoidCallback
onConvertSuccess
;
/// Provider con los ajustes de la aplicación
final
ProviderAjustes
providerAjustes
;
final
ProviderAjustes
providerAjustes
;
const
ConVertexFabBar
({
const
ConVertexFabBar
({
...
@@ -28,17 +33,22 @@ class ConVertexFabBar extends StatefulWidget {
...
@@ -28,17 +33,22 @@ class ConVertexFabBar extends StatefulWidget {
}
}
class
_ConVertexFabBarState
extends
State
<
ConVertexFabBar
>
{
class
_ConVertexFabBarState
extends
State
<
ConVertexFabBar
>
{
bool
_convertirOpen
=
false
;
/// Si el botón de Agregar está expandido
bool
_agregarOpen
=
false
;
bool
_agregarOpen
=
false
;
/// Si el botón de Convertir está expandido
bool
_convertirOpen
=
false
;
/// Clave que se utiliza para abrir y cerrar el botón de Agregar
final
_agregarKey
=
GlobalKey
<
ExpandableFabState
>();
final
_agregarKey
=
GlobalKey
<
ExpandableFabState
>();
/// Clave que se utiliza para abrir y cerrar el botón de Convertir
final
_convertirKey
=
GlobalKey
<
ExpandableFabState
>();
final
_convertirKey
=
GlobalKey
<
ExpandableFabState
>();
/// Los botones de acción dentro del botón expansible Agregar
static
const
agregarButtonTypes
=
<
ActionButtonTypes
>[
static
const
agregarButtonTypes
=
<
ActionButtonTypes
>[
ActionButtonTypes
.
archivo
,
ActionButtonTypes
.
archivo
,
ActionButtonTypes
.
carpeta
,
ActionButtonTypes
.
carpeta
,
ActionButtonTypes
.
enlace
ActionButtonTypes
.
enlace
];
];
/// Los botones de acción dentro del botón expansible Convertir
static
const
convertirButtonTypes
=
<
ActionButtonTypes
>[
static
const
convertirButtonTypes
=
<
ActionButtonTypes
>[
ActionButtonTypes
.
copiar
,
ActionButtonTypes
.
copiar
,
ActionButtonTypes
.
comprimir
ActionButtonTypes
.
comprimir
...
@@ -78,21 +88,7 @@ class _ConVertexFabBarState extends State<ConVertexFabBar> {
...
@@ -78,21 +88,7 @@ class _ConVertexFabBarState extends State<ConVertexFabBar> {
);
);
}
}
List
<
Widget
>
_loadConvertirActionButtons
(
BuildContext
context
,
/// Construye los FABs expansibles
ListaSeleccionables
manager
)
{
return
convertirButtonTypes
.
map
((
type
)
{
return
ActionButton
(
tipoBoton:
type
,
manager:
manager
,
context:
context
,
disabled:
!(
widget
.
allowConversion
)
&&
type
.
isConvertir
,
onSuccess:
widget
.
onConvertSuccess
,
providerAjustes:
widget
.
providerAjustes
,
);
}).
toList
();
}
List
<
Widget
>
_buildFABs
(
ListaSeleccionables
manager
)
{
List
<
Widget
>
_buildFABs
(
ListaSeleccionables
manager
)
{
final
toRet
=
<
Widget
>[];
final
toRet
=
<
Widget
>[];
...
@@ -141,23 +137,13 @@ class _ConVertexFabBarState extends State<ConVertexFabBar> {
...
@@ -141,23 +137,13 @@ class _ConVertexFabBarState extends State<ConVertexFabBar> {
disabledElevation:
0
,
disabledElevation:
0
,
onPressed:
(!
widget
.
allowConversion
)?
null
:
onPressed:
(!
widget
.
allowConversion
)?
null
:
()
{
()
{
// Rafa: Esto es un poco un 'hack'
switch
(
widget
.
providerAjustes
.
modoConversion
){
case
1
:
final
tipoAccion
=
widget
.
providerAjustes
.
modoConversion
==
1
convertirCopiar
(
manager
);
?
ActionButtonTypes
.
copiar
break
;
:
ActionButtonTypes
.
comprimir
;
case
2
:
convertirComprimir
(
manager
);
final
callback
=
ActionButton
(
break
;
tipoBoton:
tipoAccion
,
manager:
manager
,
context:
context
,
disabled:
!(
widget
.
allowConversion
)
&&
tipoAccion
.
isConvertir
,
onSuccess:
widget
.
onConvertSuccess
,
providerAjustes:
widget
.
providerAjustes
,
).
getCallback
();
if
(
callback
!=
null
)
{
callback
();
}
}
},
},
));
));
...
@@ -195,6 +181,23 @@ class _ConVertexFabBarState extends State<ConVertexFabBar> {
...
@@ -195,6 +181,23 @@ class _ConVertexFabBarState extends State<ConVertexFabBar> {
return
toRet
;
return
toRet
;
}
}
/// Construye los botones de acción dentro del botón expansible Convertir
List
<
Widget
>
_loadConvertirActionButtons
(
BuildContext
context
,
ListaSeleccionables
manager
)
{
return
convertirButtonTypes
.
map
((
type
)
{
return
ActionButton
(
tipoBoton:
type
,
manager:
manager
,
context:
context
,
disabled:
!(
widget
.
allowConversion
)
&&
type
.
isConvertir
,
onSuccess:
widget
.
onConvertSuccess
,
providerAjustes:
widget
.
providerAjustes
,
);
}).
toList
();
}
/// Construye los botones de acción dentro del botón expansible Agregar
List
<
Widget
>
_loadAgregarActionButtons
(
BuildContext
context
,
List
<
Widget
>
_loadAgregarActionButtons
(
BuildContext
context
,
ListaSeleccionables
manager
)
ListaSeleccionables
manager
)
{
{
...
@@ -242,6 +245,110 @@ class _ConVertexFabBarState extends State<ConVertexFabBar> {
...
@@ -242,6 +245,110 @@ class _ConVertexFabBarState extends State<ConVertexFabBar> {
}).
toList
();
}).
toList
();
}
}
/// Acción que realiza el botón de convertir cuando el modo Copiar está
/// seleccionado en Ajustes
Future
<
void
>
convertirCopiar
(
ListaSeleccionables
manager
)
async
{
if
(
await
ActionButton
.
comprobacionPermisoArchivos
(
context
)){
String
?
directorioSalida
;
if
(
widget
.
providerAjustes
.
carpetaSalida
.
isNotEmpty
){
directorioSalida
=
widget
.
providerAjustes
.
carpetaSalida
;
}
else
{
directorioSalida
=
await
FilePicker
.
platform
.
getDirectoryPath
();
}
if
(
directorioSalida
!=
null
){
listenerActualizar
(
manager
);
// Convertimos los archivos como tal
List
<
Archivo
>
archivos
=
manager
.
seleccionables
.
whereType
<
Archivo
>().
toList
();
while
(
manager
.
seleccionables
.
isNotEmpty
){
ElementoSeleccionable
sel
=
manager
.
seleccionables
.
first
;
if
(
sel
is
Carpeta
){
for
(
var
archivo
in
sel
.
elementosSeleccionados
)
{
Directory
d
=
await
Directory
(
"
$directorioSalida
/
${sel.nombre}
"
).
create
();
Conversor
.
convertir
(
archivo
,
d
.
path
);
}
}
else
if
(
sel
is
Archivo
){
Conversor
.
convertir
(
sel
,
directorioSalida
);
}
manager
.
borraSeleccionable
(
0
);
}
}
}
}
/// Acción que realiza el botón de convertir cuando el modo Comprimir está
/// seleccionado en Ajustes
Future
<
void
>
convertirComprimir
(
ListaSeleccionables
manager
)
async
{
if
(
await
ActionButton
.
comprobacionPermisoArchivos
(
context
)){
// Averiguamos donde colocar los archivos de salida
String
?
directorioSalida
=
widget
.
providerAjustes
.
carpetaSalida
.
isNotEmpty
?
widget
.
providerAjustes
.
carpetaSalida
:
await
FilePicker
.
platform
.
getDirectoryPath
();
if
(
directorioSalida
!=
null
)
{
listenerActualizar
(
manager
);
final
now
=
DateTime
.
now
();
final
nombreZip
=
"ConVertex_"
"
${now.day}
-
${now.month}
-
${now.year}
_"
"
${now.hour}
-
${now.minute}
-
${now.second}
"
;
final
zipFileEncoder
=
ZipFileEncoder
();
zipFileEncoder
.
create
(
"
$directorioSalida
/
$nombreZip
.zip"
);
final
resultsZip
=
<
Future
<
void
>>[];
while
(
manager
.
seleccionables
.
isNotEmpty
){
ElementoSeleccionable
sel
=
manager
.
seleccionables
.
first
;
// Conversion de carpetas
if
(
sel
is
Carpeta
){
Directory
d
=
await
Directory
(
"
$directorioSalida
/
${sel.nombre}
"
).
create
();
final
resultsConversion
=
<
Future
<
ReturnCode
?>>[];
for
(
var
archivo
in
sel
.
elementosSeleccionados
)
{
resultsConversion
.
add
(
Conversor
.
convertir
(
archivo
,
d
.
path
));
}
// Esperamos a la conversión y añadimos a zip
for
(
final
result
in
resultsConversion
)
{
await
result
;
}
resultsZip
.
add
(
zipFileEncoder
.
addDirectory
(
d
)..
then
((
_
)
=>
d
.
delete
(
recursive:
true
))
);
}
// Conversion de archivos
else
if
(
sel
is
Archivo
){
// Esperamos a la conversión y añadimos a zip
await
Conversor
.
convertir
(
sel
,
directorioSalida
);
File
tempFile
=
await
File
(
"
$directorioSalida
/
${sel.nombre}
.
${sel.formatoDestino?.name}
"
).
create
();
resultsZip
.
add
(
zipFileEncoder
.
addFile
(
tempFile
)..
then
((
_
)
=>
tempFile
.
delete
())
);
}
// Esperamos a que la compresión se termine y se borren los
// archivos temporales
if
(
manager
.
seleccionables
.
length
==
1
)
{
for
(
final
result
in
resultsZip
)
{
await
result
;
}
zipFileEncoder
.
closeSync
();
}
// Esto hace que la barra de progreso suba
manager
.
borraSeleccionable
(
0
);
}
}
}
}
/// Listener que se encarga de actualizar el progreso conforme se convierten
/// los archivos
Future
<
void
>
listenerActualizar
(
ListaSeleccionables
manager
)
async
{
Future
<
void
>
listenerActualizar
(
ListaSeleccionables
manager
)
async
{
manager
.
iniciarConversion
();
manager
.
iniciarConversion
();
int
initialSize
=
manager
.
seleccionables
.
length
;
int
initialSize
=
manager
.
seleccionables
.
length
;
...
...
lib/widgets/convertex_progress_bar.dart
View file @
93c9a0c8
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
/// Un pequeño Widget que contiene la barra de progreso de la conversión
class
ConvertexProgressBar
extends
StatelessWidget
{
class
ConvertexProgressBar
extends
StatelessWidget
{
/// Progreso de la conversión
final
int
progress
;
final
int
progress
;
/// Alto y ancho de la barra
final
double
?
width
;
final
double
?
width
;
final
double
?
height
;
final
double
?
height
;
/// Colores de fondo, borde y texto de la barra de progreso
final
Color
?
background
;
final
Color
?
background
;
final
Color
?
completedBackground
;
final
Color
?
completedBackground
;
final
Color
?
borderColor
;
final
Color
?
borderColor
;
...
...
lib/widgets/convertex_prototipo_app.dart
View file @
93c9a0c8
...
@@ -4,12 +4,14 @@ import 'package:prueba_multimedia/modelo/provider_ajustes.dart';
...
@@ -4,12 +4,14 @@ 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'
;
/// Clase que representa la aplicación de ConVertex
class
ConvertexPrototipoApp
extends
StatelessWidget
{
class
ConvertexPrototipoApp
extends
StatelessWidget
{
const
ConvertexPrototipoApp
({
super
.
key
});
const
ConvertexPrototipoApp
({
super
.
key
});
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
MaterialApp
(
return
MaterialApp
(
title:
'ConVertex'
,
theme:
ThemeData
(
theme:
ThemeData
(
colorScheme:
ColorScheme
.
fromSeed
(
seedColor:
Colors
.
deepPurple
)
colorScheme:
ColorScheme
.
fromSeed
(
seedColor:
Colors
.
deepPurple
)
),
),
...
...
lib/widgets/convertible_widget.dart
View file @
93c9a0c8
...
@@ -2,7 +2,9 @@ import 'package:flutter/material.dart';
...
@@ -2,7 +2,9 @@ import 'package:flutter/material.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'
;
/// Widget para mostrar archivos y enlaces en la lista de archivos de la página principal
class
ConvertibleWidget
extends
StatelessWidget
{
class
ConvertibleWidget
extends
StatelessWidget
{
/// Índice del archivo o enlace en cuestión en la lista de seleccionables
final
int
indice
;
final
int
indice
;
final
Convertible
convertible
;
final
Convertible
convertible
;
final
ListaSeleccionables
lista
;
final
ListaSeleccionables
lista
;
...
@@ -10,7 +12,6 @@ class ConvertibleWidget extends StatelessWidget {
...
@@ -10,7 +12,6 @@ class ConvertibleWidget extends StatelessWidget {
const
ConvertibleWidget
({
super
.
key
,
const
ConvertibleWidget
({
super
.
key
,
required
this
.
indice
,
required
this
.
convertible
,
required
this
.
lista
});
required
this
.
indice
,
required
this
.
convertible
,
required
this
.
lista
});
// TODO: ACTUALIZAR PARA MOSTRAR FORMATOS Y CAMBIOS
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
final
String
nombre
=
convertible
.
nombre
;
final
String
nombre
=
convertible
.
nombre
;
...
...
lib/widgets/expandable_fab.dart
View file @
93c9a0c8
import
'dart:math'
;
import
'dart:math'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
/// Widget que contiene un botón expansible, como los usados en la página
/// principal. Inspirados en [https://docs.flutter.dev/cookbook/effects/expandable-fab]
@immutable
@immutable
class
ExpandableFab
extends
StatefulWidget
{
class
ExpandableFab
extends
StatefulWidget
{
final
bool
?
initialOpen
;
final
bool
?
initialOpen
;
/// Si es true, se alinea a la izquierda
final
bool
invert
;
final
bool
invert
;
/// Icono del FAB
final
Icon
icon
;
final
Icon
icon
;
/// Texto del FAB
final
String
?
label
;
final
String
?
label
;
/// Distancia a la que se crean los hijos del FAB
final
double
distance
;
final
double
distance
;
/// Lista de hijos del FAB
final
List
<
Widget
>
children
;
final
List
<
Widget
>
children
;
const
ExpandableFab
({
const
ExpandableFab
({
...
@@ -26,8 +33,10 @@ class ExpandableFab extends StatefulWidget {
...
@@ -26,8 +33,10 @@ class ExpandableFab extends StatefulWidget {
class
ExpandableFabState
extends
State
<
ExpandableFab
>
class
ExpandableFabState
extends
State
<
ExpandableFab
>
with
SingleTickerProviderStateMixin
{
with
SingleTickerProviderStateMixin
{
/// Controladores de la animación
late
final
AnimationController
_controller
;
late
final
AnimationController
_controller
;
late
final
Animation
<
double
>
_expandAnimation
;
late
final
Animation
<
double
>
_expandAnimation
;
/// Si está abierto
bool
_open
=
false
;
bool
_open
=
false
;
@override
@override
...
@@ -52,16 +61,19 @@ class ExpandableFabState extends State<ExpandableFab>
...
@@ -52,16 +61,19 @@ class ExpandableFabState extends State<ExpandableFab>
super
.
dispose
();
super
.
dispose
();
}
}
/// Simula una pulsación sobre el botón
void
tap
(){
void
tap
(){
_toggle
();
_toggle
();
}
}
/// Simula el cierre del botón
void
close
(){
void
close
(){
if
(
_open
){
if
(
_open
){
_toggle
();
_toggle
();
}
}
}
}
/// Alterna el estado abierto-cerrado
void
_toggle
(){
void
_toggle
(){
setState
(()
{
setState
(()
{
_open
=
!
_open
;
_open
=
!
_open
;
...
@@ -95,6 +107,7 @@ class ExpandableFabState extends State<ExpandableFab>
...
@@ -95,6 +107,7 @@ class ExpandableFabState extends State<ExpandableFab>
);
);
}
}
/// Construye la X que contrae el FAB
Widget
_buildTapToCloseFab
()
{
Widget
_buildTapToCloseFab
()
{
return
SizedBox
(
return
SizedBox
(
width:
56
,
width:
56
,
...
@@ -118,6 +131,7 @@ class ExpandableFabState extends State<ExpandableFab>
...
@@ -118,6 +131,7 @@ class ExpandableFabState extends State<ExpandableFab>
);
);
}
}
/// Construye el contenedor que expande las opciones
Widget
_buildTapToOpenFab
()
{
Widget
_buildTapToOpenFab
()
{
return
IgnorePointer
(
return
IgnorePointer
(
ignoring:
_open
,
ignoring:
_open
,
...
@@ -140,6 +154,7 @@ class ExpandableFabState extends State<ExpandableFab>
...
@@ -140,6 +154,7 @@ class ExpandableFabState extends State<ExpandableFab>
);
);
}
}
/// Construye el botón del FAB que expande las opciones
Widget
_loadFloatingActionButton
(){
Widget
_loadFloatingActionButton
(){
if
(
widget
.
label
==
null
){
if
(
widget
.
label
==
null
){
return
FloatingActionButton
(
return
FloatingActionButton
(
...
@@ -158,6 +173,7 @@ class ExpandableFabState extends State<ExpandableFab>
...
@@ -158,6 +173,7 @@ class ExpandableFabState extends State<ExpandableFab>
);
);
}
}
/// Construye las opciones del FAB
List
<
Widget
>
_buildExpandingActionButtons
()
{
List
<
Widget
>
_buildExpandingActionButtons
()
{
final
children
=
<
Widget
>[];
final
children
=
<
Widget
>[];
final
count
=
widget
.
children
.
length
;
final
count
=
widget
.
children
.
length
;
...
@@ -178,6 +194,7 @@ class ExpandableFabState extends State<ExpandableFab>
...
@@ -178,6 +194,7 @@ class ExpandableFabState extends State<ExpandableFab>
return
children
;
return
children
;
}
}
/// Obtiene la anchura que debería tener el botón
double
_computeWidth
()
{
double
_computeWidth
()
{
if
(
_open
){
if
(
_open
){
if
(
widget
.
label
!=
null
)
return
170.0
;
if
(
widget
.
label
!=
null
)
return
170.0
;
...
@@ -190,6 +207,7 @@ class ExpandableFabState extends State<ExpandableFab>
...
@@ -190,6 +207,7 @@ class ExpandableFabState extends State<ExpandableFab>
}
}
}
}
/// Clase que se utiliza para construir la animación del FAB abriéndose y cerrándose
class
_ExpandingActionButton
extends
StatelessWidget
{
class
_ExpandingActionButton
extends
StatelessWidget
{
final
bool
invert
;
final
bool
invert
;
final
double
directionInDegrees
;
final
double
directionInDegrees
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment