diff --git a/app/src/main/java/com/example/spotifydownloader/Fragments/SelectSongFragment.kt b/app/src/main/java/com/example/spotifydownloader/Fragments/SelectSongFragment.kt index 0563737..e5a850f 100644 --- a/app/src/main/java/com/example/spotifydownloader/Fragments/SelectSongFragment.kt +++ b/app/src/main/java/com/example/spotifydownloader/Fragments/SelectSongFragment.kt @@ -83,7 +83,8 @@ class selectSongFragment : Fragment(R.layout.fragment_select_song) { albumName = songData.album.name, albumArtistName = songData.album.artists[0].name, releaseDate = songData.album.release_date, - folderUri = args.ItemListData.folderUri + folderUri = args.ItemListData.folderUri, + isSearch = true ) val action = selectSongFragmentDirections.actionSelectSongFragmentToSongDownloadFragment(data) navController.navigate(action) diff --git a/app/src/main/java/com/example/spotifydownloader/Fragments/SongDownloadFragment.kt b/app/src/main/java/com/example/spotifydownloader/Fragments/SongDownloadFragment.kt index 3f85152..e3d3420 100644 --- a/app/src/main/java/com/example/spotifydownloader/Fragments/SongDownloadFragment.kt +++ b/app/src/main/java/com/example/spotifydownloader/Fragments/SongDownloadFragment.kt @@ -45,7 +45,6 @@ class SongDownloadFragment : Fragment(R.layout.fragment_song_download) { private lateinit var navController: NavController private val args by navArgs() private var stop = false - private var songItems = mutableListOf() private lateinit var binding:FragmentSongDownloadBinding private lateinit var bottomNav : BottomNavigationView @@ -93,8 +92,12 @@ class SongDownloadFragment : Fragment(R.layout.fragment_song_download) { "Finished", Toast.LENGTH_SHORT ).show() - navController.popBackStack() - navController.popBackStack() + if (args.DataSearch.isSearch) { + navController.popBackStack() + navController.popBackStack() + }else{ + navController.popBackStack() + } bottomNav.startAnimation(from_bottom) bottomNav.menu.forEach { it.isEnabled = true @@ -111,8 +114,12 @@ class SongDownloadFragment : Fragment(R.layout.fragment_song_download) { "Internet Connection Error", Toast.LENGTH_SHORT ).show() - navController.popBackStack() - navController.popBackStack() + if (args.DataSearch.isSearch) { + navController.popBackStack() + navController.popBackStack() + }else{ + navController.popBackStack() + } bottomNav.startAnimation(from_bottom) bottomNav.menu.forEach { it.isEnabled = true @@ -130,8 +137,12 @@ class SongDownloadFragment : Fragment(R.layout.fragment_song_download) { "Finished", Toast.LENGTH_SHORT ).show() - navController.popBackStack() - navController.popBackStack() + if (args.DataSearch.isSearch) { + navController.popBackStack() + navController.popBackStack() + }else{ + navController.popBackStack() + } bottomNav.startAnimation(from_bottom) bottomNav.menu.forEach { it.isEnabled = true @@ -220,8 +231,8 @@ class SongDownloadFragment : Fragment(R.layout.fragment_song_download) { request.addOption("--audio-format", "mp3") request.addOption("-R", "2") request.addOption("--socket-timeout", "40") - request.addOption("--downloader", "libaria2c.so"); - request.addOption("--external-downloader-args", "aria2c:\"--summary-interval=1\""); + request.addOption("--downloader", "libaria2c.so") + request.addOption("--external-downloader-args", "aria2c:\"--summary-interval=1\"") println(request.buildCommand()) @@ -270,6 +281,7 @@ class SongDownloadFragment : Fragment(R.layout.fragment_song_download) { }catch (e: IOException){ return 1 } + var destUri = data val treeUri = Uri.parse(destUri.toString()) val docId = DocumentsContract.getTreeDocumentId(treeUri) @@ -277,7 +289,7 @@ class SongDownloadFragment : Fragment(R.layout.fragment_song_download) { val fileTempLocation = File("${fileLocation}.mp3") val mimeType = MimeTypeMap.getSingleton() - .getMimeTypeFromExtension(fileTempLocation.extension) ?: "*/*" + .getMimeTypeFromExtension(fileTempLocation.extension) ?:"*/*" destUri = DocumentsContract.createDocument( (context as Activity).contentResolver, destDir, @@ -293,6 +305,7 @@ class SongDownloadFragment : Fragment(R.layout.fragment_song_download) { binding.progressBar.incrementProgressBy(10) } + } else if (!(isDeviceOnline(context as Activity))) { Log.e(tag, "Connection Error") diff --git a/app/src/main/java/com/example/spotifydownloader/Fragments/SongFragment.kt b/app/src/main/java/com/example/spotifydownloader/Fragments/SongFragment.kt index 7246c7a..9b33184 100644 --- a/app/src/main/java/com/example/spotifydownloader/Fragments/SongFragment.kt +++ b/app/src/main/java/com/example/spotifydownloader/Fragments/SongFragment.kt @@ -159,7 +159,6 @@ class SongFragment : Fragment(R.layout.fragment_song) { val itemListData = ItemListData(Items= ItemListObject.toList(), folderUri = folderUri) val action = SongFragmentDirections.actionSongFragmentToSelectSongFragment(itemListData) - println(itemListData.Items[0]) runOnUiThread { enableDisableUI(true) navController.navigate(action) diff --git a/app/src/main/java/com/example/spotifydownloader/Fragments/TrackFragment.kt b/app/src/main/java/com/example/spotifydownloader/Fragments/TrackFragment.kt new file mode 100644 index 0000000..caf674b --- /dev/null +++ b/app/src/main/java/com/example/spotifydownloader/Fragments/TrackFragment.kt @@ -0,0 +1,256 @@ +package com.example.spotifydownloader.Fragments + +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.net.ConnectivityManager +import android.net.Uri +import android.os.Bundle +import android.util.Log +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.animation.Animation +import android.view.animation.AnimationUtils +import android.widget.Toast +import androidx.activity.result.contract.ActivityResultContracts +import androidx.core.view.forEach +import androidx.fragment.app.activityViewModels +import androidx.lifecycle.Observer +import androidx.lifecycle.lifecycleScope +import androidx.navigation.NavController +import androidx.navigation.Navigation +import com.example.spotifydownloader.R +import com.example.spotifydownloader.SharedViewModel +import com.example.spotifydownloader.SpotifyApi.model.Search.Item +import com.example.spotifydownloader.databinding.FragmentTrackBinding +import com.example.spotifydownloader.parcels.DataSearch +import com.google.android.material.bottomnavigation.BottomNavigationView +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import java.io.IOException + + +class trackFragment : Fragment(R.layout.fragment_track) { + private var _binding: FragmentTrackBinding? = null + private var data: Intent? = null + private val tag = "MainActivity" + private lateinit var navController: NavController + private val sharedViewModel : SharedViewModel by activityViewModels() + private var folderUri: Uri?=null + private lateinit var bottomNav : BottomNavigationView + + private val binding get() = _binding!! + + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + // Inflate the layout for this fragment + _binding = FragmentTrackBinding.inflate(inflater, container, false) + val view = binding.root + return view + } + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + navController = Navigation.findNavController(view) + val resultLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + if (result.resultCode == Activity.RESULT_OK) { + // There are no request codes + data = result.data + sharedViewModel.folderUri.value = data?.data + if (data != null) { + Log.d(tag, data?.data.toString()) + Log.d(tag, (context as Activity).externalCacheDir.toString()) + + } + + } + + } + binding.perms.setOnClickListener { + val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) + resultLauncher.launch(intent) + Log.d(tag, resultLauncher.toString()) + + + } + bottomNav = activity?.findViewById(R.id.bottomNav)!! + val from_top : Animation by lazy { AnimationUtils.loadAnimation((context as Activity), + R.anim.from_top + ) } + + + + + + fun isDeviceOnline(context: Context): Boolean { + val connManager = + context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val networkCapabilities = connManager.getNetworkCapabilities(connManager.activeNetwork) + return if (networkCapabilities == null) { + println("Device Offline") + false + } else { + true + } + } + fun enableDisableUI(enable: Boolean) { + + binding.perms.isEnabled = enable + binding.PlaylistLinkTextBox.isEnabled = enable + binding.download.isEnabled = enable + } + val spotifyApi = sharedViewModel.spotifyApi + sharedViewModel.trackLink.observe(viewLifecycleOwner, Observer { + trackLink -> + binding.PlaylistLinkEditText.setText(trackLink) + }) + sharedViewModel.folderUri.observe(viewLifecycleOwner, Observer { + folderUri1 -> + folderUri = folderUri1 + + }) + binding.download.setOnClickListener { + + + + lifecycleScope.launch(Dispatchers.IO) { + runOnUiThread { + enableDisableUI(false) + } + + + var succesCode = 0 + + var songName = "" + var imgUrl = "" + var artistName = "" + var filename = "" + var albumName = "" + var albumArtistName = "" + var releaseDate = "" + val regex = Regex("[^A-Za-z0-9]") + + try { + + + val textInBox = binding.PlaylistLinkEditText.text.toString() + println(textInBox) + val response = spotifyApi.getTrack(textInBox) + songName = response.name + imgUrl = response.album.images[0].url + artistName = response.artists[0].name + filename = regex.replace(response.name,"") + albumName = response.album.name + albumArtistName = response.album.artists[0].name + releaseDate = response.album.release_date + + + + + }catch (e:IOException) { + Log.e(tag, e.toString()) + + succesCode = 1 + }catch (e:IllegalArgumentException){ + Log.e(tag,e.toString()) + + succesCode = 2 + + + } + if (isDeviceOnline(context as Activity)&&folderUri!=null&& succesCode== 0){ + val data = DataSearch( + songName=songName, + imgUrl = imgUrl, + artistName=artistName, + filename = filename, + albumName = albumName, + albumArtistName = albumArtistName, + releaseDate = releaseDate, + folderUri = folderUri, + isSearch = false + ) + val action = trackFragmentDirections.actionTrackFragmentToSongDownloadFragment(data) + runOnUiThread { + bottomNav.startAnimation(from_top) + bottomNav.menu.forEach { + it.isEnabled = false + } + enableDisableUI(true) + navController.navigate(action) + } + + + }else if (succesCode == 1){ + runOnUiThread { + Toast.makeText( + context as Activity, + "Connection Error try again later", + Toast.LENGTH_SHORT + ).show() + + + enableDisableUI(true) + } + + + } + else if (succesCode == 2 ) { + runOnUiThread { + Toast.makeText( + context as Activity, "Invalid track link", Toast.LENGTH_SHORT + ).show() + enableDisableUI(true) + } + } + + + else if (folderUri == null){ + runOnUiThread { + Toast.makeText( + context as Activity, "Please choose a folder", Toast.LENGTH_SHORT + ).show() + enableDisableUI(true) + } + } + + else { + runOnUiThread { + + Toast.makeText( + context as Activity, + "Connection Error try again later", + Toast.LENGTH_SHORT + ).show() + + + enableDisableUI(true) + } + } + } + + } + + + + + + } + private fun Fragment?.runOnUiThread(action: () -> Unit) { + this ?: return + if (!isAdded) return // Fragment not attached to an Activity + activity?.runOnUiThread(action) + } + +} + diff --git a/app/src/main/java/com/example/spotifydownloader/MainActivity.kt b/app/src/main/java/com/example/spotifydownloader/MainActivity.kt index b415a18..83dc280 100644 --- a/app/src/main/java/com/example/spotifydownloader/MainActivity.kt +++ b/app/src/main/java/com/example/spotifydownloader/MainActivity.kt @@ -4,12 +4,14 @@ import android.content.Intent import android.os.Bundle import android.util.Log import android.view.MenuItem +import android.view.View import android.widget.Toast import androidx.activity.viewModels import androidx.appcompat.app.ActionBarDrawerToggle import androidx.appcompat.app.AppCompatActivity import androidx.core.content.PackageManagerCompat.LOG_TAG import androidx.core.view.GravityCompat +import androidx.core.view.forEach import androidx.core.view.get import androidx.navigation.NavController import androidx.navigation.NavGraph @@ -21,6 +23,7 @@ import com.example.spotifydownloader.SpotifyApi.SpotifyApi import com.example.spotifydownloader.SpotifyApi.util.Constants.Companion.CLIENT_ID import com.example.spotifydownloader.SpotifyApi.util.Constants.Companion.CLIENT_SECRET import com.example.spotifydownloader.databinding.ActivityMainBinding +import com.google.android.material.bottomnavigation.BottomNavigationView class MainActivity : AppCompatActivity() { @@ -30,6 +33,7 @@ class MainActivity : AppCompatActivity() { private val tag = "MainActivity" private val sharedViewModel: SharedViewModel by viewModels() private lateinit var navController:NavController + private lateinit var bottomNavView:BottomNavigationView override fun onCreate(savedInstanceState: Bundle?) { @@ -42,7 +46,7 @@ class MainActivity : AppCompatActivity() { - val bottomNavView = binding.bottomNav + bottomNavView = binding.bottomNav navController = findNavController(R.id.fragment) @@ -91,14 +95,36 @@ class MainActivity : AppCompatActivity() { "playlist"->{ sharedViewModel.playlistLink.value = it navController.navigate(R.id.playListFragment) + bottomNavView.forEach { + + it.isEnabled = true + } + bottomNavView.visibility = View.GONE + + } "album"->{ sharedViewModel.albumLink.value = it navController.navigate(R.id.albumFragment) + bottomNavView.forEach { + it.isEnabled = true + } + bottomNavView.visibility = View.GONE } + "track"->{ + sharedViewModel.trackLink.value= it + navController.navigate(R.id.trackFragment) + bottomNavView.forEach { + + it.isEnabled = true + } + bottomNavView.visibility = View.GONE + } + + else -> { Toast.makeText(this,"Invalid Link",Toast.LENGTH_SHORT).show() diff --git a/app/src/main/java/com/example/spotifydownloader/SharedViewModel.kt b/app/src/main/java/com/example/spotifydownloader/SharedViewModel.kt index 1dbfad4..dafded1 100644 --- a/app/src/main/java/com/example/spotifydownloader/SharedViewModel.kt +++ b/app/src/main/java/com/example/spotifydownloader/SharedViewModel.kt @@ -10,6 +10,7 @@ import com.example.spotifydownloader.SpotifyApi.util.Constants.Companion.CLIENT_ class SharedViewModel:ViewModel() { var playlistLink = MutableLiveData() var albumLink = MutableLiveData() + var trackLink = MutableLiveData() var folderUri = MutableLiveData() val spotifyApi = SpotifyApi(CLIENT_ID, CLIENT_SECRET) } \ No newline at end of file diff --git a/app/src/main/java/com/example/spotifydownloader/parcels/DataSearch.kt b/app/src/main/java/com/example/spotifydownloader/parcels/DataSearch.kt index 246aeda..6112e6d 100644 --- a/app/src/main/java/com/example/spotifydownloader/parcels/DataSearch.kt +++ b/app/src/main/java/com/example/spotifydownloader/parcels/DataSearch.kt @@ -15,7 +15,8 @@ data class DataSearch( val albumName:String, val albumArtistName:String, val releaseDate:String, - val folderUri: Uri? + val folderUri: Uri?, + val isSearch:Boolean diff --git a/app/src/main/res/layout/fragment_track.xml b/app/src/main/res/layout/fragment_track.xml new file mode 100644 index 0000000..d5a778e --- /dev/null +++ b/app/src/main/res/layout/fragment_track.xml @@ -0,0 +1,144 @@ + + + + + + + + +