import 'dart:convert'; import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; import 'package:manager_api/api.dart'; import 'package:mymuseum_visitapp/Components/Loading.dart'; import 'package:mymuseum_visitapp/Components/SearchBox.dart'; import 'package:mymuseum_visitapp/Components/SearchNumberBox.dart'; import 'package:mymuseum_visitapp/Helpers/DatabaseHelper.dart'; import 'package:mymuseum_visitapp/Helpers/translationHelper.dart'; import 'package:mymuseum_visitapp/Models/visitContext.dart'; import 'package:mymuseum_visitapp/Screens/Article/article.dart'; import 'package:mymuseum_visitapp/Screens/Visit/visit.dart'; import 'package:mymuseum_visitapp/Services/apiService.dart'; import 'package:mymuseum_visitapp/Services/downloadConfiguration.dart'; import 'package:mymuseum_visitapp/app_context.dart'; import 'package:mymuseum_visitapp/constants.dart'; import 'package:provider/provider.dart'; class ConfigurationsList extends StatefulWidget { const ConfigurationsList({Key? key, required this.configurations, required this.alreadyDownloaded, required this.requestRefresh}) : super(key: key); final List configurations; final List alreadyDownloaded; final Function requestRefresh; @override State createState() => _ConfigurationsListState(); } class _ConfigurationsListState extends State { List configurations = []; List alreadyDownloaded = []; VisitAppContext? visitAppContext; @override void initState() { configurations = widget.configurations; alreadyDownloaded = widget.alreadyDownloaded; super.initState(); } @override Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; final appContext = Provider.of(context); visitAppContext = appContext.getContext(); return ListView.builder( shrinkWrap: true, //I've set this as true here depending on what your listview content is //physics: NeverScrollableScrollPhysics(),//This prevents scrolling, but may inhibit refresh indicator, remove as you need itemBuilder: (BuildContext context, int index) { return InkWell( onTap: () async { if(configurations[index].isOffline! && alreadyDownloaded.any((c) => c == configurations[index].id)) { VisitAppContext visitAppContext = appContext.getContext(); if(!configurations[index].languages!.contains(visitAppContext.language)) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(TranslationHelper.getFromLocale("languageNotSupported", appContext)), backgroundColor: kBlue2), ); } else { // Update context visitAppContext.configuration = configurations[index]; visitAppContext.sectionIds = List.from(await DatabaseHelper.instance.queryWithConfigurationId(DatabaseTableType.sections, visitAppContext.configuration!.id!)).map((e) => e.id).toList(); appContext.setContext(visitAppContext); Navigator.of(context).pushReplacement(MaterialPageRoute( builder: (context) => VisitPage(configurationId: configurations[index].id!), )); } } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(TranslationHelper.getFromLocale("visitDownloadWarning", appContext)), backgroundColor: kBlue2), ); } }, child: Container( height: size.height*0.15, decoration: boxDecoration(configurations[index], false), margin: const EdgeInsets.symmetric(vertical: 10, horizontal: 20), child: Stack( children: [ Row( children: [ if(configurations[index].imageId != null) Container( padding: const EdgeInsets.symmetric(horizontal: 0), height: 136, // image is square but we add extra 20 + 20 padding thats why width is 200 width: size.width*0.3, child: FutureBuilder( future: ApiService.getResource(configurations[index].imageId!), builder: (context, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.done) { return snapshot.data != null ? Container( child: ClipRRect( borderRadius: const BorderRadius.only(topLeft: Radius.circular(20), bottomLeft: Radius.circular(20)), child: Image.memory( base64Decode(snapshot.data.data!), fit: BoxFit.cover ), ), ) : const Text(""); } else if (snapshot.connectionState == ConnectionState.none) { return Text(TranslationHelper.getFromLocale("noData", appContext)); } else { return Center( child: SizedBox( height: size.height * 0.15, child: const Loading() ) ); } } ), ), Align( alignment: Alignment.topLeft, child: Container( width: size.width*0.45, child: Padding( padding: const EdgeInsets.only(top: 45, left: 10), child: AutoSizeText( TranslationHelper.get(configurations[index].title, appContext), style: const TextStyle(fontSize: kMenuTitleDetailSize), maxFontSize: 20, maxLines: 2, ), ), ), ), ], ), if(configurations[index].isOffline!) Positioned( bottom: 0, right: 0, child: Container( width: 45, height: 45, decoration: BoxDecoration( shape: BoxShape.rectangle, color: kBlue1, borderRadius: BorderRadius.circular(20.0), ), margin: const EdgeInsets.all(8), child: InkWell( onTap: () async { await downloadClicked(appContext, configurations[index]); widget.requestRefresh(); }, child: configurations[index].isOffline! && !alreadyDownloaded.any((c) => c == configurations[index].id) ? const Icon(Icons.download, color: Colors.white) : const Icon(Icons.refresh, color: Colors.white), ), ) ) ], ), ), ); }, itemCount: configurations.length ); } Future downloadClicked(AppContext appContext, ConfigurationDTO configuration) async { String loadingtext = TranslationHelper.getFromLocale("downloadConfiguration", appContext); showDialog( barrierDismissible: false, context: context, builder: (_) { return Dialog( backgroundColor: Colors.white, child: Padding( padding: const EdgeInsets.symmetric(vertical: 20), child: Column( mainAxisSize: MainAxisSize.min, children: [ const CircularProgressIndicator(), const SizedBox( height: 15, ), Text(loadingtext) ], ), ), ); }); var isFinish = await DownloadConfiguration.downloadClicked(appContext, configuration); print("C4EST FINIITO"); print(isFinish); Navigator.of(context).pop(); } } boxDecoration(ConfigurationDTO configuration, bool isSelected) { return BoxDecoration( color: Colors.white, shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(20.0), border: Border.all( color: kBlue0.withOpacity(0.35), width: 0.2, ), boxShadow: [ BoxShadow( color: kBlue0.withOpacity(0.35), //spreadRadius: 0.15, blurRadius: 27, offset: const Offset(0, 15), // changes position of shadow ), ], ); }