diff --git a/lib/homepage.dart b/lib/homepage.dart index b610708dba70d0c78d81b116ac29f0a69999c97d..2388a5897e3dc1853680b643311bb39ea2ade7fc 100644 --- a/lib/homepage.dart +++ b/lib/homepage.dart @@ -8,19 +8,18 @@ import 'package:flutter/services.dart'; import 'package:spotify_sdk/models/connection_status.dart'; import 'package:spotify_sdk/models/track.dart'; import 'package:spotify_sdk/spotify_sdk.dart'; -import 'dart:developer' as developer; import 'main.dart'; -void printErr(String msg) { - developer.log(msg); -} - +///After Login/Registration thr routing will bring you to this page +///This page will render the main MusicPlayer class HomePage extends StatelessWidget { final pageController; const HomePage({super.key, this.pageController}); + /// the root of the page will be rendered if the connection status changes or + /// a function emits in the rebuildStream @override Widget build(BuildContext context) { return StreamBuilder<ConnectionStatus>( @@ -38,6 +37,9 @@ class HomePage extends StatelessWidget { ); } + /// builds PlayerStateWidget if the app is connected to Spotify, + /// otherwise it will display a connection button, that will initiate + /// the connection to the local spotify app on click Widget player(BuildContext context) { return Stack(children: [ Center( @@ -82,6 +84,8 @@ class HomePage extends StatelessWidget { ]); } + /// The PlayerStateWidget builds the ControlButtons and the SongInfo, which + /// contains the SongTitle, AlbumTitle and AlbumImage Widget _buildPlayerStateWidget(BuildContext context) { Track? track; if (MusicPlayerState.of(context).playerState == null) { @@ -213,6 +217,7 @@ class HomePage extends StatelessWidget { } } + Future<void> checkIfAppIsActive(BuildContext context) async { try { var isActive = await SpotifySdk.isSpotifyAppActive; @@ -230,9 +235,10 @@ class HomePage extends StatelessWidget { void setStatus(String code, {String? message}) { var text = message ?? ''; - printErr(text); + print(text); } + //build snack bar that can be call for input feedback void buildSnackbar(BuildContext context) { final snackBar = SnackBar( content: Text(MusicPlayerState.of(context).connected @@ -243,6 +249,7 @@ class HomePage extends StatelessWidget { } } +/// renders album image, song and album title class SongInfo extends StatelessWidget{ const SongInfo({ Key? key, @@ -306,6 +313,9 @@ class SongInfo extends StatelessWidget{ } +/// contains the play and pause button +/// on click the the PlayerStateStream will be called and rebuild this buttons +/// and the spotifySdk change the PlayerSate from the local spotify app class ControlButtons extends StatelessWidget { const ControlButtons({ Key? key, diff --git a/lib/main.dart b/lib/main.dart index 53f265c71c825324b7d4c0e7b3005b4e6c10bcf7..1033770adc51249dfcf426463e19e49f43fe2ea1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -11,9 +11,11 @@ import 'package:spotify_sdk/models/track.dart'; import 'homepage.dart'; import 'moodpage.dart'; + Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp; + //loads config file for late usage await dotenv.load(fileName: '.env'); runApp(const MyApp()); } @@ -40,6 +42,10 @@ const Color onPrimary = Color(0xFFFFFFFF); const Color primaryContainer = Color(0xFFFFDFBD); const Color onPrimaryContainer = Color(0xFF312B25); + +/// Renders a static Top-/BottomBar +/// further pages will be loaded in the body of the material app +/// and can be switched via PageViewWidget class HUD extends StatefulWidget { const HUD({super.key}); @@ -108,6 +114,8 @@ class _HUDState extends State<HUD> { } } +/// Renders a player control bar above the bottom bar. +/// It contains a the AlbumImage and a button to player/pause the track class MusicBar extends StatelessWidget { MusicBar({ Key? key, @@ -126,9 +134,6 @@ class MusicBar extends StatelessWidget { return const Center( child: Text('PlayState or track is Null'), ); - } else { - //Todo maybe undo - MusicPlayerState.of(context).currentTrackImageUri = track!.imageUri; } return Container( height: 80, @@ -146,7 +151,7 @@ class MusicBar extends StatelessWidget { child: Column(children: [ Padding( padding: const EdgeInsets.only(bottom: 5, top: 5), - child: Text(track.name, + child: Text(track!.name, style: const TextStyle( fontSize: 16.0, fontWeight: FontWeight.bold, diff --git a/lib/widgets/musicPlayerState.dart b/lib/widgets/musicPlayerState.dart index e1d5ae291a0a2ef4facf2b3a74f6585ad924bfcf..b44da80747c6903a9a39bb51df086e12f1b2c894 100644 --- a/lib/widgets/musicPlayerState.dart +++ b/lib/widgets/musicPlayerState.dart @@ -7,6 +7,9 @@ import 'package:spotify_sdk/models/image_uri.dart'; import 'package:spotify_sdk/models/player_state.dart'; 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 class MusicPlayerState extends InheritedWidget { MusicPlayerState({super.key, required super.child}); @@ -32,14 +35,14 @@ class MusicPlayerState extends InheritedWidget { rebuildStream.sink.add(null); } + /// will be called on PlayStateChange + /// load new Imag e void updatePlayerState() async { playerState = await getPlayerState(); loadAlbumImage().then((value) => playStatedStream.sink.add(null)); - //currentTrackImageUri = playerState?.track?.imageUri; - //spotifyImageWidget(currentTrackImageUri!); - playStatedStream.sink.add(null); } + ///disconnect your app from your local spotify app Future<void> disconnect() async { try { setLoading(true); @@ -55,6 +58,10 @@ class MusicPlayerState extends InheritedWidget { } } + /// 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 { try { setLoading(true); @@ -79,7 +86,6 @@ class MusicPlayerState extends InheritedWidget { return connected; } - //Todo how does the FutureBuilder works Widget spotifyImageWidget(ImageUri imageUri) { return FutureBuilder( future: SpotifySdk.getImage( @@ -88,13 +94,10 @@ class MusicPlayerState extends InheritedWidget { ), builder: (BuildContext context, AsyncSnapshot<Uint8List?> snapshot) { if (snapshot.hasData) { - print("-------------------------------------------------bevor ${albumImage?.hashCode} --------------------------------"); albumImage = Image.memory(snapshot.data!); - print("-------------------------------------------------after ${albumImage?.hashCode} --------------------------------"); rebuildStream.sink.add(null); return const Center(child: Text('Getting image...')); } else if (snapshot.hasError) { - print("-------------------------------------------------bevor ${albumImage?.hashCode} --------------------------------"); setStatus(snapshot.error.toString()); return SizedBox( width: ImageDimension.small.value.toDouble(), @@ -102,7 +105,6 @@ class MusicPlayerState extends InheritedWidget { child: const Center(child: Text('Error getting image')), ); } else { - print("-------------------------------------------------bevor ${albumImage?.hashCode} --------------------------------"); return SizedBox( width: ImageDimension.small.value.toDouble(), height: ImageDimension.small.value.toDouble(), @@ -112,6 +114,9 @@ class MusicPlayerState extends InheritedWidget { }); } + + ///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( @@ -125,6 +130,7 @@ class MusicPlayerState extends InheritedWidget { print(text); } + //get PlayState from local spotify app Future<PlayerState?> getPlayerState() async { try { return await SpotifySdk.getPlayerState();