MediaQueue: QueueList in Example

This commit is contained in:
gianlucaparadise 2022-07-22 06:16:38 +02:00
parent 90ae50dd28
commit 3351e5e5ab
7 changed files with 175 additions and 4 deletions

View file

@ -223,7 +223,17 @@ class _MyAppState extends State<MyApp> {
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
child: Text("Append to Queue"),
onPressed: _hasSession ? _appendToQueue : null,
/**
* From the documentation:
* The Receiver SDK maintains the queue and responds to operations
* on the queue as long as the queue has at least one item
* currently active (playing or paused).
*/
onPressed: _hasSession &&
![PlayerState.idle, PlayerState.unknown]
.contains(_playerState)
? _appendToQueue
: null,
),
),
Padding(

View file

@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_cast_framework/cast.dart';
import 'package:flutter_cast_framework/widgets.dart';
import 'package:flutter_cast_framework_example/widgets/QueueListItem.dart';
class QueueRoute extends StatelessWidget {
final FlutterCastFramework castFramework;
@ -9,23 +11,66 @@ class QueueRoute extends StatelessWidget {
required this.castFramework,
}) : super(key: key);
Widget _getEmptyQueueMessage(BuildContext context) {
Widget _getEmptyQueueMessage(BuildContext context, String text) {
return Container(
alignment: Alignment.center,
child: Text(
"Queue is empty!",
text,
style: Theme.of(context).textTheme.headline6,
),
);
}
Widget _getEmptyItemMessage(BuildContext context, String text) {
return Container(
alignment: Alignment.center,
child: Text(
text,
style: Theme.of(context).textTheme.bodyText1,
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Queue'),
),
body: _getEmptyQueueMessage(context),
body: QueueList(
castFramework: castFramework,
listItemBuilder: (BuildContext context, MediaQueueItem item) {
return QueueListItem(item: item);
},
emptyListStateBuilder: (context, isLoading, error) {
if (isLoading) {
return _getEmptyQueueMessage(context, "Loading...");
}
if (error != null) {
debugPrint(
"MediaQueue - error while retrieving items count $error",
);
return _getEmptyQueueMessage(context, "An error occurred");
}
return _getEmptyQueueMessage(context, "Queue is empty!");
},
emptyItemStateBuilder: (context, isLoading, error) {
if (isLoading) {
return _getEmptyItemMessage(context, "Loading...");
}
if (error != null) {
debugPrint(
"MediaQueue - error while retrieving items count $error",
);
return _getEmptyItemMessage(context, "An error occurred");
}
return _getEmptyItemMessage(context, "Item is empty!");
},
),
);
}
}

View file

@ -0,0 +1,36 @@
import 'package:flutter/material.dart';
import 'package:flutter_cast_framework/cast.dart';
class QueueItemHeading extends StatelessWidget {
final MediaInfo? mediaInfo;
const QueueItemHeading({
Key? key,
required this.mediaInfo,
}) : super(key: key);
@override
Widget build(BuildContext context) {
// final titleText = mediaInfo?.mediaMetadata?.strings[MediaMetadataKey.title]
// final subtitleText = mediaInfo?.mediaMetadata?.strings[MediaMetadataKey.subtitle]
final titleText = "";
final subtitleText = "";
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
titleText,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
Container(height: 2),
Text(
subtitleText,
overflow: TextOverflow.ellipsis,
maxLines: 1,
)
],
);
}
}

View file

@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
import 'package:flutter_cast_framework/cast.dart';
import 'package:flutter_cast_framework_example/widgets/QueueItemHeading.dart';
import 'package:flutter_cast_framework_example/widgets/Thumbnail.dart';
class QueueListItem extends StatelessWidget {
final MediaQueueItem item;
const QueueListItem({
Key? key,
required this.item,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final webImage = item.media?.mediaMetadata?.webImages?.first;
return Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1,
color: Colors.grey,
),
),
),
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Thumbnail(image: webImage),
),
Container(width: 10), // this is a spacer
Expanded(
flex: 2,
child: QueueItemHeading(
mediaInfo: item.media,
),
),
// isCastConnected ? moreMenuButton : SizedBox.shrink(),
],
),
);
}
}

View file

@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'package:flutter_cast_framework/cast.dart';
import 'package:transparent_image/transparent_image.dart';
class Thumbnail extends StatelessWidget {
final WebImage? image;
const Thumbnail({
Key? key,
required this.image,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final imageUrl = image?.url;
return AspectRatio(
aspectRatio: 480.0 / 270.0,
child: imageUrl == null
? SizedBox.shrink()
: FadeInImage.memoryNetwork(
placeholder: kTransparentImage,
image: imageUrl,
),
);
}
}

View file

@ -170,6 +170,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.2"
transparent_image:
dependency: "direct main"
description:
name: transparent_image
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
typed_data:
dependency: transitive
description:

View file

@ -13,6 +13,7 @@ dependencies:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
transparent_image: ^2.0.0
dev_dependencies:
flutter_test: