playlists delete

This commit is contained in:
rimthekid 2022-04-14 11:51:54 -07:00
parent 191b5f6bdd
commit c4accf3fc6
14 changed files with 160 additions and 9 deletions

View File

@ -10,9 +10,15 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.ScrollView import android.widget.ScrollView
import android.widget.TextView import android.widget.TextView
import android.widget.Toast
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.github.libretube.adapters.ChannelAdapter import com.github.libretube.adapters.ChannelAdapter
import com.github.libretube.adapters.PlaylistsAdapter
import com.github.libretube.adapters.SubscriptionAdapter
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException import java.io.IOException
@ -23,6 +29,7 @@ class Library : Fragment() {
private val TAG = "LibraryFragment" private val TAG = "LibraryFragment"
lateinit var token: String lateinit var token: String
lateinit var playlistRecyclerView: RecyclerView lateinit var playlistRecyclerView: RecyclerView
lateinit var refreshLayout: SwipeRefreshLayout
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
arguments?.let { arguments?.let {
@ -41,25 +48,43 @@ class Library : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
playlistRecyclerView = view.findViewById(R.id.playlist_recView) playlistRecyclerView = view.findViewById(R.id.playlist_recView)
playlistRecyclerView.layoutManager = LinearLayoutManager(view.context)
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE) val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
token = sharedPref?.getString("token","")!! token = sharedPref?.getString("token","")!!
if(token!="") { if(token!="") {
refreshLayout = view.findViewById(R.id.playlist_refresh)
view.findViewById<ImageView>(R.id.boogh2).visibility=View.GONE
view.findViewById<TextView>(R.id.textLike2).visibility=View.GONE
fetchPlaylists(view) fetchPlaylists(view)
refreshLayout?.isEnabled = true
refreshLayout?.setOnRefreshListener {
Log.d(TAG,"hmm")
fetchPlaylists(view)
}
} }
} }
private fun fetchPlaylists(view: View){ private fun fetchPlaylists(view: View){
fun run() { fun run() {
refreshLayout?.isRefreshing = true
lifecycleScope.launchWhenCreated { lifecycleScope.launchWhenCreated {
val response = try { val response = try {
RetrofitInstance.api.playlists(token) RetrofitInstance.api.playlists(token)
}catch(e: IOException) { }catch(e: IOException) {
println(e) println(e)
Log.e(TAG, "IOException, you might not have internet connection") Log.e(TAG, "IOException, you might not have internet connection")
Toast.makeText(context,R.string.unknown_error, Toast.LENGTH_SHORT).show()
return@launchWhenCreated return@launchWhenCreated
} catch (e: HttpException) { } catch (e: HttpException) {
Log.e(TAG, "HttpException, unexpected response") Log.e(TAG, "HttpException, unexpected response")
Toast.makeText(context,R.string.server_error, Toast.LENGTH_SHORT).show()
return@launchWhenCreated return@launchWhenCreated
}finally {
refreshLayout?.isRefreshing = false
}
if (response.isNotEmpty()){
val playlistsAdapter = PlaylistsAdapter(response.toMutableList())
playlistRecyclerView.adapter= playlistsAdapter
} }
runOnUiThread { runOnUiThread {

View File

@ -8,6 +8,7 @@ import android.util.Log
import android.view.View import android.view.View
import android.widget.Button import android.widget.Button
import android.widget.EditText import android.widget.EditText
import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
@ -15,6 +16,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.github.libretube.adapters.TrendingAdapter import com.github.libretube.adapters.TrendingAdapter
import com.github.libretube.obj.Login import com.github.libretube.obj.Login
import org.w3c.dom.Text
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException import java.io.IOException
import java.lang.Exception import java.lang.Exception
@ -34,7 +36,10 @@ class LoginDialog : DialogFragment() {
var view: View var view: View
Log.e("dafaq",token!!) Log.e("dafaq",token!!)
if(token!=""){ if(token!=""){
val sharedPref2 = context?.getSharedPreferences("username", Context.MODE_PRIVATE)
val user = sharedPref2?.getString("username","")
view = inflater.inflate(R.layout.dialog_logout, null) view = inflater.inflate(R.layout.dialog_logout, null)
view.findViewById<TextView>(R.id.user).text = view.findViewById<TextView>(R.id.user).text.toString()+" ("+user+")"
view.findViewById<Button>(R.id.logout).setOnClickListener { view.findViewById<Button>(R.id.logout).setOnClickListener {
Toast.makeText(context,R.string.loggedout, Toast.LENGTH_SHORT).show() Toast.makeText(context,R.string.loggedout, Toast.LENGTH_SHORT).show()
val sharedPref = context?.getSharedPreferences("token",Context.MODE_PRIVATE) val sharedPref = context?.getSharedPreferences("token",Context.MODE_PRIVATE)
@ -96,6 +101,11 @@ class LoginDialog : DialogFragment() {
putString("token",response.token) putString("token",response.token)
apply() apply()
} }
val sharedPref2 = context?.getSharedPreferences("username",Context.MODE_PRIVATE)
with (sharedPref2!!.edit()) {
putString("username",login.username)
apply()
}
dialog?.dismiss() dialog?.dismiss()
} }
@ -130,6 +140,11 @@ class LoginDialog : DialogFragment() {
putString("token",response.token) putString("token",response.token)
apply() apply()
} }
val sharedPref2 = context?.getSharedPreferences("username",Context.MODE_PRIVATE)
with (sharedPref2!!.edit()) {
putString("username",login.username)
apply()
}
dialog?.dismiss() dialog?.dismiss()
} }

View File

@ -53,11 +53,14 @@ interface PipedApi {
suspend fun unsubscribe(@Header("Authorization") token: String, @Body subscribe: Subscribe): Message suspend fun unsubscribe(@Header("Authorization") token: String, @Body subscribe: Subscribe): Message
@POST("import") @POST("import")
suspend fun importSubscriptions(@Header("Authorization") token: String, @Body channels: List<String>): Message suspend fun importSubscriptions(@Query("override") override: String, @Header("Authorization") token: String, @Body channels: List<String>): Message
@GET("user/playlists") @GET("user/playlists")
suspend fun playlists(@Header("Authorization") token: String): List<Playlists> suspend fun playlists(@Header("Authorization") token: String): List<Playlists>
@POST("user/playlists/delete")
suspend fun deletePlaylist(@Header("Authorization") token: String, @Body playlistId: PlaylistId): Message
//only for fetching servers list //only for fetching servers list
@GET @GET
suspend fun getInstances(@Url url: String): List<Instances> suspend fun getInstances(@Url url: String): List<Instances>

View File

@ -334,6 +334,7 @@ class PlayerFragment : Fragment() {
exoPlayer.prepare() exoPlayer.prepare()
exoPlayer.play() exoPlayer.play()
view.findViewById<TextView>(R.id.title_textView).text = response.title
view.findViewById<TextView>(R.id.player_title).text = response.title view.findViewById<TextView>(R.id.player_title).text = response.title
view.findViewById<TextView>(R.id.player_description).text = response.description view.findViewById<TextView>(R.id.player_description).text = response.description

View File

@ -1,22 +1,37 @@
package com.github.libretube.adapters package com.github.libretube.adapters
import android.content.Context
import android.media.Image
import android.os.Bundle import android.os.Bundle
import android.text.format.DateUtils import android.text.format.DateUtils
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.blankj.utilcode.util.ThreadUtils.runOnUiThread
import com.github.libretube.*
import com.github.libretube.obj.PlaylistId
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import com.github.libretube.PlayerFragment
import com.github.libretube.R
import com.github.libretube.obj.StreamItem import com.github.libretube.obj.StreamItem
import com.github.libretube.formatShort
import com.github.libretube.obj.Playlists import com.github.libretube.obj.Playlists
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import retrofit2.HttpException
import java.io.IOException
class PlaylistsAdapter(private val playlists: MutableList<Playlists>): RecyclerView.Adapter<PlaylistsViewHolder>() { class PlaylistsAdapter(private val playlists: MutableList<Playlists>): RecyclerView.Adapter<PlaylistsViewHolder>() {
val TAG = "PlaylistsAdapter"
override fun getItemCount(): Int { override fun getItemCount(): Int {
return playlists.size return playlists.size
} }
@ -33,10 +48,62 @@ class PlaylistsAdapter(private val playlists: MutableList<Playlists>): RecyclerV
override fun onBindViewHolder(holder: PlaylistsViewHolder, position: Int) { override fun onBindViewHolder(holder: PlaylistsViewHolder, position: Int) {
val playlist = playlists[position] val playlist = playlists[position]
val thumbnailImage = holder.v.findViewById<ImageView>(R.id.playlist_thumbnail)
Picasso.get().load(playlist.thumbnail).into(thumbnailImage)
holder.v.findViewById<TextView>(R.id.playlist_title).text = playlist.name
holder.v.findViewById<ImageView>(R.id.delete_playlist).setOnClickListener {
val builder = AlertDialog.Builder(holder.v.context)
builder.setTitle("Androidly Alert")
builder.setMessage("We have a message")
builder.setPositiveButton(R.string.yes) { dialog, which ->
val sharedPref = holder.v.context.getSharedPreferences("token", Context.MODE_PRIVATE)
val token = sharedPref?.getString("token","")!!
deletePlaylist(playlist.id!!, token, position)
}
builder.setNegativeButton(R.string.cancel) { dialog, which ->
}
builder.show()
}
holder.v.setOnClickListener {
//playlists clicked
val activity = holder.v.context as MainActivity
val bundle = bundleOf("playlist_id" to playlist.id)
activity.navController.navigate(R.id.playlistFragment,bundle)
}
}
private fun deletePlaylist(id: String, token: String, position: Int) {
fun run() {
GlobalScope.launch{
val response = try {
RetrofitInstance.api.deletePlaylist(token, PlaylistId(id))
}catch(e: IOException) {
println(e)
Log.e(TAG, "IOException, you might not have internet connection")
return@launch
} catch (e: HttpException) {
Log.e(TAG, "HttpException, unexpected response")
return@launch
}finally {
}
try{
if(response.message == "ok"){
Log.d(TAG,"deleted!")
playlists.removeAt(position)
runOnUiThread{notifyDataSetChanged()}
}
}catch (e:Exception){
Log.e(TAG,e.toString())
}
}
}
run()
} }
} }
class PlaylistsViewHolder(val v: View): RecyclerView.ViewHolder(v){ class PlaylistsViewHolder(val v: View): RecyclerView.ViewHolder(v){
init { init {
} }
} }

View File

@ -1,5 +1,8 @@
package com.github.libretube.obj package com.github.libretube.obj
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties(ignoreUnknown = true)
data class Channel( data class Channel(
var id: String? = null, var id: String? = null,
var name: String? = null, var name: String? = null,

View File

@ -1,5 +1,8 @@
package com.github.libretube.obj package com.github.libretube.obj
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties(ignoreUnknown = true)
data class ChapterSegment( data class ChapterSegment(
var title: String?, var title: String?,
var image: String?, var image: String?,

View File

@ -1,5 +1,8 @@
package com.github.libretube.obj package com.github.libretube.obj
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties(ignoreUnknown = true)
data class Instances( data class Instances(
var name: String? = null, var name: String? = null,
var api_url: String? = null, var api_url: String? = null,

View File

@ -1,5 +1,8 @@
package com.github.libretube.obj package com.github.libretube.obj
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties(ignoreUnknown = true)
data class Login( data class Login(
val username: String? = null, val username: String? = null,
val password: String? = null val password: String? = null

View File

@ -0,0 +1,9 @@
package com.github.libretube.obj
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties(ignoreUnknown = true)
data class PlaylistId(
var playlistId: String? = null,
var videoId: String? = null,
)

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2L18,7L6,7v12zM8,9h8v10L8,19L8,9zM15.5,4l-1,-1h-5l-1,1L5,4v2h14L19,4z"/>
</vector>

View File

@ -12,6 +12,7 @@
android:contentDescription="@string/app_name" /> android:contentDescription="@string/app_name" />
<TextView <TextView
android:id="@+id/user"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/already_logged_in" android:text="@string/already_logged_in"

View File

@ -42,7 +42,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:text="TextView" android:text="TextView"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toStartOf="@+id/delete_playlist"
app:layout_constraintStart_toEndOf="@+id/card_playlist_thumbnail" app:layout_constraintStart_toEndOf="@+id/card_playlist_thumbnail"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
@ -55,5 +55,13 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/card_playlist_thumbnail" app:layout_constraintStart_toEndOf="@+id/card_playlist_thumbnail"
app:layout_constraintTop_toBottomOf="@+id/playlist_title" /> app:layout_constraintTop_toBottomOf="@+id/playlist_title" />
<ImageView
android:id="@+id/delete_playlist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_delete"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:background="?android:attr/selectableItemBackground"
/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,5 +1,5 @@
<resources> <resources>
<string name="hello_blank_fragment">Hello blank fragment</string> <string name="yes">Yes</string>
<string name="choose_quality_dialog">Choose Quality:</string> <string name="choose_quality_dialog">Choose Quality:</string>
<string name="search_hint">Search</string> <string name="search_hint">Search</string>
<string name="subscribe">SUBSCRIBE</string> <string name="subscribe">SUBSCRIBE</string>
@ -22,7 +22,7 @@
<string name="customInstance">Add a custom instance</string> <string name="customInstance">Add a custom instance</string>
<string name="region">Choose a region</string> <string name="region">Choose a region</string>
<string name="login_register">Login/Register</string> <string name="login_register">Login/Register</string>
<string name="please_login">Please Login or Register from the settings to show your Subscriptions!</string> <string name="please_login">Please Login or Register in the settings First!</string>
<string name="importsuccess">Subscribed successfully!</string> <string name="importsuccess">Subscribed successfully!</string>
<string name="subscribeIsEmpty">Subscribe to some channels first!</string> <string name="subscribeIsEmpty">Subscribe to some channels first!</string>
<string name="cannotDownload">Can\'t Download this stream!</string> <string name="cannotDownload">Can\'t Download this stream!</string>