Merge branch 'post-context-menu' into 'master'
Delete posts with three-dot "more options" menu See merge request pixeldroid/PixelDroid!238
This commit is contained in:
commit
18df0d030b
@ -107,7 +107,7 @@ interface PixelfedAPI {
|
|||||||
@Path("id") statusId: String
|
@Path("id") statusId: String
|
||||||
) : Call<Status>
|
) : Call<Status>
|
||||||
|
|
||||||
@POST("/api/v1/statuses/{id}/favourited_by")
|
@GET("/api/v1/statuses/{id}/favourited_by")
|
||||||
fun postLikedBy(
|
fun postLikedBy(
|
||||||
@Path("id") statusId: String
|
@Path("id") statusId: String
|
||||||
) : Call<List<Account>>
|
) : Call<List<Account>>
|
||||||
@ -132,6 +132,12 @@ interface PixelfedAPI {
|
|||||||
@Field("language") language : String? = null
|
@Field("language") language : String? = null
|
||||||
) : Call<Status>
|
) : Call<Status>
|
||||||
|
|
||||||
|
@DELETE("/api/v1/statuses/{id}")
|
||||||
|
suspend fun deleteStatus(
|
||||||
|
@Header("Authorization") authorization: String,
|
||||||
|
@Path("id") statusId: String
|
||||||
|
)
|
||||||
|
|
||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
@POST("/api/v1/statuses/{id}/reblog")
|
@POST("/api/v1/statuses/{id}/reblog")
|
||||||
fun reblogStatus(
|
fun reblogStatus(
|
||||||
|
@ -14,4 +14,6 @@ interface FeedContentDao<T: FeedContentDatabase>{
|
|||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
suspend fun insertAll(feedContent: List<T>)
|
suspend fun insertAll(feedContent: List<T>)
|
||||||
|
|
||||||
|
suspend fun delete(id: String, userId: String, instanceUri: String)
|
||||||
|
|
||||||
}
|
}
|
@ -14,4 +14,7 @@ interface NotificationDao: FeedContentDao<Notification> {
|
|||||||
@Query("""SELECT * FROM notifications WHERE user_id=:userId AND instance_uri=:instanceUri
|
@Query("""SELECT * FROM notifications WHERE user_id=:userId AND instance_uri=:instanceUri
|
||||||
ORDER BY CAST(created_at AS FLOAT) DESC""")
|
ORDER BY CAST(created_at AS FLOAT) DESC""")
|
||||||
override fun feedContent(userId: String, instanceUri: String): PagingSource<Int, Notification>
|
override fun feedContent(userId: String, instanceUri: String): PagingSource<Int, Notification>
|
||||||
|
|
||||||
|
@Query("DELETE FROM notifications WHERE user_id=:userId AND instance_uri=:instanceUri AND id=:id")
|
||||||
|
override suspend fun delete(id: String, userId: String, instanceUri: String)
|
||||||
}
|
}
|
@ -15,4 +15,7 @@ interface HomePostDao: FeedContentDao<HomeStatusDatabaseEntity> {
|
|||||||
@Query("DELETE FROM homePosts")
|
@Query("DELETE FROM homePosts")
|
||||||
override suspend fun clearFeedContent()
|
override suspend fun clearFeedContent()
|
||||||
|
|
||||||
|
@Query("DELETE FROM homePosts WHERE user_id=:userId AND instance_uri=:instanceUri AND id=:id")
|
||||||
|
override suspend fun delete(id: String, userId: String, instanceUri: String)
|
||||||
|
|
||||||
}
|
}
|
@ -15,4 +15,7 @@ interface PublicPostDao: FeedContentDao<PublicFeedStatusDatabaseEntity> {
|
|||||||
@Query("DELETE FROM publicPosts")
|
@Query("DELETE FROM publicPosts")
|
||||||
override suspend fun clearFeedContent()
|
override suspend fun clearFeedContent()
|
||||||
|
|
||||||
|
@Query("DELETE FROM publicPosts WHERE user_id=:userId AND instance_uri=:instanceUri AND id=:id")
|
||||||
|
override suspend fun delete(id: String, userId: String, instanceUri: String)
|
||||||
|
|
||||||
}
|
}
|
@ -4,6 +4,7 @@ import android.os.Bundle
|
|||||||
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 androidx.lifecycle.lifecycleScope
|
||||||
import com.h.pixeldroid.R
|
import com.h.pixeldroid.R
|
||||||
import com.h.pixeldroid.objects.Status
|
import com.h.pixeldroid.objects.Status
|
||||||
import com.h.pixeldroid.objects.Status.Companion.DOMAIN_TAG
|
import com.h.pixeldroid.objects.Status.Companion.DOMAIN_TAG
|
||||||
@ -26,17 +27,16 @@ class PostFragment : BaseFragment() {
|
|||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View {
|
||||||
val root: View = inflater.inflate(R.layout.post_fragment, container, false)
|
val root: View = inflater.inflate(R.layout.post_fragment, container, false)
|
||||||
|
|
||||||
val user = db.userDao().getActiveUser()!!
|
val user = db.userDao().getActiveUser()!!
|
||||||
|
|
||||||
val accessToken = user.accessToken
|
|
||||||
val api = apiHolder.api ?: apiHolder.setDomain(user.instance_uri)
|
val api = apiHolder.api ?: apiHolder.setDomain(user.instance_uri)
|
||||||
|
|
||||||
val holder = StatusViewHolder(root)
|
val holder = StatusViewHolder(root)
|
||||||
|
|
||||||
holder.bind(currentStatus, statusDomain, api, "Bearer $accessToken")
|
holder.bind(currentStatus, api, db, lifecycleScope)
|
||||||
|
|
||||||
return root
|
return root
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.h.pixeldroid.fragments
|
package com.h.pixeldroid.fragments
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
|
import android.app.AlertDialog
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
@ -13,6 +14,8 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.lifecycle.LifecycleCoroutineScope
|
||||||
|
import androidx.paging.RemoteMediator
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.viewpager2.widget.ViewPager2
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
import at.connyduck.sparkbutton.SparkButton
|
import at.connyduck.sparkbutton.SparkButton
|
||||||
@ -23,6 +26,9 @@ import com.google.android.material.tabs.TabLayoutMediator
|
|||||||
import com.h.pixeldroid.R
|
import com.h.pixeldroid.R
|
||||||
import com.h.pixeldroid.ReportActivity
|
import com.h.pixeldroid.ReportActivity
|
||||||
import com.h.pixeldroid.api.PixelfedAPI
|
import com.h.pixeldroid.api.PixelfedAPI
|
||||||
|
import com.h.pixeldroid.db.AppDatabase
|
||||||
|
import com.h.pixeldroid.db.entities.HomeStatusDatabaseEntity
|
||||||
|
import com.h.pixeldroid.db.entities.PublicFeedStatusDatabaseEntity
|
||||||
import com.h.pixeldroid.objects.Attachment
|
import com.h.pixeldroid.objects.Attachment
|
||||||
import com.h.pixeldroid.objects.Context
|
import com.h.pixeldroid.objects.Context
|
||||||
import com.h.pixeldroid.objects.Status
|
import com.h.pixeldroid.objects.Status
|
||||||
@ -35,9 +41,12 @@ import com.karumi.dexter.listener.PermissionGrantedResponse
|
|||||||
import com.karumi.dexter.listener.single.BasePermissionListener
|
import com.karumi.dexter.listener.single.BasePermissionListener
|
||||||
import kotlinx.android.synthetic.main.comment.view.*
|
import kotlinx.android.synthetic.main.comment.view.*
|
||||||
import kotlinx.android.synthetic.main.post_fragment.view.*
|
import kotlinx.android.synthetic.main.post_fragment.view.*
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
|
import retrofit2.HttpException
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,14 +79,9 @@ class StatusViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
|||||||
|
|
||||||
private var status: Status? = null
|
private var status: Status? = null
|
||||||
|
|
||||||
init {
|
fun bind(status: Status?, pixelfedAPI: PixelfedAPI, db: AppDatabase, lifecycleScope: LifecycleCoroutineScope) {
|
||||||
itemView.setOnClickListener {
|
|
||||||
//notification?.openActivity()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun bind(status: Status?, instanceUri: String, pixelfedAPI: PixelfedAPI, credential: String) {
|
|
||||||
|
|
||||||
|
this.itemView.visibility = View.VISIBLE
|
||||||
this.status = status
|
this.status = status
|
||||||
|
|
||||||
val metrics = itemView.context.resources.displayMetrics
|
val metrics = itemView.context.resources.displayMetrics
|
||||||
@ -89,9 +93,11 @@ class StatusViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
|||||||
.asDrawable().fitCenter()
|
.asDrawable().fitCenter()
|
||||||
.placeholder(ColorDrawable(Color.GRAY))
|
.placeholder(ColorDrawable(Color.GRAY))
|
||||||
|
|
||||||
setupPost(itemView, picRequest, instanceUri, false)
|
val user = db.userDao().getActiveUser()!!
|
||||||
|
|
||||||
activateButtons(this, pixelfedAPI, credential)
|
setupPost(itemView, picRequest, user.instance_uri, false)
|
||||||
|
|
||||||
|
activateButtons(this, pixelfedAPI, db, lifecycleScope)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,8 +223,10 @@ class StatusViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun activateButtons(holder: StatusViewHolder, api: PixelfedAPI, credential: String){
|
fun activateButtons(holder: StatusViewHolder, api: PixelfedAPI, db: AppDatabase, lifecycleScope: LifecycleCoroutineScope){
|
||||||
|
val user = db.userDao().getActiveUser()!!
|
||||||
|
|
||||||
|
val credential = "Bearer ${user.accessToken}"
|
||||||
//Set the special HTML text
|
//Set the special HTML text
|
||||||
setDescription(holder.view, api, credential)
|
setDescription(holder.view, api, credential)
|
||||||
|
|
||||||
@ -238,7 +246,7 @@ class StatusViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
|||||||
//Activate double tap liking
|
//Activate double tap liking
|
||||||
activateDoubleTapLiker(holder, api, credential)
|
activateDoubleTapLiker(holder, api, credential)
|
||||||
|
|
||||||
activateMoreButton(holder)
|
activateMoreButton(holder, api, db, lifecycleScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun activateReblogger(
|
fun activateReblogger(
|
||||||
@ -326,7 +334,7 @@ class StatusViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun activateMoreButton(holder: StatusViewHolder){
|
fun activateMoreButton(holder: StatusViewHolder, api: PixelfedAPI, db: AppDatabase, lifecycleScope: LifecycleCoroutineScope){
|
||||||
holder.more.setOnClickListener {
|
holder.more.setOnClickListener {
|
||||||
PopupMenu(it.context, it).apply {
|
PopupMenu(it.context, it).apply {
|
||||||
setOnMenuItemClickListener { item ->
|
setOnMenuItemClickListener { item ->
|
||||||
@ -397,6 +405,32 @@ class StatusViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
|||||||
}).check()
|
}).check()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
R.id.post_more_menu_delete -> {
|
||||||
|
val builder = AlertDialog.Builder(holder.itemView.context)
|
||||||
|
builder.apply {
|
||||||
|
setMessage(R.string.delete_dialog)
|
||||||
|
setPositiveButton(R.string.OK) { _, _ ->
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
val user = db.userDao().getActiveUser()!!
|
||||||
|
status?.id?.let { id ->
|
||||||
|
db.homePostDao().delete(id, user.user_id, user.instance_uri)
|
||||||
|
db.publicPostDao().delete(id, user.user_id, user.instance_uri)
|
||||||
|
try {
|
||||||
|
api.deleteStatus("Bearer ${user.accessToken}", id)
|
||||||
|
holder.itemView.visibility = View.GONE
|
||||||
|
} catch (exception: IOException) {
|
||||||
|
} catch (exception: HttpException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setNegativeButton(R.string.cancel) { _, _ -> }
|
||||||
|
show()
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -405,6 +439,10 @@ class StatusViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
|||||||
//make sure to disable image-related things if there aren't any
|
//make sure to disable image-related things if there aren't any
|
||||||
menu.setGroupVisible(R.id.post_more_group_picture, false)
|
menu.setGroupVisible(R.id.post_more_group_picture, false)
|
||||||
}
|
}
|
||||||
|
if(status?.account?.id == db.userDao().getActiveUser()!!.user_id){
|
||||||
|
//make sure to enable deleting post if it's the user's
|
||||||
|
menu.setGroupVisible(R.id.post_more_menu_group_delete, true)
|
||||||
|
}
|
||||||
show()
|
show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.paging.ExperimentalPagingApi
|
import androidx.paging.ExperimentalPagingApi
|
||||||
import androidx.paging.PagingDataAdapter
|
import androidx.paging.PagingDataAdapter
|
||||||
import androidx.paging.RemoteMediator
|
import androidx.paging.RemoteMediator
|
||||||
@ -89,8 +90,7 @@ class PostFeedFragment<T: FeedContentDatabase>: CachedFeedFragment<T>() {
|
|||||||
val uiModel = getItem(position) as Status
|
val uiModel = getItem(position) as Status
|
||||||
uiModel.let {
|
uiModel.let {
|
||||||
val instanceUri = db.userDao().getActiveUser()!!.instance_uri
|
val instanceUri = db.userDao().getActiveUser()!!.instance_uri
|
||||||
val accessToken = db.userDao().getActiveUser()!!.accessToken
|
(holder as StatusViewHolder).bind(it, apiHolder.setDomain(instanceUri), db, lifecycleScope)
|
||||||
(holder as StatusViewHolder).bind(it, instanceUri, apiHolder.setDomain(instanceUri), "Bearer $accessToken")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.paging.ExperimentalPagingApi
|
import androidx.paging.ExperimentalPagingApi
|
||||||
import androidx.paging.PagingDataAdapter
|
import androidx.paging.PagingDataAdapter
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
@ -12,7 +13,6 @@ import androidx.recyclerview.widget.RecyclerView
|
|||||||
import com.h.pixeldroid.R
|
import com.h.pixeldroid.R
|
||||||
import com.h.pixeldroid.fragments.StatusViewHolder
|
import com.h.pixeldroid.fragments.StatusViewHolder
|
||||||
import com.h.pixeldroid.fragments.feeds.uncachedFeeds.*
|
import com.h.pixeldroid.fragments.feeds.uncachedFeeds.*
|
||||||
import com.h.pixeldroid.objects.Account
|
|
||||||
import com.h.pixeldroid.objects.Results
|
import com.h.pixeldroid.objects.Results
|
||||||
import com.h.pixeldroid.objects.Status
|
import com.h.pixeldroid.objects.Status
|
||||||
|
|
||||||
@ -80,8 +80,7 @@ class SearchPostsFragment : UncachedFeedFragment<Status>() {
|
|||||||
val uiModel = getItem(position) as Status
|
val uiModel = getItem(position) as Status
|
||||||
uiModel.let {
|
uiModel.let {
|
||||||
val instanceUri = db.userDao().getActiveUser()!!.instance_uri
|
val instanceUri = db.userDao().getActiveUser()!!.instance_uri
|
||||||
val accessToken = db.userDao().getActiveUser()!!.accessToken
|
(holder as StatusViewHolder).bind(it, apiHolder.setDomain(instanceUri), db, lifecycleScope)
|
||||||
(holder as StatusViewHolder).bind(it, instanceUri, apiHolder.setDomain(instanceUri), "Bearer $accessToken")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,4 +14,14 @@
|
|||||||
<item android:id="@+id/post_more_menu_save_to_gallery"
|
<item android:id="@+id/post_more_menu_save_to_gallery"
|
||||||
android:title="@string/save_to_gallery"/>
|
android:title="@string/save_to_gallery"/>
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
|
<!-- Group that should only be shown if this is the user's post -->
|
||||||
|
<group
|
||||||
|
android:id="@+id/post_more_menu_group_delete"
|
||||||
|
android:visible="false">
|
||||||
|
|
||||||
|
<item android:id="@+id/post_more_menu_delete"
|
||||||
|
android:title="@string/delete"/>
|
||||||
|
|
||||||
|
</group>
|
||||||
</menu>
|
</menu>
|
||||||
|
@ -139,6 +139,10 @@
|
|||||||
<string name="discover">DISCOVER</string>
|
<string name="discover">DISCOVER</string>
|
||||||
<string name="something_went_wrong">Something went wrong…</string>
|
<string name="something_went_wrong">Something went wrong…</string>
|
||||||
<string name="panda_pull_to_refresh_to_try_again">This panda is not happy. Pull to refresh to try again.</string>
|
<string name="panda_pull_to_refresh_to_try_again">This panda is not happy. Pull to refresh to try again.</string>
|
||||||
|
<string name="delete">Delete</string>
|
||||||
|
<string name="OK">OK</string>
|
||||||
|
<string name="delete_dialog">Delete this post?</string>
|
||||||
|
<string name="cancel">Cancel</string>
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user