diff --git a/app/src/main/java/com/github/libretube/MainActivity.kt b/app/src/main/java/com/github/libretube/MainActivity.kt index 749d3815f..e6e7beee0 100644 --- a/app/src/main/java/com/github/libretube/MainActivity.kt +++ b/app/src/main/java/com/github/libretube/MainActivity.kt @@ -22,7 +22,6 @@ import android.view.inputmethod.InputMethodManager import android.widget.Button import android.widget.ImageView import android.widget.LinearLayout -import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.constraintlayout.motion.widget.MotionLayout @@ -30,15 +29,12 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.os.bundleOf import androidx.core.text.HtmlCompat import androidx.fragment.app.Fragment -import androidx.fragment.app.setFragmentResult -import androidx.lifecycle.lifecycleScope import androidx.navigation.NavController import androidx.navigation.findNavController import androidx.navigation.ui.setupWithNavController import androidx.preference.PreferenceManager import com.github.libretube.fragments.PlayerFragment import com.github.libretube.fragments.isFullScreen -import com.github.libretube.obj.Playlists import com.github.libretube.preferences.SponsorBlockSettings import com.github.libretube.util.CronetHelper import com.github.libretube.util.LocaleHelper @@ -46,8 +42,6 @@ import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.ThemeHelper import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.color.DynamicColors -import retrofit2.HttpException -import java.io.IOException class MainActivity : AppCompatActivity() { val TAG = "MainActivity" @@ -160,30 +154,6 @@ class MainActivity : AppCompatActivity() { false } } - importPlaylist(applicationContext, "PLr6ePnxUUANvLpkBIDsY-MbArrGNBknt_") - } - - private fun importPlaylist(context: Context, playlistId: String) { - fun run() { - val sharedPref = context.getSharedPreferences("token", Context.MODE_PRIVATE) - val token = sharedPref?.getString("token", "")!! - lifecycleScope.launchWhenCreated { - val response = try { - RetrofitInstance.api.importPlaylist(token, playlistId) - } catch (e: IOException) { - println(e) - Log.e(TAG, "IOException, you might not have internet connection") - Toast.makeText(context, R.string.unknown_error, Toast.LENGTH_SHORT).show() - return@launchWhenCreated - } catch (e: HttpException) { - Log.e(TAG, "HttpException, unexpected response $e") - Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show() - return@launchWhenCreated - } - Log.e(TAG, response.toString()) - } - } - run() } private fun isNetworkAvailable(context: Context): Boolean { diff --git a/app/src/main/java/com/github/libretube/adapters/PlaylistAdapter.kt b/app/src/main/java/com/github/libretube/adapters/PlaylistAdapter.kt index 3938ae50d..0523e123b 100644 --- a/app/src/main/java/com/github/libretube/adapters/PlaylistAdapter.kt +++ b/app/src/main/java/com/github/libretube/adapters/PlaylistAdapter.kt @@ -20,6 +20,8 @@ import com.github.libretube.obj.PlaylistId import com.github.libretube.obj.StreamItem import com.github.libretube.util.RetrofitInstance import com.squareup.picasso.Picasso +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import java.io.IOException import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -92,7 +94,7 @@ class PlaylistAdapter( private fun removeFromPlaylist(token: String, position: Int) { fun run() { - GlobalScope.launch { + CoroutineScope(Dispatchers.IO).launch { val response = try { RetrofitInstance.api.removeFromPlaylist( token, diff --git a/app/src/main/java/com/github/libretube/adapters/SearchAdapter.kt b/app/src/main/java/com/github/libretube/adapters/SearchAdapter.kt index 75fedea49..33b5c705f 100644 --- a/app/src/main/java/com/github/libretube/adapters/SearchAdapter.kt +++ b/app/src/main/java/com/github/libretube/adapters/SearchAdapter.kt @@ -13,6 +13,7 @@ import androidx.fragment.app.FragmentManager import androidx.recyclerview.widget.RecyclerView import com.github.libretube.MainActivity import com.github.libretube.R +import com.github.libretube.dialogs.PlaylistOptionsDialog import com.github.libretube.dialogs.VideoOptionsDialog import com.github.libretube.fragments.PlayerFragment import com.github.libretube.obj.SearchItem @@ -153,6 +154,12 @@ class SearchViewHolder( val bundle = bundleOf("playlist_id" to item.url) activity.navController.navigate(R.id.playlistFragment, bundle) } + v.setOnLongClickListener { + val playlistId = item.url!!.replace("/playlist?list=", "") + PlaylistOptionsDialog(playlistId, v.context) + .show(childFragmentManager, "PlaylistOptionsDialog") + true + } } fun bind(searchItem: SearchItem) { diff --git a/app/src/main/java/com/github/libretube/dialogs/PlaylistOptionsDialog.kt b/app/src/main/java/com/github/libretube/dialogs/PlaylistOptionsDialog.kt new file mode 100644 index 000000000..bc97dcf40 --- /dev/null +++ b/app/src/main/java/com/github/libretube/dialogs/PlaylistOptionsDialog.kt @@ -0,0 +1,79 @@ +package com.github.libretube.dialogs + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import android.util.Log +import android.widget.ArrayAdapter +import android.widget.Toast +import androidx.fragment.app.DialogFragment +import androidx.lifecycle.lifecycleScope +import com.github.libretube.R +import com.github.libretube.obj.PlaylistId +import com.github.libretube.util.RetrofitInstance +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import retrofit2.HttpException +import java.io.IOException + +class PlaylistOptionsDialog( + private val playlistId: String, + context: Context +) : DialogFragment() { + val TAG = "PlaylistOptionsDialog" + + private val optionsList = listOf( + context.getString(R.string.clonePlaylist), + context.getString(R.string.share) + ) + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val dialog = MaterialAlertDialogBuilder(requireContext()) + .setNegativeButton(R.string.cancel) { dialog, _ -> + dialog.dismiss() + } + .setAdapter( + ArrayAdapter( + requireContext(), + R.layout.video_options_dialog_item, + optionsList + ) + ) { _, which -> + when (which) { + // Clone the playlist to the users Piped account + 0 -> { + val sharedPref = + context?.getSharedPreferences("token", Context.MODE_PRIVATE) + val token = sharedPref?.getString("token", "")!! + importPlaylist(token, playlistId) + } + // share the playlist + 1 -> { + val shareDialog = ShareDialog(playlistId) + // using parentFragmentManager is important here + shareDialog.show(parentFragmentManager, "ShareDialog") + } + } + } + return dialog.show() + } + + private fun importPlaylist(token: String, playlistId: String) { + fun run() { + CoroutineScope(Dispatchers.IO).launch { + val response = try { + RetrofitInstance.api.importPlaylist(token, PlaylistId(playlistId)) + } catch (e: IOException) { + println(e) + return@launch + } catch (e: HttpException) { + return@launch + } + Log.e(TAG, response.toString()) + } + } + run() + } +} diff --git a/app/src/main/java/com/github/libretube/dialogs/VideoOptionsDialog.kt b/app/src/main/java/com/github/libretube/dialogs/VideoOptionsDialog.kt index 532808e0d..c68876838 100644 --- a/app/src/main/java/com/github/libretube/dialogs/VideoOptionsDialog.kt +++ b/app/src/main/java/com/github/libretube/dialogs/VideoOptionsDialog.kt @@ -19,7 +19,7 @@ class VideoOptionsDialog(private val videoId: String, context: Context) : Dialog /** * List that stores the different menu options. In the future could be add more options here. */ - private val list = listOf( + private val optionsList = listOf( context.getString(R.string.playOnBackground), context.getString(R.string.addToPlaylist), context.getString(R.string.share) @@ -37,9 +37,9 @@ class VideoOptionsDialog(private val videoId: String, context: Context) : Dialog ArrayAdapter( requireContext(), R.layout.video_options_dialog_item, - list + optionsList ) - ) { dialog, which -> + ) { _, which -> // For now, this checks the position of the option with the position that is in the // list. I don't like it, but we will do like this for now. when (which) { @@ -70,9 +70,6 @@ class VideoOptionsDialog(private val videoId: String, context: Context) : Dialog // using parentFragmentManager is important here shareDialog.show(parentFragmentManager, "ShareDialog") } - else -> { - dialog.dismiss() - } } } .show() diff --git a/app/src/main/java/com/github/libretube/util/PipedApi.kt b/app/src/main/java/com/github/libretube/util/PipedApi.kt index 85b3dc716..82b8c67aa 100644 --- a/app/src/main/java/com/github/libretube/util/PipedApi.kt +++ b/app/src/main/java/com/github/libretube/util/PipedApi.kt @@ -120,7 +120,7 @@ interface PipedApi { @POST("import/playlist") suspend fun importPlaylist( @Header("Authorization") token: String, - @Body playlistId: String + @Body playlistId: PlaylistId ): Message @GET("user/playlists") diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f90925c76..aef9e11b1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -200,4 +200,5 @@ Autopause Pause the player when the screen is turned off. Automatically play the next video when the current is finished. + Clone playlist