Added failed uploads fragment

This commit is contained in:
Kanahia 2024-06-09 18:17:37 +05:30
parent 13b4987a54
commit 474c3bc01e
9 changed files with 307 additions and 93 deletions

View file

@ -34,6 +34,7 @@ import fr.free.nrw.commons.profile.achievements.AchievementsFragment;
import fr.free.nrw.commons.profile.leaderboard.LeaderboardFragment;
import fr.free.nrw.commons.review.ReviewImageFragment;
import fr.free.nrw.commons.settings.SettingsFragment;
import fr.free.nrw.commons.upload.FailedUploadsFragment;
import fr.free.nrw.commons.upload.PendingUploadsFragment;
import fr.free.nrw.commons.upload.categories.UploadCategoriesFragment;
import fr.free.nrw.commons.upload.depicts.DepictsFragment;
@ -159,4 +160,7 @@ public abstract class FragmentBuilderModule {
@ContributesAndroidInjector
abstract PendingUploadsFragment bindPendingUploadsFragment();
@ContributesAndroidInjector
abstract FailedUploadsFragment bindFailedUploadsFragment();
}

View file

@ -0,0 +1,75 @@
package fr.free.nrw.commons.upload
import android.net.Uri
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.URLUtil
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.facebook.imagepipeline.request.ImageRequest
import fr.free.nrw.commons.R
import fr.free.nrw.commons.contributions.Contribution
import timber.log.Timber
import java.io.File
class FailedUploadsAdapter(items: List<Contribution>) :
RecyclerView.Adapter<FailedUploadsAdapter.ViewHolder>() {
private val items: List<Contribution> = items
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view: View =
LayoutInflater.from(parent.context).inflate(R.layout.item_failed_upload, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item: Contribution = items[position]
holder.titleTextView.setText(item.media.displayTitle)
var imageRequest: ImageRequest? = null
val imageSource: String = item.localUri.toString()
if (!TextUtils.isEmpty(imageSource)) {
if (URLUtil.isFileUrl(imageSource)) {
imageRequest = ImageRequest.fromUri(Uri.parse(imageSource))!!
} else if (imageSource != null) {
val file = File(imageSource)
imageRequest = ImageRequest.fromFile(file)!!
}
if (imageRequest != null) {
holder.itemImage.setImageRequest(imageRequest)
}
}
if (item.state == Contribution.STATE_FAILED) {
holder.errorTextView.setText("Failed")
holder.errorTextView.visibility = View.VISIBLE
holder.itemProgress.visibility = View.GONE
}
holder.itemImage.setImageRequest(imageRequest)
}
override fun getItemCount(): Int {
return items.size
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var itemImage: com.facebook.drawee.view.SimpleDraweeView =
itemView.findViewById(R.id.itemImage)
var titleTextView: TextView = itemView.findViewById<TextView>(R.id.titleTextView)
var itemProgress: ProgressBar = itemView.findViewById<ProgressBar>(R.id.itemProgress)
var errorTextView: TextView = itemView.findViewById<TextView>(R.id.errorTextView)
var deleteButton: ImageView = itemView.findViewById(R.id.deleteButton)
}
interface Callback {
fun deleteUpload(contribution: Contribution?)
}
}

View file

@ -0,0 +1,133 @@
package fr.free.nrw.commons.upload
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.paging.PagedList
import androidx.recyclerview.widget.LinearLayoutManager
import fr.free.nrw.commons.R
import fr.free.nrw.commons.auth.SessionManager
import fr.free.nrw.commons.contributions.Contribution
import fr.free.nrw.commons.databinding.FragmentFailedUploadsBinding
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment
import fr.free.nrw.commons.media.MediaClient
import fr.free.nrw.commons.profile.ProfileActivity
import org.apache.commons.lang3.StringUtils
import javax.inject.Inject
/**
* A simple [Fragment] subclass.
* Use the [FailedUploadsFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class FailedUploadsFragment : CommonsDaggerSupportFragment(),PendingUploadsContract.View {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
private val ARG_PARAM1 = "param1"
private val ARG_PARAM2 = "param2"
@Inject
lateinit var pendingUploadsPresenter: PendingUploadsPresenter
@Inject
lateinit var mediaClient: MediaClient
@Inject
lateinit var sessionManager: SessionManager
private var userName: String? = null
lateinit var binding: FragmentFailedUploadsBinding
var l = ArrayList<Contribution>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
//Now that we are allowing this fragment to be started for
// any userName- we expect it to be passed as an argument
if (arguments != null) {
userName = requireArguments().getString(ProfileActivity.KEY_USERNAME)
}
if (StringUtils.isEmpty(userName)) {
userName = sessionManager!!.getUserName()
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentFailedUploadsBinding.inflate(layoutInflater)
pendingUploadsPresenter.onAttachView(this)
initRecyclerView()
return binding.root
}
fun initRecyclerView() {
binding.failedUploadsRecyclerView.setLayoutManager(LinearLayoutManager(this.context))
pendingUploadsPresenter!!.setup(
userName,
sessionManager!!.userName == userName
)
pendingUploadsPresenter!!.totalContributionList.observe(
viewLifecycleOwner
) { list: PagedList<Contribution?> ->
l = ArrayList()
list.forEach {
if (it!!.state == Contribution.STATE_FAILED) {
l.add(it)
}
}
if (l.size == 0) {
binding.nofailedTextView.visibility = View.VISIBLE
binding.failedUplaodsLl.visibility = View.GONE
} else {
binding.nofailedTextView.visibility = View.GONE
binding.failedUplaodsLl.visibility = View.VISIBLE
val adapter = FailedUploadsAdapter(l)
binding.failedUploadsRecyclerView.setAdapter(adapter)
}
}
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment FailedUploadsFragment.
*/
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
FailedUploadsFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
override fun showWelcomeTip(numberOfUploads: Boolean) {
//TODO("Not yet implemented")
}
override fun showProgress(shouldShow: Boolean) {
//TODO("Not yet implemented")
}
override fun showNoContributionsUI(shouldShow: Boolean) {
//TODO("Not yet implemented")
}
}

