Untitled
import 'dart:convert'; import 'dart:collection'; import 'dart:developer'; import 'package:audio_service/audio_service.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; import 'package:gurbani_app/main.dart'; import 'package:gurbani_app/screens/live/miniplayer.dart'; import 'package:gurbani_app/utils/sharepreferce.dart'; import 'package:gurbani_app/widgets/constraints.dart'; import 'package:just_audio/just_audio.dart'; class MusicTile { final String audioLink; final String thumbnailLink; final String headingName; final String location; final String uniqueID; MusicTile({ required this.audioLink, required this.thumbnailLink, required this.headingName, required this.location, required this.uniqueID, }); } class AudioPlayerService { static final AudioPlayer _audioPlayer = AudioPlayer(); static AudioPlayer get audioPlayer => _audioPlayer; } class LiveScreen extends StatefulWidget { const LiveScreen({Key? key}) : super(key: key); @override _LiveScreenState createState() => _LiveScreenState(); } class _LiveScreenState extends State<LiveScreen> { final _firestore = FirebaseFirestore.instance; final Map<String, ValueNotifier<bool>> favoriteMap = {}; LinkedHashSet<MusicTile> favoriteList = LinkedHashSet<MusicTile>(); final AudioPlayer _audioPlayer = AudioPlayerService.audioPlayer; SharedPref sharedPref = SharedPref(); bool isMini = false; bool isMini1 = false; String? Hn = ''; String? TL = ''; String? An = ''; String? Ht = ''; String? AL = ''; void disose() { _audioPlayer.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( elevation: 0, backgroundColor: Colors.blue, // Replace with your color leading: IconButton( onPressed: () { Navigator.pop(context); }, icon: const Icon(Icons.arrow_back_sharp, color: Colors.white), ), title: const Text( "Live Kirtan", style: TextStyle( fontSize: 18, fontWeight: FontWeight.w600, color: Colors.white, ), ), actions: [ IconButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => FavoriteListScreen( favoriteList: favoriteList.toList(), favoriteMap: favoriteMap, audioPlayer: _audioPlayer, ), ), ); }, icon: const Icon(Icons.favorite, color: Color.fromRGBO(244, 67, 54, 1)), ), ], ), body: Padding( padding: const EdgeInsets.all(8.0), child: StreamBuilder<QuerySnapshot>( stream: _firestore.collection('songDocs').snapshots(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center( child: CircularProgressIndicator( color: Colors.black54, ), ); } else if (snapshot.hasData) { final links = snapshot.data!.docs; List<Widget> musicTiles = []; for (var link in links) { String jsonString = link.get('info'); Map<String, dynamic> jsonData = _decodeJson(jsonString); if (jsonData.containsKey('info')) { List<dynamic> jsonList = jsonData['info'] as List<dynamic>; List<MusicTile> musicTilesList = jsonList.map((jsonMap) { return MusicTile( audioLink: jsonMap['audioLink'], thumbnailLink: jsonMap['thumbnailLink'], headingName: jsonMap['headingName'], location: jsonMap['location'], uniqueID: jsonMap['uniqueID'], ); }).toList(); musicTiles.addAll(musicTilesList.map((musicTile) { if (!favoriteMap.containsKey(musicTile.uniqueID)) { favoriteMap[musicTile.uniqueID] = ValueNotifier<bool>(false); } return InkWell( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => JustMusicPlay( audioLink: musicTile.audioLink, thumbnailLink: musicTile.thumbnailLink, headingName: musicTile.headingName, heroTag: musicTile.uniqueID, audioPlayer: _audioPlayer, // Pass the audioPlayer here albumName: musicTile.location, ), ), ); }, child: Card( elevation: 3, margin: EdgeInsets.zero, child: Container( padding: const EdgeInsets.symmetric(horizontal: 10), child: Row( children: [ Container( width: 75, height: 75, decoration: BoxDecoration( image: DecorationImage( fit: BoxFit.cover, image: NetworkImage(musicTile.thumbnailLink), ), ), ), Expanded( child: Container( padding: const EdgeInsets.only( left: 8, top: 8, bottom: 8, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( musicTile.headingName, overflow: TextOverflow.ellipsis, maxLines: 1, style: const TextStyle( fontSize: 17, fontWeight: FontWeight.w600, color: Colors.black, ), ), GestureDetector( onTap: () { setState(() { favoriteMap[musicTile.uniqueID]! .value = !favoriteMap[ musicTile.uniqueID]! .value; if (favoriteMap[ musicTile.uniqueID]! .value) { if (!favoriteList .contains(musicTile)) { favoriteList.add(musicTile); favoriteList = LinkedHashSet< MusicTile>.from( favoriteList.toList() ..sort( (a, b) => a.uniqueID .compareTo( b.uniqueID), ), ); } } else { favoriteList.removeWhere( (item) => item.uniqueID == musicTile.uniqueID, ); } }); }, child: ValueListenableBuilder<bool>( valueListenable: favoriteMap[ musicTile.uniqueID]!, builder: (context, isFavorite, _) { return Icon( isFavorite ? Icons.favorite : Icons.favorite_border, color: Colors.red, ); }, ), ), ], ), const SizedBox( height: 5, ), Text( musicTile.location, overflow: TextOverflow.ellipsis, maxLines: 1, style: const TextStyle( fontSize: 15, color: Colors.orange, ), ), const SizedBox( height: 3, ), ], ), ), ), ], ), ), ), ); })); // Add a separator (empty space) between list items musicTiles.add(const SizedBox(height: 15)); } } return ListView( children: musicTiles, ); } else { return Container( alignment: Alignment.center, child: const Text("Try Again After Some time"), ); } }, ), ), // bottomNavigationBar: isMini != null // ? MiniPlayer( // songTitle: Hn ?? '', // audioPlayer: _audioPlayer, // thumbnailLink: TL ?? '', // uniqueID: Ht ?? '', // audiolink: AL ?? '', // location: An ?? '', // ) // : null, ); } // Helper method to safely decode JSON with error handling Map<String, dynamic> _decodeJson(String jsonString) { try { return json.decode(jsonString) as Map<String, dynamic>; } catch (e) { print("Error decoding JSON: $e"); return {}; } } } class JustMusicPlay extends StatefulWidget { final String audioLink; final String thumbnailLink; final String headingName; final String albumName; final String heroTag; final AudioPlayer audioPlayer; const JustMusicPlay({ Key? key, required this.audioLink, required this.thumbnailLink, required this.headingName, required this.heroTag, required this.audioPlayer, required this.albumName, }) : super(key: key); @override State<JustMusicPlay> createState() => _JustMusicPlayState(); } class _JustMusicPlayState extends State<JustMusicPlay> { SharedPref sharedPref = SharedPref(); bool isPlaying = false; bool isMini = true; @override void initState() { super.initState(); playSongs(); // Play the songs when the widget is created print("=================MEDIA-ITEM===================="); print(newMethod()); } playSongs() { try { widget.audioPlayer.setAudioSource( AudioSource.uri( Uri.parse(widget.audioLink), tag: newMethod(), ), ); if (widget.audioPlayer.playing) { // this was the issue for notification not changing setState(() { widget.audioPlayer.stop(); isPlaying = false; }); } widget.audioPlayer.play(); isPlaying = true; print("audio link --------- ${widget.audioLink}"); print("thumbnail --------- ${widget.thumbnailLink}"); print("heading --------- ${widget.headingName}"); print("HERO TAG --------- ${widget.heroTag}"); } on Exception { log("ERROR PARSING DATA"); } } MediaItem newMethod() { return MediaItem( id: widget.headingName, album: widget.albumName, title: widget.headingName, artUri: Uri.parse(widget.thumbnailLink), ); } @override Widget build(BuildContext context) { print(widget.audioLink); return Scaffold( appBar: AppBar( elevation: 0, title: Text(widget.headingName, style: const TextStyle(fontSize: 22)), backgroundColor: Colors.blue, leading: IconButton( icon: const Icon(Icons.arrow_back_sharp), color: Colors.white, onPressed: () { Navigator.pop(context); }, ), actions: [ IconButton( icon: const Icon(Icons.share), onPressed: () {}, ), ], ), body: Container( child: Column( children: [ Padding( padding: const EdgeInsets.only(top: 50.0, left: 14.0, right: 14.0), child: ClipRRect( borderRadius: const BorderRadius.all(Radius.circular(10.0)), child: Hero( tag: widget.heroTag, child: Image.network( (widget.thumbnailLink), height: 370, width: 500, fit: BoxFit.cover, ), ), ), ), Center( child: Padding( padding: const EdgeInsets.only(top: 38.0), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ IconButton( onPressed: () {}, iconSize: 50, icon: const Icon(Icons.circle), ), IconButton( onPressed: () { if (isPlaying) { widget.audioPlayer.pause(); setState(() { isPlaying = false; }); } else { widget.audioPlayer.play(); setState(() { isPlaying = true; }); } }, iconSize: 50, icon: isPlaying ? const Icon(Icons.pause_circle) : const Icon(Icons.play_circle), ), IconButton( onPressed: () { setState(() { sharedPref.write(key: 'isMini', value: false); print('My boolean value when stop: $isMini'); }); widget.audioPlayer.stop(); // Navigator.pop(context); Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => const LiveScreen()), ); }, iconSize: 50, icon: const Icon(Icons.stop_circle_outlined), ), ], ), ), ), ], ), ), ); } } class FavoriteListScreen extends StatelessWidget { final List<MusicTile> favoriteList; final Map<String, ValueNotifier<bool>> favoriteMap; final AudioPlayer audioPlayer; // Pass the AudioPlayer instance here const FavoriteListScreen({ Key? key, required this.favoriteList, required this.favoriteMap, required this.audioPlayer, }) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( elevation: 0, backgroundColor: Colors.blue, leading: IconButton( onPressed: () { Navigator.pop(context); }, icon: const Icon(Icons.arrow_back_sharp, color: Colors.white), ), title: const Text( "Favorite List", style: TextStyle( fontSize: 18, fontWeight: FontWeight.w600, color: Colors.white, ), ), ), body: Padding( padding: const EdgeInsets.all(8.0), child: ListView.builder( itemCount: favoriteList.length, itemBuilder: (context, index) { MusicTile musicTile = favoriteList.elementAt(index); return InkWell( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => JustMusicPlay( audioLink: musicTile.audioLink, thumbnailLink: musicTile.thumbnailLink, headingName: musicTile.headingName, heroTag: musicTile.uniqueID, audioPlayer: audioPlayer, // Use the audioPlayer from the constructor albumName: musicTile.location, ), ), ); }, child: Card( elevation: 3, margin: EdgeInsets.zero, child: Container( padding: const EdgeInsets.symmetric(horizontal: 10), child: Row( children: [ Container( width: 75, height: 75, decoration: BoxDecoration( image: DecorationImage( fit: BoxFit.cover, image: NetworkImage(musicTile.thumbnailLink), ), ), ), Expanded( child: Container( padding: const EdgeInsets.only( left: 8, top: 8, bottom: 8, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( musicTile.headingName, overflow: TextOverflow.ellipsis, maxLines: 1, style: const TextStyle( fontSize: 17, fontWeight: FontWeight.w600, color: Colors.black, ), ), ], ), const SizedBox( height: 5, ), Text( musicTile.location, overflow: TextOverflow.ellipsis, maxLines: 1, style: const TextStyle( fontSize: 15, color: Colors.orange, ), ), const SizedBox( height: 3, ), ], ), ), ), ], ), ), ), ); }, ), ), ); } void toggleFavoriteStatus(String uniqueID) { favoriteMap[uniqueID]!.value = !favoriteMap[uniqueID]!.value; if (!favoriteMap[uniqueID]!.value) { favoriteList.removeWhere((item) => item?.uniqueID == uniqueID); } } } // aa
Leave a Comment