Commit 470c1e15 by Diego Pérez Peña

Página de conversión y página de metadatos actualizadas

parent f1d29c6d
...@@ -30,14 +30,13 @@ class Carpeta extends ElementoSeleccionable{ ...@@ -30,14 +30,13 @@ class Carpeta extends ElementoSeleccionable{
_directory = directory, _formatos = formatos, _directory = directory, _formatos = formatos,
super(nombre: directory.path.split('/').last, icon: const Icon(Icons.folder_outlined)); super(nombre: directory.path.split('/').last, icon: const Icon(Icons.folder_outlined));
Carpeta setFormatoDestino(Formato original, Formato destino){ void setFormatoDestino(Formato original, Formato? destino){
final formatosAlt = formatos.toList(); final formatosAlt = formatos.toList();
for(InfoFormato i in formatosAlt){ for(InfoFormato i in formatosAlt){
if(i.formatoOriginal == original){ if(i.formatoOriginal == original){
i.formatoDestino = destino; i.formatoDestino = destino;
} }
} }
return Carpeta.fromList(id: id, directory: directory, formatos: formatosAlt);
} }
@override @override
...@@ -76,4 +75,10 @@ class InfoFormato { ...@@ -76,4 +75,10 @@ class InfoFormato {
// TODO: <implement> // 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
...@@ -4,6 +4,7 @@ import 'package:uuid/uuid.dart'; ...@@ -4,6 +4,7 @@ import 'package:uuid/uuid.dart';
import 'carpeta.dart'; import 'carpeta.dart';
import 'elemento_seleccionable.dart'; import 'elemento_seleccionable.dart';
import 'archivo.dart'; import 'archivo.dart';
import 'formato.dart';
class ListaSeleccionables extends ChangeNotifier { class ListaSeleccionables extends ChangeNotifier {
final _seleccionables = <ElementoSeleccionable>[]; final _seleccionables = <ElementoSeleccionable>[];
...@@ -27,7 +28,7 @@ class ListaSeleccionables extends ChangeNotifier { ...@@ -27,7 +28,7 @@ class ListaSeleccionables extends ChangeNotifier {
void addCarpeta(Directory directory){ void addCarpeta(Directory directory){
_seleccionables.add(Carpeta(id: const Uuid().v1(), _seleccionables.add(Carpeta(id: const Uuid().v1(),
directory: directory)); directory: directory, formatos: <Formato, bool>{Formato.mp4: false, Formato.mp3: true}));
notifyListeners(); notifyListeners();
} }
} }
\ No newline at end of file
...@@ -5,12 +5,16 @@ import 'package:prueba_multimedia/paginas/paginas.dart'; ...@@ -5,12 +5,16 @@ import 'package:prueba_multimedia/paginas/paginas.dart';
class PaginaConfiguracion extends StatefulWidget { class PaginaConfiguracion extends StatefulWidget {
final ListaSeleccionables _lista;
final int _indice;
final ElementoSeleccionable _elementoAsociado; final ElementoSeleccionable _elementoAsociado;
const PaginaConfiguracion({ const PaginaConfiguracion({
super.key, super.key,
required elementoAsociado required ListaSeleccionables lista,
}): _elementoAsociado = elementoAsociado; required int indice,
required ElementoSeleccionable elemento
}): _lista = lista, _indice = indice, _elementoAsociado = elemento;
@override @override
State<PaginaConfiguracion> createState() => _PaginaConfiguracionState(); State<PaginaConfiguracion> createState() => _PaginaConfiguracionState();
...@@ -37,11 +41,7 @@ class _PaginaConfiguracionState extends State<PaginaConfiguracion> { ...@@ -37,11 +41,7 @@ class _PaginaConfiguracionState extends State<PaginaConfiguracion> {
) )
), ),
), ),
body: Consumer<ListaSeleccionables>( body: _construirCuerpo(widget._lista),
builder: (context, manager, child){
return _construirCuerpo(manager);
},
),
bottomNavigationBar: _construirBarraNavegacion() bottomNavigationBar: _construirBarraNavegacion()
); );
} }
...@@ -67,40 +67,32 @@ class _PaginaConfiguracionState extends State<PaginaConfiguracion> { ...@@ -67,40 +67,32 @@ class _PaginaConfiguracionState extends State<PaginaConfiguracion> {
if(widget._elementoAsociado is Convertible){ if(widget._elementoAsociado is Convertible){
final arch = widget._elementoAsociado as Convertible; final arch = widget._elementoAsociado as Convertible;
if(_categoriaActiva == 0){ if(_categoriaActiva == 0){
return PaginaConversion(lista: manager, formatoOriginal: arch.formatoOriginal); return PaginaConversion.convertible(
lista: manager,
indiceArchivo: widget._indice,
elemento: arch,
formatoOriginal: arch.formatoOriginal
);
} }
else if(_categoriaActiva == 2){ else if(_categoriaActiva == 2 || arch.formatoOriginal.tipoMultimedia != TipoMultimedia.video){
return PaginaMetadatos(formato: arch.formatoOriginal); return PaginaMetadatos(
lista: manager,
archivo: arch,
indiceSeleccionable: widget._indice
);
} }
else{ else{
if(arch.formatoOriginal.tipoMultimedia == TipoMultimedia.video){
return PaginaFotograma(); return PaginaFotograma();
} }
// Página de metadatos
return PaginaMetadatos(formato: arch.formatoOriginal);
}
} }
// Páginas de carpetas y formato de archivo para carpeta // Páginas de carpetas y formato de archivo para carpeta
// TODO: Carpeta de ejemplo, cargar carpetas de verdad // TODO: Carpeta de ejemplo, cargar carpetas de verdad
return PaginaConfiguracionCarpeta(formatosCarpeta: [ return PaginaConfiguracionCarpeta(
InfoFormato(formato: Formato.jpg, lista: manager,
nombreCarpeta: widget._elementoAsociado.nombre, carpeta: widget._elementoAsociado as Carpeta,
subCarpeta: false, indice: widget._indice
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: [])
]);
} }
BottomNavigationBar? _construirBarraNavegacion(){ BottomNavigationBar? _construirBarraNavegacion(){
......
...@@ -3,10 +3,21 @@ import 'package:prueba_multimedia/modelo/modelo.dart'; ...@@ -3,10 +3,21 @@ import 'package:prueba_multimedia/modelo/modelo.dart';
import 'package:prueba_multimedia/paginas/paginas.dart'; import 'package:prueba_multimedia/paginas/paginas.dart';
class PaginaConfiguracionCarpeta extends StatefulWidget { class PaginaConfiguracionCarpeta extends StatefulWidget {
final ListaSeleccionables _lista;
final List<InfoFormato> _formatosCarpeta; final List<InfoFormato> _formatosCarpeta;
final int _indice;
const PaginaConfiguracionCarpeta({super.key, required List<InfoFormato> formatosCarpeta}): final Carpeta _carpeta;
_formatosCarpeta = formatosCarpeta;
PaginaConfiguracionCarpeta({
super.key,
required ListaSeleccionables lista,
required int indice,
required Carpeta carpeta
}):
_lista = lista,
_indice = indice,
_carpeta = carpeta,
_formatosCarpeta = carpeta.formatos;
@override @override
State<PaginaConfiguracionCarpeta> createState() => _PaginaConfiguracionCarpetaState(); State<PaginaConfiguracionCarpeta> createState() => _PaginaConfiguracionCarpetaState();
...@@ -83,6 +94,7 @@ class _PaginaConfiguracionCarpetaState extends State<PaginaConfiguracionCarpeta> ...@@ -83,6 +94,7 @@ class _PaginaConfiguracionCarpetaState extends State<PaginaConfiguracionCarpeta>
onChanged: (bool? value) { onChanged: (bool? value) {
setState(() { setState(() {
_incluirSubcarpetas = value!; _incluirSubcarpetas = value!;
widget._lista.actualizaSeleccionable(widget._indice, widget._carpeta);
}); });
}) })
], ],
...@@ -194,7 +206,11 @@ class _PaginaConfiguracionCarpetaState extends State<PaginaConfiguracionCarpeta> ...@@ -194,7 +206,11 @@ class _PaginaConfiguracionCarpetaState extends State<PaginaConfiguracionCarpeta>
() { () {
Navigator.push(context, Navigator.push(context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
return PaginaConfiguracion(elementoAsociado: i.conversion); return PaginaConfiguracion(
indice: widget._formatosCarpeta.indexOf(i),
elemento: i.conversion,
lista: widget._lista,
);
} }
)); ));
}, },
......
...@@ -4,18 +4,36 @@ import 'package:prueba_multimedia/modelo/modelo.dart'; ...@@ -4,18 +4,36 @@ import 'package:prueba_multimedia/modelo/modelo.dart';
class PaginaConversion extends StatefulWidget { class PaginaConversion extends StatefulWidget {
final ListaSeleccionables _lista; final ListaSeleccionables _lista;
final int _indiceArchivo; final int _indiceArchivo;
final ElementoSeleccionable _seleccionable; final Carpeta? _carpeta;
final InfoFormato? _infoFormato;
final Convertible? _archivo;
final Formato _formatoOriginal; final Formato _formatoOriginal;
const PaginaConversion({ const PaginaConversion.convertible({
super.key, super.key,
required Formato formatoOriginal, required Formato formatoOriginal,
required int indiceArchivo, required int indiceArchivo,
required Convertible seleccionable, required Convertible elemento,
required ListaSeleccionables lista required ListaSeleccionables lista
}): _formatoOriginal = formatoOriginal, }): _formatoOriginal = formatoOriginal,
_indiceArchivo = indiceArchivo, _indiceArchivo = indiceArchivo,
_seleccionable = seleccionable, _archivo = elemento,
_carpeta = null,
_infoFormato = null,
_lista = lista;
const PaginaConversion.carpeta({
super.key,
required Formato formatoOriginal,
required int indiceArchivo,
required Carpeta carpeta,
required InfoFormato infoFormato,
required ListaSeleccionables lista
}): _formatoOriginal = formatoOriginal,
_indiceArchivo = indiceArchivo,
_archivo = null,
_carpeta = carpeta,
_infoFormato = infoFormato,
_lista = lista; _lista = lista;
@override @override
...@@ -24,8 +42,6 @@ class PaginaConversion extends StatefulWidget { ...@@ -24,8 +42,6 @@ class PaginaConversion extends StatefulWidget {
class _PaginaConversionState extends State<PaginaConversion> class _PaginaConversionState extends State<PaginaConversion>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
// Podríamos hacer que en vez de poder haber nulos sea el mismo formato
// que el de origen de manera predeterminada ?
Formato? _formatoConvertido; Formato? _formatoConvertido;
Calidad? _calidadActual = null; Calidad? _calidadActual = null;
...@@ -36,6 +52,12 @@ class _PaginaConversionState extends State<PaginaConversion> ...@@ -36,6 +52,12 @@ class _PaginaConversionState extends State<PaginaConversion>
void initState() { void initState() {
super.initState(); super.initState();
_tabController = TabController(length: 3, vsync: this); _tabController = TabController(length: 3, vsync: this);
if(widget._carpeta != null){
_formatoConvertido = widget._infoFormato!.formatoDestino;
}
else{
_formatoConvertido = widget._archivo!.formatoDestino;
}
} }
@override @override
...@@ -52,11 +74,11 @@ class _PaginaConversionState extends State<PaginaConversion> ...@@ -52,11 +74,11 @@ class _PaginaConversionState extends State<PaginaConversion>
Row( Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
_createOriginalFormatBox(), _createFormatBox(true),
const SizedBox(width: 10.0), const SizedBox(width: 10.0),
Icon(Icons.chevron_right), Icon(Icons.chevron_right),
const SizedBox(width: 10.0), const SizedBox(width: 10.0),
_createConversionFormatBox() _createFormatBox(false)
], ],
), ),
SizedBox(height: 20.0), SizedBox(height: 20.0),
...@@ -69,34 +91,21 @@ class _PaginaConversionState extends State<PaginaConversion> ...@@ -69,34 +91,21 @@ class _PaginaConversionState extends State<PaginaConversion>
); );
} }
Widget _createOriginalFormatBox(){ Widget _createFormatBox(bool original){
final String nombreFormato = widget._formatoOriginal.name.toUpperCase();
return DecoratedBox(
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
),
borderRadius: BorderRadius.circular(15),
color: Colors.black26
),
child: Padding(
padding: const EdgeInsets.all(13.0),
child: Text(
nombreFormato,
style: Theme.of(context).textTheme.titleLarge,
textScaler: TextScaler.linear(1.3)
),
)
);
}
_createConversionFormatBox() {
final String nombreFormato; final String nombreFormato;
final Color fondo;
if(original){
nombreFormato = widget._formatoOriginal.name.toUpperCase();
fondo = Colors.black26;
}
else{
if(_formatoConvertido == null){ if(_formatoConvertido == null){
nombreFormato = ' '; nombreFormato = ' ';
fondo = Colors.white;
} else { } else {
nombreFormato = _formatoConvertido!.name.toUpperCase(); nombreFormato = _formatoConvertido!.name.toUpperCase();
fondo = Theme.of(context).colorScheme.inversePrimary;
}
} }
return DecoratedBox( return DecoratedBox(
...@@ -105,7 +114,7 @@ class _PaginaConversionState extends State<PaginaConversion> ...@@ -105,7 +114,7 @@ class _PaginaConversionState extends State<PaginaConversion>
color: Colors.black, color: Colors.black,
), ),
borderRadius: BorderRadius.circular(15), borderRadius: BorderRadius.circular(15),
color: _formatoConvertido == null ? Colors.white : Theme.of(context).colorScheme.inversePrimary color: fondo
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(13.0), padding: const EdgeInsets.all(13.0),
...@@ -156,7 +165,7 @@ class _PaginaConversionState extends State<PaginaConversion> ...@@ -156,7 +165,7 @@ class _PaginaConversionState extends State<PaginaConversion>
} }
} }
Widget _createDefaultConversionPanel() { Widget _createTabVideos(){
return Material( return Material(
clipBehavior: Clip.antiAlias, clipBehavior: Clip.antiAlias,
shape: BeveledRectangleBorder( shape: BeveledRectangleBorder(
...@@ -179,15 +188,39 @@ class _PaginaConversionState extends State<PaginaConversion> ...@@ -179,15 +188,39 @@ class _PaginaConversionState extends State<PaginaConversion>
children: [ children: [
_createBotonesPerfilFormato(), _createBotonesPerfilFormato(),
SizedBox( SizedBox(
height: MediaQuery.of(context).size.height - 460, height: 68,
child: TabBar(
controller: _tabController,
tabs: <Widget>[
Tab(
icon: TipoMultimedia.video.icono,
text: 'Vídeo',
),
Tab(
icon: TipoMultimedia.audio.icono,
text: 'Audio',
),
Tab(
icon: TipoMultimedia.imagen.icono,
text: 'Imagen',
)
]
),
),
SizedBox(
height: MediaQuery.of(context).size.height - 528,
child: Padding( child: Padding(
padding: const EdgeInsets.only(top: 16.0), padding: const EdgeInsets.only(top: 16.0),
child: GridView.count( child: TabBarView(
crossAxisCount: _showProfiles? 1 : 3, controller: _tabController,
childAspectRatio: _showProfiles ? 6.0 : 1.0, children: TipoMultimedia.values.map((tipo) {
return GridView.count(
crossAxisCount: 3,
crossAxisSpacing: 12, crossAxisSpacing: 12,
mainAxisSpacing: 12, mainAxisSpacing: 12,
children: _showProfiles? _createListPerfiles() : _createGridBotonesConversion() children: _createGridBotonesConversion(tipo: tipo)
);
}).toList()
), ),
), ),
), ),
...@@ -198,7 +231,7 @@ class _PaginaConversionState extends State<PaginaConversion> ...@@ -198,7 +231,7 @@ class _PaginaConversionState extends State<PaginaConversion>
); );
} }
Widget _createTabVideos(){ Widget _createDefaultConversionPanel() {
return Material( return Material(
clipBehavior: Clip.antiAlias, clipBehavior: Clip.antiAlias,
shape: BeveledRectangleBorder( shape: BeveledRectangleBorder(
...@@ -221,39 +254,15 @@ class _PaginaConversionState extends State<PaginaConversion> ...@@ -221,39 +254,15 @@ class _PaginaConversionState extends State<PaginaConversion>
children: [ children: [
_createBotonesPerfilFormato(), _createBotonesPerfilFormato(),
SizedBox( SizedBox(
height: 68, height: MediaQuery.of(context).size.height - 460,
child: TabBar(
controller: _tabController,
tabs: <Widget>[
Tab(
icon: TipoMultimedia.video.icono,
text: 'Vídeo',
),
Tab(
icon: TipoMultimedia.audio.icono,
text: 'Audio',
),
Tab(
icon: TipoMultimedia.imagen.icono,
text: 'Imagen',
)
]
),
),
SizedBox(
height: MediaQuery.of(context).size.height - 528,
child: Padding( child: Padding(
padding: const EdgeInsets.only(top: 16.0), padding: const EdgeInsets.only(top: 16.0),
child: TabBarView( child: GridView.count(
controller: _tabController, crossAxisCount: _showProfiles? 1 : 3,
children: TipoMultimedia.values.map((tipo) { childAspectRatio: _showProfiles ? 6.0 : 1.0,
return GridView.count(
crossAxisCount: 3,
crossAxisSpacing: 12, crossAxisSpacing: 12,
mainAxisSpacing: 12, mainAxisSpacing: 12,
children: _createGridBotonesConversion(tipo: tipo) children: _showProfiles? _createListPerfiles() : _createGridBotonesConversion()
);
}).toList()
), ),
), ),
), ),
...@@ -326,7 +335,6 @@ class _PaginaConversionState extends State<PaginaConversion> ...@@ -326,7 +335,6 @@ class _PaginaConversionState extends State<PaginaConversion>
formatoPerfil = perfil.extensionMusica; formatoPerfil = perfil.extensionMusica;
} }
if(formatoPerfil != null){ if(formatoPerfil != null){
Color color = Theme.of(context).cardColor; Color color = Theme.of(context).cardColor;
if(formatoPerfil == widget._formatoOriginal){ if(formatoPerfil == widget._formatoOriginal){
...@@ -348,11 +356,8 @@ class _PaginaConversionState extends State<PaginaConversion> ...@@ -348,11 +356,8 @@ class _PaginaConversionState extends State<PaginaConversion>
), ),
); );
} : () { } : () {
if (_formatoConvertido != formatoPerfil) { if (_formatoConvertido != formatoPerfil && _calidadActual != perfil.calidad) {
setState(() { _cambiarFormatoCalidad(formatoPerfil!, perfil.calidad);
_formatoConvertido = formatoPerfil;
_calidadActual = perfil.calidad;
});
} }
}, },
child: Container( child: Container(
...@@ -395,27 +400,10 @@ class _PaginaConversionState extends State<PaginaConversion> ...@@ -395,27 +400,10 @@ class _PaginaConversionState extends State<PaginaConversion>
borderRadius: BorderRadius.circular(20.0), borderRadius: BorderRadius.circular(20.0),
onTap: _formatoConvertido == elemento ? () { onTap: _formatoConvertido == elemento ? () {
setState(() { setState(() {
_formatoConvertido = null; _formatoConvertido = _calidadActual = null;
_calidadActual = null; _cambiarFormatoCalidad(null, null);
}); });
} : () { setState((){ } : () => _cambiarFormatoCalidad(elemento, Calidad.media),
_formatoConvertido = elemento;
// TODO: Cambiar calidad del archivo
ElementoSeleccionable resultado;
if(widget._seleccionable is Carpeta){
final formatos = (widget._seleccionable as Carpeta).formatos;
for(InfoFormato f in formatos){
if(f.formatoOriginal == widget._formatoOriginal){
}
}
}
else{
}
widget._lista.actualizaSeleccionable(widget._indiceArchivo, resultado);
}); },
onLongPress: () { onLongPress: () {
showDialog<void>( showDialog<void>(
context: context, context: context,
...@@ -460,4 +448,25 @@ class _PaginaConversionState extends State<PaginaConversion> ...@@ -460,4 +448,25 @@ class _PaginaConversionState extends State<PaginaConversion>
); );
}).toList(); }).toList();
} }
void _cambiarFormatoCalidad(Formato? destino, Calidad? calidad){
setState((){
_formatoConvertido = destino;
_calidadActual = calidad;
ElementoSeleccionable resultado;
if(widget._carpeta != null){
widget._carpeta!.setFormatoDestino(widget._formatoOriginal, _formatoConvertido);
resultado = widget._carpeta!;
}
else{
widget._archivo!.formatoDestino = _formatoConvertido;
resultado = widget._archivo!;
}
// TODO: ACTUALIZAR CALIDAD
widget._lista.actualizaSeleccionable(widget._indiceArchivo, resultado);
});
}
} }
\ No newline at end of file
...@@ -2,9 +2,27 @@ import 'package:flutter/material.dart'; ...@@ -2,9 +2,27 @@ import 'package:flutter/material.dart';
import 'package:prueba_multimedia/modelo/modelo.dart'; import 'package:prueba_multimedia/modelo/modelo.dart';
class PaginaMetadatos extends StatefulWidget { class PaginaMetadatos extends StatefulWidget {
final Formato _formato; final ListaSeleccionables _lista;
late final Formato _formato;
const PaginaMetadatos({super.key, required formato}): _formato = formato; final Convertible _archivo;
final int _indiceArchivo;
PaginaMetadatos({
super.key,
required ListaSeleccionables lista,
required Convertible archivo,
required int indiceSeleccionable
}):
_archivo = archivo,
_indiceArchivo = indiceSeleccionable,
_lista = lista {
if(_archivo.formatoDestino == null){
_formato = _archivo.formatoOriginal;
}
else{
_formato = _archivo.formatoDestino!;
}
}
@override @override
State<PaginaMetadatos> createState() => _PaginaMetadatosState(); State<PaginaMetadatos> createState() => _PaginaMetadatosState();
......
...@@ -19,7 +19,7 @@ class PaginaPrincipalLlena extends StatelessWidget { ...@@ -19,7 +19,7 @@ class PaginaPrincipalLlena extends StatelessWidget {
return const SizedBox(height: 8.0); return const SizedBox(height: 8.0);
}, },
itemBuilder: (context, index) { itemBuilder: (context, index) {
return SeleccionableWidget(seleccionable: seleccionables[index]); return SeleccionableWidget(indice: index, seleccionable: seleccionables[index], lista: listaSeleccionables);
}, },
), ),
); );
......
...@@ -3,9 +3,11 @@ import 'package:prueba_multimedia/paginas/paginas.dart'; ...@@ -3,9 +3,11 @@ import 'package:prueba_multimedia/paginas/paginas.dart';
import 'package:prueba_multimedia/modelo/modelo.dart'; import 'package:prueba_multimedia/modelo/modelo.dart';
class SeleccionableWidget extends StatelessWidget { class SeleccionableWidget extends StatelessWidget {
final int indice;
final ElementoSeleccionable seleccionable; 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 // TODO: ACTUALIZAR PARA MOSTRAR FORMATOS Y CAMBIOS
@override @override
...@@ -32,7 +34,7 @@ class SeleccionableWidget extends StatelessWidget { ...@@ -32,7 +34,7 @@ class SeleccionableWidget extends StatelessWidget {
onPressed: () { onPressed: () {
Navigator.push(context, Navigator.push(context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
return PaginaConfiguracion(elementoAsociado: seleccionable); return PaginaConfiguracion(indice: indice, elemento: seleccionable, lista: lista);
})); }));
}, },
) )
......
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