Commit 54232159 by Rafa Castillo Passols

Merge de actualizacionLista

parents a1d6afbf 38e38526
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';
import 'archivo.dart';
import 'convertible.dart';
import 'elemento_seleccionable.dart';
......@@ -7,41 +8,85 @@ import 'formato.dart';
class Carpeta extends ElementoSeleccionable{
final Directory _directory;
final bool _incluirSubcarpetas = false;
final List<InfoFormato> _formatos;
bool _incluirSubcarpetas = false;
bool _open = false;
late final List<InfoFormato> _formatos;
Directory get directory => _directory;
List<InfoFormato> get formatos => List.unmodifiable(_formatos);
bool get isOpen => _open;
bool get incluyeSubcarpetas => _incluirSubcarpetas;
Carpeta({required super.id, required Directory directory}):
_directory = directory, _formatos = [],
_directory = directory,
super(nombre: directory.path.split('/').last, icon: const Icon(Icons.folder_outlined))
{
_formatos = [];
final archivos = directory.listSync(recursive: true, followLinks: false);
for(var a in archivos) {
Formato? f = Formato.fromExtension(a.path.split(".").last);
if(f != null){
_formatos.add(InfoFormato(
formato: f,
nombreCarpeta: directory.path.split('/').last,
subCarpeta: false));
}
}
}
Carpeta.fromList({required super.id, required Directory directory, required List<InfoFormato> formatos}):
_directory = directory, _formatos = formatos,
super(nombre: directory.path.split('/').last, icon: const Icon(Icons.folder_outlined));
InfoFormato? getInfoFormato({required Formato formato}){
for(InfoFormato i in _formatos){
if(i.formatoOriginal == formato){
return i;
}
}
return null;
}
void setFormatoDestino(Formato original, Formato? destino){
final formatosAlt = formatos.toList();
for(InfoFormato i in formatosAlt){
if(i.formatoOriginal == original){
i.formatoDestino = destino;
}
}
}
void pressOpenClose(){
_open = !_open;
}
void pressIncluirSubcarpetas(){
_incluirSubcarpetas = !_incluirSubcarpetas;
}
void pressAltSeleccionado(int index){
_formatos[index].seleccionado = !_formatos[index].seleccionado;
}
}
class InfoFormato {
final bool _subcarpeta;
bool _seleccionado;
bool seleccionado;
final Convertible _conversion;
final List<File> _archivos;
bool get subcarpeta => _subcarpeta;
bool get seleccionado => _seleccionado;
Convertible get conversion => _conversion;
Formato get formatoOriginal => _conversion.formatoOriginal;
Formato? get formatoDestino => _conversion.formatoDestino;
List<Archivo> get archivos => List.unmodifiable(_archivos);
set seleccionado(bool value) => _seleccionado = value;
set formato(Formato? destino) => _conversion.formatoDestino = destino;
set formatoDestino(Formato? destino) => _conversion.formatoDestino = destino;
InfoFormato({required Formato formato,
required String nombreCarpeta,
required bool subCarpeta,
bool? seleccionado,
required List<File> archivos}):
_subcarpeta = subCarpeta, _seleccionado = seleccionado ?? !subCarpeta, _archivos = archivos,
_conversion = Convertible(id: "null", nombre: '$nombreCarpeta > ${formato.name}',
bool? seleccionado}):
_subcarpeta = subCarpeta, seleccionado = seleccionado ?? !subCarpeta,
_conversion = Convertible(id: const Uuid().v1(), nombre: '$nombreCarpeta > ${formato.name}',
icon: Icon(Icons.find_in_page_outlined), formatoOriginal: formato);
void convertir(){
......@@ -49,4 +94,10 @@ class InfoFormato {
// TODO: <implement>
}
}
@override
bool operator ==(Object other) {
if(other is InfoFormato) return this.formatoOriginal == other.formatoOriginal;
return super == other;
}
}
\ No newline at end of file
......@@ -88,12 +88,13 @@ enum Formato {
}
enum TipoMultimedia {
video(Icon(Icons.movie_creation_outlined)),
audio(Icon(Icons.music_note_outlined)),
imagen(Icon(Icons.image_outlined));
video("Vídeo", Icon(Icons.movie_creation_outlined)),
audio("Audio", Icon(Icons.music_note_outlined)),
imagen("Imagen", Icon(Icons.image_outlined));
final String nombre;
final Icon icono;
const TipoMultimedia(this.icono);
const TipoMultimedia(this.nombre, this.icono);
}
enum Clasificacion {
......
......@@ -4,6 +4,7 @@ import 'package:uuid/uuid.dart';
import 'carpeta.dart';
import 'elemento_seleccionable.dart';
import 'archivo.dart';
import 'formato.dart';
class ListaSeleccionables extends ChangeNotifier {
final _seleccionables = <ElementoSeleccionable>[];
......@@ -14,15 +15,33 @@ class ListaSeleccionables extends ChangeNotifier {
notifyListeners();
}
void actualizaSeleccionable(int indice, ElementoSeleccionable elemento){
_seleccionables[indice] = elemento;
notifyListeners();
}
void addArchivo(File file) {
_seleccionables.add(Archivo(id: "Archivo",
_seleccionables.add(Archivo(id: const Uuid().v1(),
file: file));
notifyListeners();
}
void addCarpeta(Directory directory){
_seleccionables.add(Carpeta(id: const Uuid().v1(),
directory: directory));
final newCarpeta = Carpeta(
id: const Uuid().v1(),
directory: directory
);
if(newCarpeta.formatos.isNotEmpty){
_seleccionables.add(Carpeta(
id: const Uuid().v1(),
directory: directory
));
notifyListeners();
}
}
void reinsertar(int index, ElementoSeleccionable element){
_seleccionables.insert(index, element);
notifyListeners();
}
}
\ No newline at end of file
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:prueba_multimedia/modelo/modelo.dart';
import 'package:prueba_multimedia/paginas/paginas.dart';
class PaginaConfiguracion extends StatefulWidget {
final ListaSeleccionables _lista;
final int _indice;
final ElementoSeleccionable _elementoAsociado;
final Carpeta? _carpeta;
const PaginaConfiguracion({
super.key,
required elementoAsociado
}): _elementoAsociado = elementoAsociado;
required ListaSeleccionables lista,
required int indice,
required ElementoSeleccionable elemento,
Carpeta? carpeta
}): _lista = lista, _indice = indice, _elementoAsociado = elemento,
_carpeta = carpeta;
@override
State<PaginaConfiguracion> createState() => _PaginaConfiguracionState();
......@@ -23,10 +31,12 @@ class _PaginaConfiguracionState extends State<PaginaConfiguracion> {
return Scaffold(
appBar: AppBar(
title: RichText(
maxLines: 1,
overflow: TextOverflow.ellipsis,
text: TextSpan(
children: [
WidgetSpan(
child: Icon(_getIcon())
child: _getIcon()
),
TextSpan(
text: _getShownName(),
......@@ -36,19 +46,22 @@ class _PaginaConfiguracionState extends State<PaginaConfiguracion> {
)
),
),
body: _construirCuerpo(),
body: _construirCuerpo(widget._lista),
bottomNavigationBar: _construirBarraNavegacion()
);
}
IconData _getIcon(){
Icon _getIcon(){
if(widget._elementoAsociado is Carpeta){
return Icons.folder;
return Icon(Icons.folder);
}
if(widget._elementoAsociado is Enlace){
return Icons.link;
return Icon(Icons.link);
}
return Icons.insert_drive_file;
if(widget._elementoAsociado is Convertible){
return (widget._elementoAsociado as Convertible).formatoOriginal.tipoMultimedia.icono;
}
return Icon(Icons.insert_drive_file);
}
String _getShownName() {
......@@ -58,44 +71,51 @@ class _PaginaConfiguracionState extends State<PaginaConfiguracion> {
return sb.toString();
}
Widget _construirCuerpo() {
if(widget._elementoAsociado is Convertible){
final arch = widget._elementoAsociado as Convertible;
Widget _construirCuerpo(ListaSeleccionables manager) {
if(widget._elementoAsociado is Archivo){
final arch = widget._elementoAsociado as Archivo;
if(_categoriaActiva == 0){
return PaginaConversion(formatoOriginal: arch.formatoOriginal);
if(widget._carpeta != null){
return PaginaConversion.carpeta(
lista: manager,
indiceArchivo: widget._indice,
carpeta: widget._carpeta!,
infoFormato: widget._carpeta!.getInfoFormato(formato: arch.formatoOriginal)!,
formatoOriginal: arch.formatoOriginal
);
}
return PaginaConversion.convertible(
lista: manager,
indiceArchivo: widget._indice,
elemento: arch,
formatoOriginal: arch.formatoOriginal
);
}
else if(_categoriaActiva == 2){
return PaginaMetadatos(formato: arch.formatoOriginal);
else if(_categoriaActiva == 2 || arch.formatoOriginal.tipoMultimedia != TipoMultimedia.video){
return FutureBuilder(
future: arch.metadatos,
builder: (context, snapshot) {
return snapshot.hasData
? PaginaMetadatos(
metadatos: snapshot.data!,
formato: arch.formatoOriginal
)
: CircularProgressIndicator();
}
);
}
else{
if(arch.formatoOriginal.tipoMultimedia == TipoMultimedia.video){
return PaginaFotograma();
}
// Página de metadatos
return PaginaMetadatos(formato: arch.formatoOriginal);
return PaginaFotograma();
}
}
// Páginas de carpetas y formato de archivo para carpeta
// TODO: Carpeta de ejemplo, cargar carpetas de verdad
return PaginaConfiguracionCarpeta(formatosCarpeta: [
InfoFormato(formato: Formato.jpg,
nombreCarpeta: widget._elementoAsociado.nombre,
subCarpeta: false,
archivos: []),
InfoFormato(formato: Formato.mp4,
nombreCarpeta: widget._elementoAsociado.nombre,
subCarpeta: false,
archivos: []),
InfoFormato(formato: Formato.tif,
nombreCarpeta: widget._elementoAsociado.nombre,
subCarpeta: true,
archivos: []),
InfoFormato(formato: Formato.png,
nombreCarpeta: widget._elementoAsociado.nombre,
subCarpeta: true,
archivos: [])
]);
return PaginaConfiguracionCarpeta(
lista: manager,
carpeta: widget._elementoAsociado as Carpeta,
indice: widget._indice
);
}
BottomNavigationBar? _construirBarraNavegacion(){
......
......@@ -3,10 +3,21 @@ import 'package:prueba_multimedia/modelo/modelo.dart';
import 'package:prueba_multimedia/paginas/paginas.dart';
class PaginaConfiguracionCarpeta extends StatefulWidget {
final ListaSeleccionables _lista;
final List<InfoFormato> _formatosCarpeta;
const PaginaConfiguracionCarpeta({super.key, required List<InfoFormato> formatosCarpeta}):
_formatosCarpeta = formatosCarpeta;
final int _indice;
final Carpeta _carpeta;
PaginaConfiguracionCarpeta({
super.key,
required ListaSeleccionables lista,
required int indice,
required Carpeta carpeta
}):
_lista = lista,
_indice = indice,
_carpeta = carpeta,
_formatosCarpeta = carpeta.formatos;
@override
State<PaginaConfiguracionCarpeta> createState() => _PaginaConfiguracionCarpetaState();
......@@ -21,7 +32,7 @@ class _PaginaConfiguracionCarpetaState extends State<PaginaConfiguracionCarpeta>
@override
void initState() {
super.initState();
_incluirSubcarpetas = false;
_incluirSubcarpetas = widget._carpeta.incluyeSubcarpetas;
for(TipoMultimedia t in TipoMultimedia.values){
_formatos[t] = [];
......@@ -83,6 +94,8 @@ class _PaginaConfiguracionCarpetaState extends State<PaginaConfiguracionCarpeta>
onChanged: (bool? value) {
setState(() {
_incluirSubcarpetas = value!;
widget._carpeta.pressIncluirSubcarpetas();
widget._lista.actualizaSeleccionable(widget._indice, widget._carpeta);
});
})
],
......@@ -136,8 +149,10 @@ class _PaginaConfiguracionCarpetaState extends State<PaginaConfiguracionCarpeta>
for(InfoFormato i in widget._formatosCarpeta){
if(_formatos[t]!.contains(i.formatoOriginal) && !(!_incluirSubcarpetas && i.subcarpeta)){
_seleccionados[i.formatoOriginal] = _allOfType[t]!;
widget._carpeta.pressAltSeleccionado(widget._carpeta.formatos.indexOf(i));
}
}
widget._lista.actualizaSeleccionable(widget._indice, widget._carpeta);
});
})
],
......@@ -186,6 +201,8 @@ class _PaginaConfiguracionCarpetaState extends State<PaginaConfiguracionCarpeta>
_seleccionados[i.formatoOriginal] = value!;
_allOfType[i.formatoOriginal.tipoMultimedia] =
_actualizarCheckboxTipo(i.formatoOriginal.tipoMultimedia);
widget._carpeta.pressAltSeleccionado(widget._carpeta.formatos.indexOf(i));
widget._lista.actualizaSeleccionable(widget._indice, widget._carpeta);
});
}),
IconButton(
......@@ -194,7 +211,12 @@ class _PaginaConfiguracionCarpetaState extends State<PaginaConfiguracionCarpeta>
() {
Navigator.push(context,
MaterialPageRoute(builder: (context) {
return PaginaConfiguracion(elementoAsociado: i.conversion);
return PaginaConfiguracion(
indice: widget._indice,
elemento: i.conversion,
lista: widget._lista,
carpeta: widget._carpeta
);
}
));
},
......
import 'package:flutter/material.dart';
import 'package:prueba_multimedia/modelo/modelo.dart';
import 'package:prueba_multimedia/widgets/carpeta_widget.dart';
import 'package:prueba_multimedia/widgets/widgets.dart';
class PaginaPrincipalLlena extends StatelessWidget {
......@@ -19,7 +20,48 @@ class PaginaPrincipalLlena extends StatelessWidget {
return const SizedBox(height: 8.0);
},
itemBuilder: (context, index) {
return SeleccionableWidget(seleccionable: seleccionables[index]);
return Dismissible(
key: Key(seleccionables[index].id),
background: Container(
color: Colors.red,
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Icon(Icons.delete,
color: Colors.white,
size: 31.0
),
),
),
secondaryBackground: Container(
color: Colors.red,
alignment: Alignment.centerRight,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Icon(Icons.delete,
color: Colors.white,
size: 31.0
),
),
),
onDismissed: (direction) {
listaSeleccionables.borraSeleccionable(index);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('${seleccionables[index].nombre} borrado'),
action: SnackBarAction(
label: 'Deshacer',
onPressed: () {
listaSeleccionables.reinsertar(index, seleccionables[index]);
}
),
)
);
},
child: (seleccionables[index] is Carpeta)?
CarpetaWidget(indice: index, carpeta: seleccionables[index] as Carpeta, lista: listaSeleccionables)
: SeleccionableWidget(indice: index, seleccionable: seleccionables[index], lista: listaSeleccionables)
);
},
),
);
......
......@@ -3,40 +3,75 @@ import 'package:prueba_multimedia/paginas/paginas.dart';
import 'package:prueba_multimedia/modelo/modelo.dart';
class SeleccionableWidget extends StatelessWidget {
final int indice;
final ElementoSeleccionable seleccionable;
final ListaSeleccionables lista;
const SeleccionableWidget({super.key, required this.seleccionable});
const SeleccionableWidget({super.key, required this.indice, required this.seleccionable, required this.lista});
// TODO: ACTUALIZAR PARA MOSTRAR FORMATOS Y CAMBIOS
@override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
seleccionable.icono,
const SizedBox(width: 10,),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
seleccionable.nombre,
style: Theme.of(context).textTheme.bodyLarge
),
],
final String nombre = seleccionable.nombre;
int index = nombre.lastIndexOf('.');
final String visible;
if(index > -1){
visible = nombre.substring(0, index);
}
else {
visible = nombre;
}
Widget? formatoOrig;
if(seleccionable is Convertible){
Convertible arch = (seleccionable as Convertible);
String texto = arch.formatoOriginal.name.toUpperCase();
if(arch.formatoDestino != null) texto += " > ${arch.formatoDestino!.name.toUpperCase()}";
formatoOrig = Flexible(flex:1, child: Text(texto));
}
return SizedBox(
height: 60,
width: MediaQuery.of(context).size.width,
child: Row(
children: <Widget>[
Flexible(flex: 1, child: seleccionable.icono),
Flexible(flex: 1, child: const SizedBox(width: 15)),
Flexible(
flex: 16,
child: SizedBox.expand(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flexible(
flex: 1,
child: Text(
visible,
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.bold
)
),
),
if(formatoOrig != null) formatoOrig
],
)
),
),
Flexible(
flex: 2,
child: IconButton(
icon: const Icon(Icons.edit),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) {
return PaginaConfiguracion(indice: indice, elemento: seleccionable, lista: lista);
}));
},
),
)
),
if (seleccionable is Carpeta)
IconButton(onPressed: () {}, icon: Icon(Icons.menu)),
IconButton(
icon: const Icon(Icons.edit),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) {
return PaginaConfiguracion(elementoAsociado: seleccionable);
}));
},
)
],
]
)
);
}
}
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