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),
 | |
|           ]);
 | |
|         }
 | |
|       },
 | |
|     );
 | |
|   }
 | |
| }
 |