Newer
Older
Erik Hinkelmanns
committed
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:spotify_sdk/models/image_uri.dart';
import 'package:spotify_sdk/models/player_state.dart';
Erik Hinkelmanns
committed
import 'package:spotify_sdk/spotify_sdk.dart';
/// InheritedWidget that holds the state of your MusicPlayer
/// the rebuild stream builds the hole body
/// the playStatedStream only rebuild the Image, SongInfo and the ControlsButtons
Erik Hinkelmanns
committed
class MusicPlayerState extends InheritedWidget {
Erik Hinkelmanns
committed
bool loading = false;
bool connected = false;
StreamController<void> rebuildStream = StreamController.broadcast();
StreamController<void> playStatedStream = StreamController.broadcast();
PlayerState? playerState;
Erik Hinkelmanns
committed
late ImageUri? currentTrackImageUri;
Erik Hinkelmanns
committed
static MusicPlayerState? maybeOf(BuildContext context) =>
context.dependOnInheritedWidgetOfExactType<MusicPlayerState>();
static MusicPlayerState of(BuildContext context) {
final MusicPlayerState? result = maybeOf(context);
assert(result != null, 'No PlayerState found in context');
return result!;
}
Erik Hinkelmanns
committed
this.loading = loading;
rebuildStream.sink.add(null);
Erik Hinkelmanns
committed
}
/// will be called on PlayStateChange
/// load new Imag e
void updatePlayerState() async {
playerState = await getPlayerState();
loadAlbumImage().then((value) => playStatedStream.sink.add(null));
Erik Hinkelmanns
committed
Future<void> disconnect() async {
try {
setLoading(true);
var result = await SpotifySdk.disconnect();
setStatus(result ? 'disconnect successful' : 'disconnect failed');
setLoading(false);
} on PlatformException catch (e) {
setLoading(false);
setStatus(e.code, message: e.message);
} on MissingPluginException {
setLoading(false);
setStatus('not implemented');
}
}
/// establish connection to local spotify app
/// connection data will be loaded in main from dotenv.env
/// if connection successful
/// connection will be set to true and loading to false
Future<bool> connectToSpotifyRemote() async {
Erik Hinkelmanns
committed
try {
setLoading(true);
var result = await SpotifySdk.connectToSpotifyRemote(
clientId: dotenv.env['CLIENT_ID'].toString(),
redirectUrl: dotenv.env['REDIRECT_URL'].toString());
setStatus(result
? 'connect to spotify successful'
: 'connect to spotify failed');
playerState = await getPlayerState();
setLoading(false);
connected = result;
Erik Hinkelmanns
committed
} on PlatformException catch (e) {
setLoading(false);
setStatus(e.code, message: e.message);
} on MissingPluginException {
setLoading(false);
setStatus('not implemented');
}
return connected;
Erik Hinkelmanns
committed
}
Widget spotifyImageWidget(ImageUri imageUri) {
return FutureBuilder(
future: SpotifySdk.getImage(
dimension: ImageDimension.large,
),
builder: (BuildContext context, AsyncSnapshot<Uint8List?> snapshot) {
if (snapshot.hasData) {
albumImage = Image.memory(snapshot.data!);
rebuildStream.sink.add(null);
return const Center(child: Text('Getting image...'));
} else if (snapshot.hasError) {
setStatus(snapshot.error.toString());
return SizedBox(
width: ImageDimension.small.value.toDouble(),
height: ImageDimension.small.value.toDouble(),
child: const Center(child: Text('Error getting image')),
);
} else {
return SizedBox(
width: ImageDimension.small.value.toDouble(),
height: ImageDimension.small.value.toDouble(),
child: const Center(child: Text('Getting image...')),
);
}
});
}
///loads the Album image via spotify.sdk and saves the image in MusicPlayState
///for global access
Future<void> loadAlbumImage() async {
currentTrackImageUri = playerState?.track?.imageUri;
albumImage = Image.memory((await SpotifySdk.getImage(
imageUri: currentTrackImageUri!,
dimension: ImageDimension.large,
))!);
Erik Hinkelmanns
committed
void setStatus(String code, {String? message}) {
var text = message ?? '';
print(text);
}
Future<PlayerState?> getPlayerState() async {
try {
return await SpotifySdk.getPlayerState();
} on PlatformException catch (e) {
setStatus(e.code, message: e.message);
} on MissingPluginException {
setStatus('not implemented');
}
}
Erik Hinkelmanns
committed
@override
bool updateShouldNotify(covariant MusicPlayerState oldWidget) {
return loading != oldWidget.loading && connected != oldWidget.connected;
}
}