View file

@ -121,7 +121,6 @@ class PendingUploadsFragment : CommonsDaggerSupportFragment(), PendingUploadsCon
x++
}
}
Timber.tag("PRINT").e(l.size.toString())
if (l.size == 0) {
binding.nopendingTextView.visibility = View.VISIBLE
binding.pendingUplaodsLl.visibility = View.GONE

View file

@ -3,22 +3,12 @@ package fr.free.nrw.commons.upload
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.viewpager.widget.ViewPager
import androidx.work.ExistingWorkPolicy
import fr.free.nrw.commons.R
import fr.free.nrw.commons.ViewPagerAdapter
import fr.free.nrw.commons.contributions.Contribution
import fr.free.nrw.commons.databinding.ActivityUploadProgressBinding
import fr.free.nrw.commons.theme.BaseActivity
import fr.free.nrw.commons.upload.fragments.FailedUploadsFragment
import fr.free.nrw.commons.upload.worker.WorkRequestHelper.Companion.makeOneTimeWorkRequest
import fr.free.nrw.commons.utils.NetworkUtils
import fr.free.nrw.commons.utils.ViewUtil
import io.reactivex.functions.Action
import timber.log.Timber
import javax.inject.Inject
class UploadProgressActivity : BaseActivity() {
@ -93,12 +83,9 @@ class UploadProgressActivity : BaseActivity() {
}
fun updateMenuItems(currentPosition: Int) {
menu!!.clear()
if (currentPosition == 0) {
if (isPendingIconsVisible){
menu!!.removeItem(R.id.retry_icon)
menu!!.removeItem(R.id.cancel_icon)
menu!!.removeItem(R.id.pause_icon)
menu!!.removeItem(R.id.resume_icon)
if (!isPaused){
if (menu!!.findItem(R.id.pause_icon) == null) {
menu!!.add(Menu.NONE, R.id.pause_icon, Menu.NONE, "Pause")
@ -127,19 +114,21 @@ class UploadProgressActivity : BaseActivity() {
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
}
}
}else{
menu!!.removeItem(R.id.retry_icon)
menu!!.removeItem(R.id.pause_icon)
menu!!.removeItem(R.id.resume_icon)
menu!!.removeItem(R.id.cancel_icon)
}
} else if (currentPosition == 1) {
menu!!.removeItem(R.id.pause_icon)
if (menu!!.findItem(R.id.retry_icon) == null) {
menu!!.add(Menu.NONE, R.id.retry_icon, Menu.NONE, "Retry")
.setIcon(R.drawable.ic_refresh_white_24dp)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
}
if (menu!!.findItem(R.id.cancel_icon) == null) {
menu!!.add(Menu.NONE, R.id.cancel_icon, Menu.NONE, "Cancel")
.setIcon(android.R.drawable.ic_menu_close_clear_cancel).setOnMenuItemClickListener {
hidePendingIcons()
true
}
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
}
}
}

View file

@ -1,60 +0,0 @@
package fr.free.nrw.commons.upload.fragments
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import fr.free.nrw.commons.R
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [FailedUploadsFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class FailedUploadsFragment : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_failed_uploads, container, false)
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment FailedUploadsFragment.
*/
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
FailedUploadsFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}

View file

@ -1,7 +0,0 @@
package fr.free.nrw.commons.upload.fragments
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER

View file

@ -1,14 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".upload.fragments.FailedUploadsFragment">
android:gravity="center"
android:orientation="vertical"
tools:context=".upload.FailedUploadsFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/nofailedTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="You do not have any failed Uploads!" />
<LinearLayout
android:id="@+id/failedUplaodsLl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
android:layout_marginTop="10dp"
android:orientation="vertical"
android:visibility="gone">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/failed_uploads_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:fresco="http://schemas.android.com/tools"
android:paddingBottom="8dp"
android:gravity="center"
android:orientation="horizontal">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/itemImage"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="?attr/mainBackground"
app:actualImageScaleType="centerCrop"
fresco:placeholderImage="@drawable/ic_image_black_24dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="6dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/titleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24sp"
android:text="RandomTest" />
<ProgressBar
android:id="@+id/itemProgress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/errorTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Queued"
android:visibility="gone" />
</LinearLayout>
<ImageView
android:id="@+id/retryButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dimen_10"
android:src="@drawable/ic_refresh_white_24dp" />
<ImageView
android:id="@+id/deleteButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_menu_close_clear_cancel" />
</LinearLayout>