import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import '../platform.dart'; import '../screen_loading.dart'; import '../types/video.dart'; import '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 RefreshIndicator( onRefresh: () async { loadData(); await Future.delayed(Duration(milliseconds: 600)); }, triggerMode: RefreshIndicatorTriggerMode.anywhere, color: Colors.purple, child: 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 ScreenLoading(); } }, )); } Widget _mainGrid(List data, double width) { return Stack( children: [ Column( children: [ if (widget.headerBuilder != null) widget.headerBuilder!(this), data.length > 0 ? 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; }); }, ); }, ), ) : Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( height: 32, ), Icon(Icons.warning_amber, size: 52), Text("no item available") ], ), ), 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!), ), ), ), ]; } }