use previewgrid also on shufflescreen

This commit is contained in:
lukas-heiligenbrunner 2022-08-25 22:20:25 +02:00
parent e0f75f8736
commit 404d1d7cf7
4 changed files with 67 additions and 86 deletions

View File

@ -1,5 +1,5 @@
buildscript { buildscript {
ext.kotlin_version = '1.4.32' ext.kotlin_version = '1.6.0'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()

View File

@ -6,9 +6,11 @@ import 'package:openmediacentermobile/platform.dart';
import 'package:openmediacentermobile/preview_tile.dart'; import 'package:openmediacentermobile/preview_tile.dart';
class PreviewGrid extends StatefulWidget { class PreviewGrid extends StatefulWidget {
const PreviewGrid({Key? key, required this.videoLoader}) : super(key: key); const PreviewGrid({Key? key, required this.videoLoader, this.headerBuilder, this.footerBuilder}) : super(key: key);
final Future<List<VideoT>> Function() videoLoader; final Future<List<VideoT>> Function() videoLoader;
final Widget Function(_PreviewGridState state)? footerBuilder;
final Widget Function(_PreviewGridState state)? headerBuilder;
@override @override
State<PreviewGrid> createState() => _PreviewGridState(); State<PreviewGrid> createState() => _PreviewGridState();
@ -21,7 +23,13 @@ class _PreviewGridState extends State<PreviewGrid> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_data = widget.videoLoader(); loadData();
}
void loadData() {
setState(() {
_data = widget.videoLoader();
});
} }
@override @override
@ -36,29 +44,37 @@ class _PreviewGridState extends State<PreviewGrid> {
} else if (snapshot.hasData) { } else if (snapshot.hasData) {
return Stack( return Stack(
children: [ children: [
MasonryGridView.count( Column(
// every tile should be at max 330 pixels long... children: [
crossAxisCount: isTV() ? width ~/ 200 : width ~/ 275, if (widget.headerBuilder != null) widget.headerBuilder!(this),
// crossAxisCount: isTV() ? width ~/ 200 : width ~/ 330, Expanded(
child: MasonryGridView.count(
mainAxisSpacing: 4, // every tile should be at max 330 pixels long...
crossAxisSpacing: 4, crossAxisCount: isTV() ? width ~/ 200 : width ~/ 275,
padding: EdgeInsets.all(5), // crossAxisCount: isTV() ? width ~/ 200 : width ~/ 330,
itemBuilder: (context, index) { itemCount: snapshot.data!.length,
return PreviewTile( mainAxisSpacing: 4,
dta: snapshot.data![index], crossAxisSpacing: 4,
onLongPress: (img) { padding: EdgeInsets.all(5),
setState(() { itemBuilder: (context, index) {
_previewImage = img; return PreviewTile(
}); dta: snapshot.data![index],
}, onLongPress: (img) {
onLongPressEnd: () { setState(() {
setState(() { _previewImage = img;
_previewImage = null; });
}); },
}, onLongPressEnd: () {
); setState(() {
}, _previewImage = null;
});
},
);
},
),
),
if (widget.footerBuilder != null) widget.footerBuilder!(this),
],
), ),
if (_previewImage != null) ...[ if (_previewImage != null) ...[
BackdropFilter( BackdropFilter(
@ -72,7 +88,9 @@ class _PreviewGridState extends State<PreviewGrid> {
), ),
Container( Container(
child: Center( child: Center(
child: Padding(padding: EdgeInsets.symmetric(horizontal: 50),child: ClipRRect(borderRadius: BorderRadius.circular(10.0), child: _previewImage!)), child: Padding(
padding: EdgeInsets.symmetric(horizontal: 50),
child: ClipRRect(borderRadius: BorderRadius.circular(10.0), child: _previewImage!)),
), ),
), ),
], ],

View File

@ -91,7 +91,7 @@ class _PreviewTileState extends State<PreviewTile> {
snapshot.data! snapshot.data!
], ],
), ),
color: Color(0xFF6CE56F), color: Color(0x6a94a6ff),
), ),
Positioned.fill( Positioned.fill(
child: Material( child: Material(

View File

@ -2,7 +2,7 @@ import 'dart:convert';
import 'dart:math'; import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:openmediacentermobile/preview_grid.dart';
import 'preview_tile.dart'; import 'preview_tile.dart';
import 'api/api.dart'; import 'api/api.dart';
@ -16,8 +16,6 @@ class ShuffleScreen extends StatefulWidget {
} }
class _ShuffleScreenState extends State<ShuffleScreen> { class _ShuffleScreenState extends State<ShuffleScreen> {
late Future<List<VideoT>> _data;
Future<List<VideoT>> loadData(int nr) async { Future<List<VideoT>> loadData(int nr) async {
final data = await API.query("video", "getRandomMovies", {'Number': nr, 'Seed': Random().nextInt(0x7fffffff)}); final data = await API.query("video", "getRandomMovies", {'Number': nr, 'Seed': Random().nextInt(0x7fffffff)});
@ -28,65 +26,30 @@ class _ShuffleScreenState extends State<ShuffleScreen> {
return dta; return dta;
} }
@override
void initState() {
super.initState();
_data = Future.delayed(Duration.zero).then((_) {
double width = MediaQuery.of(context).size.width;
return loadData((isTV() ? width ~/ 200 : width ~/ 330) * 2);
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width; double width = MediaQuery.of(context).size.width;
return FutureBuilder<List<VideoT>>( return PreviewGrid(
future: _data, // a previously-obtained Future<String> or null videoLoader: () {
builder: (BuildContext context, AsyncSnapshot<List<VideoT>> snapshot) { return loadData((isTV() ? width ~/ 200 : width ~/ 330) * 2);
if (snapshot.hasError) {
return Text("Error");
} else if (snapshot.hasData) {
return Column(children: [
MasonryGridView.count(
shrinkWrap: true,
// every tile should be at max 330 pixels long...
crossAxisCount: isTV() ? width ~/ 200 : width ~/ 330,
mainAxisSpacing: 4,
crossAxisSpacing: 4,
padding: EdgeInsets.all(5),
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
return PreviewTile(dta: snapshot.data![index]);
},
),
const SizedBox(
height: 25,
),
TextButton.icon(
onPressed: () {
setState(() {
_data = loadData((isTV() ? width ~/ 200 : width ~/ 330) * 2);
});
},
icon: const Icon(Icons.update),
label: const Text("Shuffle"))
]);
} else {
return Column(children: const <Widget>[
SizedBox(
width: 60,
height: 60,
child: CircularProgressIndicator(),
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Awaiting result...'),
)
]);
}
}, },
footerBuilder: (state) => Column(
children: [
const SizedBox(
height: 25,
),
TextButton.icon(
onPressed: () {
state.loadData();
},
icon: const Icon(Icons.update),
label: const Text("Shuffle"),
),
const SizedBox(
height: 25,
),
],
),
); );
} }
} }