lukas-heiligenbrunner
bf070ff99a
update dependencies try to infer the prefix of the server url display display size dependent amount on shuffle page
142 lines
4.1 KiB
Dart
142 lines
4.1 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:openmediacentermobile/videoscreen_desktop.dart'
|
|
if (dart.library.html) 'package:openmediacentermobile/videoscreen_web.dart'
|
|
if (dart.library.io) 'package:openmediacentermobile/videoscreen_desktop.dart';
|
|
|
|
import 'api/api.dart';
|
|
import 'platform.dart';
|
|
|
|
// todo put this type in sperate class!
|
|
class VideoT {
|
|
int id;
|
|
String title;
|
|
double ratio;
|
|
|
|
VideoT(this.title, this.id, this.ratio);
|
|
|
|
factory VideoT.fromJson(dynamic json) {
|
|
return VideoT(json['MovieName'] as String, json['MovieId'] as int, (json['Ratio'] as num).toDouble());
|
|
}
|
|
}
|
|
|
|
class PreviewTile extends StatefulWidget {
|
|
const PreviewTile({Key? key, required this.dta, this.onLongPress, this.onLongPressEnd}) : super(key: key);
|
|
final VideoT dta;
|
|
final Function(Image img)? onLongPress;
|
|
final Function? onLongPressEnd;
|
|
|
|
@override
|
|
_PreviewTileState createState() => _PreviewTileState();
|
|
}
|
|
|
|
class _PreviewTileState extends State<PreviewTile> {
|
|
late Future<Image> _preview;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
|
|
_preview = loadData();
|
|
}
|
|
|
|
@override
|
|
void didUpdateWidget(PreviewTile oldWidget) {
|
|
super.didUpdateWidget(oldWidget);
|
|
|
|
if (oldWidget.dta != widget.dta) {
|
|
setState(() {
|
|
_preview = loadData();
|
|
});
|
|
}
|
|
}
|
|
|
|
Future<Image> loadData() async {
|
|
final data = await API.query("video", "readThumbnail", {'Movieid': widget.dta.id});
|
|
|
|
final img = Image.memory(
|
|
base64Decode(data.substring(23)),
|
|
width: double.infinity,
|
|
fit: BoxFit.fitWidth,
|
|
);
|
|
|
|
// precache image to avoid loading time to render image
|
|
await precacheImage(img.image, context);
|
|
|
|
return img;
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return FutureBuilder<Image>(
|
|
future: _preview, // a previously-obtained Future<String> or null
|
|
builder: (BuildContext context, AsyncSnapshot<Image> snapshot) {
|
|
if (snapshot.hasError) {
|
|
return Text("Error");
|
|
} else if (snapshot.hasData) {
|
|
return ClipRRect(
|
|
borderRadius: BorderRadius.circular(20.0),
|
|
child: Stack(
|
|
children: [
|
|
Container(
|
|
child: Column(
|
|
children: [
|
|
Text(
|
|
widget.dta.title,
|
|
style: TextStyle(fontSize: isTV() ? 8 : 10.5),
|
|
overflow: TextOverflow.clip,
|
|
maxLines: 1,
|
|
),
|
|
snapshot.data!
|
|
],
|
|
),
|
|
color: Color(0xFF6CE56F),
|
|
),
|
|
Positioned.fill(
|
|
child: Material(
|
|
color: Colors.transparent,
|
|
child: GestureDetector(
|
|
behavior: HitTestBehavior.translucent,
|
|
onLongPress: () {
|
|
if (widget.onLongPress != null) widget.onLongPress!(snapshot.data!);
|
|
},
|
|
onLongPressEnd: (details) {
|
|
if (widget.onLongPressEnd != null) widget.onLongPressEnd!();
|
|
},
|
|
child: InkWell(
|
|
onTap: () {
|
|
Navigator.push(
|
|
context,
|
|
MaterialPageRoute(
|
|
builder: (context) => VideoScreen(metaData: widget.dta),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
} else {
|
|
return Column(children: const <Widget>[
|
|
SizedBox(height: 100),
|
|
SizedBox(
|
|
width: 60,
|
|
height: 60,
|
|
child: CircularProgressIndicator(),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.only(top: 16),
|
|
child: Text('Awaiting result...'),
|
|
),
|
|
SizedBox(height: 100),
|
|
]);
|
|
}
|
|
},
|
|
);
|
|
}
|
|
}
|