import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:openmediacentermobile/platform.dart'; import 'package:openmediacentermobile/preview_tile.dart'; class PreviewGrid extends StatefulWidget { const PreviewGrid( {Key? key, required this.videoLoader, this.headerBuilder, this.footerBuilder}) : super(key: key); final Future> Function() videoLoader; final Widget Function(_PreviewGridState state)? footerBuilder; final Widget Function(_PreviewGridState state)? headerBuilder; @override State createState() => _PreviewGridState(); } class _PreviewGridState extends State { late Future> _data; Image? _previewImage; @override void initState() { super.initState(); loadData(); } void loadData() { setState(() { _data = widget.videoLoader(); }); } @override Widget build(BuildContext context) { final double width = MediaQuery.of(context).size.width; return FutureBuilder>( future: _data, builder: (BuildContext context, AsyncSnapshot> snapshot) { if (snapshot.hasError) { return Text("Error"); } else if (snapshot.hasData) { return _mainGrid(snapshot.data!, width); } else { return _pageLoading(); } }, ); } Widget _pageLoading() { return Column(children: const [ SizedBox( width: 60, height: 60, child: CircularProgressIndicator(), ), Padding( padding: EdgeInsets.only(top: 16), child: Text('Awaiting result...'), ) ]); } Widget _mainGrid(List data, double width) { return Stack( children: [ Column( children: [ if (widget.headerBuilder != null) widget.headerBuilder!(this), Expanded( child: MasonryGridView.count( // every tile should be at max 330 pixels long... crossAxisCount: isTV() ? width ~/ 200 : width ~/ 275, // crossAxisCount: isTV() ? width ~/ 200 : width ~/ 330, itemCount: data.length, mainAxisSpacing: 4, crossAxisSpacing: 4, padding: EdgeInsets.all(5), itemBuilder: (context, index) { return PreviewTile( dta: data[index], onLongPress: (img) { setState(() { _previewImage = img; }); }, onLongPressEnd: () { setState(() { _previewImage = null; }); }, ); }, ), ), if (widget.footerBuilder != null) widget.footerBuilder!(this), ], ), if (_previewImage != null) ..._buildPreviewImage(), ], ); } List _buildPreviewImage() { return [ BackdropFilter( filter: ImageFilter.blur( sigmaX: 5.0, sigmaY: 5.0, ), child: Container( color: Colors.white.withOpacity(0.6), ), ), Container( child: Center( child: Padding( padding: EdgeInsets.symmetric(horizontal: 50), child: ClipRRect( borderRadius: BorderRadius.circular(10.0), child: _previewImage!), ), ), ), ]; } }