resultLauncher) {
-        DialogUtil.showAlertDialog(activity, activity.getString(R.string.location_permission_title),
-            activity.getString(R.string.in_app_camera_location_permission_rationale),
-            activity.getString(android.R.string.ok),
-            activity.getString(android.R.string.cancel),
-            () -> {
-                createDialogsAndHandleLocationPermissions(activity,
-                    inAppCameraLocationPermissionLauncher, resultLauncher);
-            },
-            () -> locationPermissionCallback.onLocationPermissionDenied(
-                activity.getString(R.string.in_app_camera_location_permission_denied)),
-            null,
-            false);
-    }
-
-    /**
-     * Suggest user to attach location information with pictures. If the user selects "Yes", then:
-     * 
-     * Location is taken from the EXIF if the default camera application does not redact location
-     * tags.
-     * 
-     * Otherwise, if the EXIF metadata does not have location information, then location captured by
-     * the app is used
-     *
-     * @param activity
-     */
-    private void askUserToAllowLocationAccess(Activity activity,
-        ActivityResultLauncher inAppCameraLocationPermissionLauncher,
-        ActivityResultLauncher resultLauncher) {
-        DialogUtil.showAlertDialog(activity,
-            activity.getString(R.string.in_app_camera_location_permission_title),
-            activity.getString(R.string.in_app_camera_location_access_explanation),
-            activity.getString(R.string.option_allow),
-            activity.getString(R.string.option_dismiss),
-            () -> {
-                defaultKvStore.putBoolean("inAppCameraLocationPref", true);
-                createDialogsAndHandleLocationPermissions(activity,
-                    inAppCameraLocationPermissionLauncher, resultLauncher);
-            },
-            () -> {
-                ViewUtil.showLongToast(activity, R.string.in_app_camera_location_permission_denied);
-                defaultKvStore.putBoolean("inAppCameraLocationPref", false);
-                initiateCameraUpload(activity, resultLauncher);
-            },
-            null,
-            true);
-    }
-
-    /**
-     * Initiate gallery picker
-     */
-    public void initiateGalleryPick(final Activity activity, ActivityResultLauncher resultLauncher, final boolean allowMultipleUploads) {
-        initiateGalleryUpload(activity, resultLauncher, allowMultipleUploads);
-    }
-
-    /**
-     * Initiate gallery picker with permission
-     */
-    public void initiateCustomGalleryPickWithPermission(final Activity activity, ActivityResultLauncher resultLauncher) {
-        setPickerConfiguration(activity, true);
-
-        PermissionUtils.checkPermissionsAndPerformAction(activity,
-            () -> FilePicker.openCustomSelector(activity, resultLauncher, 0),
-            R.string.storage_permission_title,
-            R.string.write_storage_permission_rationale,
-            PermissionUtils.PERMISSIONS_STORAGE);
-    }
-
-
-    /**
-     * Open chooser for gallery uploads
-     */
-    private void initiateGalleryUpload(final Activity activity, ActivityResultLauncher resultLauncher,
-        final boolean allowMultipleUploads) {
-        setPickerConfiguration(activity, allowMultipleUploads);
-        FilePicker.openGallery(activity, resultLauncher, 0, isDocumentPhotoPickerPreferred());
-    }
-
-    /**
-     * Sets configuration for file picker
-     */
-    private void setPickerConfiguration(Activity activity,
-        boolean allowMultipleUploads) {
-        boolean copyToExternalStorage = defaultKvStore.getBoolean("useExternalStorage", true);
-        FilePicker.configuration(activity)
-            .setCopyTakenPhotosToPublicGalleryAppFolder(copyToExternalStorage)
-            .setAllowMultiplePickInGallery(allowMultipleUploads);
-    }
-
-    /**
-     * Initiate camera upload by opening camera
-     */
-    private void initiateCameraUpload(Activity activity, ActivityResultLauncher resultLauncher) {
-        setPickerConfiguration(activity, false);
-        if (defaultKvStore.getBoolean("inAppCameraLocationPref", false)) {
-            locationBeforeImageCapture = locationManager.getLastLocation();
-        }
-        isInAppCameraUpload = true;
-        FilePicker.openCameraForImage(activity, resultLauncher, 0);
-    }
-
-    private boolean isDocumentPhotoPickerPreferred(){
-        return defaultKvStore.getBoolean(
-            "openDocumentPhotoPickerPref", true);
-    }
-
-    public void onPictureReturnedFromGallery(ActivityResult result, Activity activity, FilePicker.Callbacks callbacks){
-
-        if(isDocumentPhotoPickerPreferred()){
-            FilePicker.onPictureReturnedFromDocuments(result, activity, callbacks);
-        } else {
-            FilePicker.onPictureReturnedFromGallery(result, activity, callbacks);
-        }
-    }
-
-    public void onPictureReturnedFromCustomSelector(ActivityResult result, Activity activity, @NonNull FilePicker.Callbacks callbacks) {
-        FilePicker.onPictureReturnedFromCustomSelector(result, activity, callbacks);
-    }
-
-    public void onPictureReturnedFromCamera(ActivityResult result, Activity activity, @NonNull FilePicker.Callbacks callbacks) {
-        FilePicker.onPictureReturnedFromCamera(result, activity, callbacks);
-    }
-
-    /**
-     * Attaches callback for file picker.
-     */
-    public void handleActivityResultWithCallback(Activity activity, FilePicker.HandleActivityResult handleActivityResult) {
-
-        handleActivityResult.onHandleActivityResult(new DefaultCallback() {
-
-                @Override
-                public void onCanceled(final ImageSource source, final int type) {
-                    super.onCanceled(source, type);
-                    defaultKvStore.remove(PLACE_OBJECT);
-                }
-
-                @Override
-                public void onImagePickerError(Exception e, FilePicker.ImageSource source,
-                    int type) {
-                    ViewUtil.showShortToast(activity, R.string.error_occurred_in_picking_images);
-                }
-
-                @Override
-                public void onImagesPicked(@NonNull List imagesFiles,
-                    FilePicker.ImageSource source, int type) {
-                    Intent intent = handleImagesPicked(activity, imagesFiles);
-                    activity.startActivity(intent);
-                }
-            });
-    }
-
-    public List handleExternalImagesPicked(Activity activity,
-        Intent data) {
-        return FilePicker.handleExternalImagesPicked(data, activity);
-    }
-
-    /**
-     * Returns intent to be passed to upload activity Attaches place object for nearby uploads and
-     * location before image capture if in-app camera is used
-     */
-    private Intent handleImagesPicked(Context context,
-        List imagesFiles) {
-        Intent shareIntent = new Intent(context, UploadActivity.class);
-        shareIntent.setAction(ACTION_INTERNAL_UPLOADS);
-        shareIntent
-            .putParcelableArrayListExtra(UploadActivity.EXTRA_FILES, new ArrayList<>(imagesFiles));
-        Place place = defaultKvStore.getJson(PLACE_OBJECT, Place.class);
-
-        if (place != null) {
-            shareIntent.putExtra(PLACE_OBJECT, place);
-        }
-
-        if (locationBeforeImageCapture != null) {
-            shareIntent.putExtra(
-                UploadActivity.LOCATION_BEFORE_IMAGE_CAPTURE,
-                locationBeforeImageCapture);
-        }
-
-        shareIntent.putExtra(
-            UploadActivity.IN_APP_CAMERA_UPLOAD,
-            isInAppCameraUpload
-        );
-        isInAppCameraUpload = false;    // reset the flag for next use
-        return shareIntent;
-    }
-
-    /**
-     * Fetches the contributions with the state "IN_PROGRESS", "QUEUED" and "PAUSED" and then it
-     * populates the `pendingContributionList`.
-     **/
-    void getPendingContributions() {
-        final PagedList.Config pagedListConfig =
-            (new PagedList.Config.Builder())
-                .setPrefetchDistance(50)
-                .setPageSize(10).build();
-        Factory factory;
-        factory = repository.fetchContributionsWithStates(
-            Arrays.asList(Contribution.STATE_IN_PROGRESS, Contribution.STATE_QUEUED,
-                Contribution.STATE_PAUSED));
-
-        LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(factory,
-            pagedListConfig);
-        pendingContributionList = livePagedListBuilder.build();
-    }
-
-    /**
-     * Fetches the contributions with the state "FAILED" and populates the
-     * `failedContributionList`.
-     **/
-    void getFailedContributions() {
-        final PagedList.Config pagedListConfig =
-            (new PagedList.Config.Builder())
-                .setPrefetchDistance(50)
-                .setPageSize(10).build();
-        Factory factory;
-        factory = repository.fetchContributionsWithStates(
-            Collections.singletonList(Contribution.STATE_FAILED));
-
-        LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(factory,
-            pagedListConfig);
-        failedContributionList = livePagedListBuilder.build();
-    }
-
-    /**
-     * Temporarily disabled, see issue [https://github.com/commons-app/apps-android-commons/issues/5847]
-     * Fetches the contributions with the state "IN_PROGRESS", "QUEUED", "PAUSED" and "FAILED" and
-     * then it populates the `failedAndPendingContributionList`.
-     **/
-//    void getFailedAndPendingContributions() {
-//        final PagedList.Config pagedListConfig =
-//            (new PagedList.Config.Builder())
-//                .setPrefetchDistance(50)
-//                .setPageSize(10).build();
-//        Factory factory;
-//        factory = repository.fetchContributionsWithStates(
-//            Arrays.asList(Contribution.STATE_IN_PROGRESS, Contribution.STATE_QUEUED,
-//                Contribution.STATE_PAUSED, Contribution.STATE_FAILED));
-//
-//        LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(factory,
-//            pagedListConfig);
-//        failedAndPendingContributionList = livePagedListBuilder.build();
-//    }
-}
diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.kt b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.kt
new file mode 100644
index 000000000..b9532a12e
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.kt
@@ -0,0 +1,475 @@
+package fr.free.nrw.commons.contributions
+
+import android.Manifest.permission
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.widget.Toast
+import androidx.activity.result.ActivityResult
+import androidx.activity.result.ActivityResultLauncher
+import androidx.lifecycle.LiveData
+import androidx.paging.LivePagedListBuilder
+import androidx.paging.PagedList
+import fr.free.nrw.commons.R
+import fr.free.nrw.commons.filepicker.DefaultCallback
+import fr.free.nrw.commons.filepicker.FilePicker
+import fr.free.nrw.commons.filepicker.FilePicker.HandleActivityResult
+import fr.free.nrw.commons.filepicker.FilePicker.configuration
+import fr.free.nrw.commons.filepicker.FilePicker.handleExternalImagesPicked
+import fr.free.nrw.commons.filepicker.FilePicker.onPictureReturnedFromDocuments
+import fr.free.nrw.commons.filepicker.FilePicker.openCameraForImage
+import fr.free.nrw.commons.filepicker.FilePicker.openCustomSelector
+import fr.free.nrw.commons.filepicker.FilePicker.openGallery
+import fr.free.nrw.commons.filepicker.UploadableFile
+import fr.free.nrw.commons.kvstore.JsonKvStore
+import fr.free.nrw.commons.location.LatLng
+import fr.free.nrw.commons.location.LocationPermissionsHelper
+import fr.free.nrw.commons.location.LocationPermissionsHelper.LocationPermissionCallback
+import fr.free.nrw.commons.location.LocationServiceManager
+import fr.free.nrw.commons.nearby.Place
+import fr.free.nrw.commons.upload.UploadActivity
+import fr.free.nrw.commons.utils.DialogUtil.showAlertDialog
+import fr.free.nrw.commons.utils.PermissionUtils.PERMISSIONS_STORAGE
+import fr.free.nrw.commons.utils.PermissionUtils.checkPermissionsAndPerformAction
+import fr.free.nrw.commons.utils.ViewUtil.showLongToast
+import fr.free.nrw.commons.utils.ViewUtil.showShortToast
+import fr.free.nrw.commons.wikidata.WikidataConstants.PLACE_OBJECT
+import java.util.Arrays
+import javax.inject.Inject
+import javax.inject.Named
+import javax.inject.Singleton
+
+@Singleton
+class ContributionController @Inject constructor(@param:Named("default_preferences") private val defaultKvStore: JsonKvStore) {
+    private var locationBeforeImageCapture: LatLng? = null
+    private var isInAppCameraUpload = false
+    @JvmField
+    var locationPermissionCallback: LocationPermissionCallback? = null
+    private var locationPermissionsHelper: LocationPermissionsHelper? = null
+
+    // Temporarily disabled, see issue [https://github.com/commons-app/apps-android-commons/issues/5847]
+    // LiveData> failedAndPendingContributionList;
+    @JvmField
+    var pendingContributionList: LiveData>? = null
+    @JvmField
+    var failedContributionList: LiveData>? = null
+
+    @JvmField
+    @Inject
+    var locationManager: LocationServiceManager? = null
+
+    @JvmField
+    @Inject
+    var repository: ContributionsRepository? = null
+
+    /**
+     * Check for permissions and initiate camera click
+     */
+    fun initiateCameraPick(
+        activity: Activity,
+        inAppCameraLocationPermissionLauncher: ActivityResultLauncher>,
+        resultLauncher: ActivityResultLauncher
+    ) {
+        val useExtStorage = defaultKvStore.getBoolean("useExternalStorage", true)
+        if (!useExtStorage) {
+            initiateCameraUpload(activity, resultLauncher)
+            return
+        }
+
+        checkPermissionsAndPerformAction(
+            activity,
+            {
+                if (defaultKvStore.getBoolean("inAppCameraFirstRun")) {
+                    defaultKvStore.putBoolean("inAppCameraFirstRun", false)
+                    askUserToAllowLocationAccess(
+                        activity,
+                        inAppCameraLocationPermissionLauncher,
+                        resultLauncher
+                    )
+                } else if (defaultKvStore.getBoolean("inAppCameraLocationPref")) {
+                    createDialogsAndHandleLocationPermissions(
+                        activity,
+                        inAppCameraLocationPermissionLauncher, resultLauncher
+                    )
+                } else {
+                    initiateCameraUpload(activity, resultLauncher)
+                }
+            },
+            R.string.storage_permission_title,
+            R.string.write_storage_permission_rationale,
+            *PERMISSIONS_STORAGE
+        )
+    }
+
+    /**
+     * Asks users to provide location access
+     *
+     * @param activity
+     */
+    private fun createDialogsAndHandleLocationPermissions(
+        activity: Activity,
+        inAppCameraLocationPermissionLauncher: ActivityResultLauncher>?,
+        resultLauncher: ActivityResultLauncher
+    ) {
+        locationPermissionCallback = object : LocationPermissionCallback {
+            override fun onLocationPermissionDenied(toastMessage: String) {
+                Toast.makeText(
+                    activity,
+                    toastMessage,
+                    Toast.LENGTH_LONG
+                ).show()
+                initiateCameraUpload(activity, resultLauncher)
+            }
+
+            override fun onLocationPermissionGranted() {
+                if (!locationPermissionsHelper!!.isLocationAccessToAppsTurnedOn()) {
+                    showLocationOffDialog(
+                        activity, R.string.in_app_camera_needs_location,
+                        R.string.in_app_camera_location_unavailable, resultLauncher
+                    )
+                } else {
+                    initiateCameraUpload(activity, resultLauncher)
+                }
+            }
+        }
+
+        locationPermissionsHelper = LocationPermissionsHelper(
+            activity, locationManager!!, locationPermissionCallback
+        )
+        inAppCameraLocationPermissionLauncher?.launch(
+            arrayOf(permission.ACCESS_FINE_LOCATION)
+        )
+    }
+
+    /**
+     * Shows a dialog alerting the user about location services being off and asking them to turn it
+     * on
+     * TODO: Add a seperate callback in LocationPermissionsHelper for this.
+     * Ref: https://github.com/commons-app/apps-android-commons/pull/5494/files#r1510553114
+     *
+     * @param activity           Activity reference
+     * @param dialogTextResource Resource id of text to be shown in dialog
+     * @param toastTextResource  Resource id of text to be shown in toast
+     * @param resultLauncher
+     */
+    private fun showLocationOffDialog(
+        activity: Activity, dialogTextResource: Int,
+        toastTextResource: Int, resultLauncher: ActivityResultLauncher
+    ) {
+        showAlertDialog(activity,
+            activity.getString(R.string.ask_to_turn_location_on),
+            activity.getString(dialogTextResource),
+            activity.getString(R.string.title_app_shortcut_setting),
+            activity.getString(R.string.cancel),
+            { locationPermissionsHelper!!.openLocationSettings(activity) },
+            {
+                Toast.makeText(
+                    activity, activity.getString(toastTextResource),
+                    Toast.LENGTH_LONG
+                ).show()
+                initiateCameraUpload(activity, resultLauncher)
+            }
+        )
+    }
+
+    fun handleShowRationaleFlowCameraLocation(
+        activity: Activity,
+        inAppCameraLocationPermissionLauncher: ActivityResultLauncher>?,
+        resultLauncher: ActivityResultLauncher
+    ) {
+        showAlertDialog(
+            activity, activity.getString(R.string.location_permission_title),
+            activity.getString(R.string.in_app_camera_location_permission_rationale),
+            activity.getString(R.string.ok),
+            activity.getString(R.string.cancel),
+            {
+                createDialogsAndHandleLocationPermissions(
+                    activity,
+                    inAppCameraLocationPermissionLauncher, resultLauncher
+                )
+            },
+            {
+                locationPermissionCallback!!.onLocationPermissionDenied(
+                    activity.getString(R.string.in_app_camera_location_permission_denied)
+                )
+            },
+            null
+        )
+    }
+
+    /**
+     * Suggest user to attach location information with pictures. If the user selects "Yes", then:
+     *
+     *
+     * Location is taken from the EXIF if the default camera application does not redact location
+     * tags.
+     *
+     *
+     * Otherwise, if the EXIF metadata does not have location information, then location captured by
+     * the app is used
+     *
+     * @param activity
+     */
+    private fun askUserToAllowLocationAccess(
+        activity: Activity,
+        inAppCameraLocationPermissionLauncher: ActivityResultLauncher>,
+        resultLauncher: ActivityResultLauncher
+    ) {
+        showAlertDialog(
+            activity,
+            activity.getString(R.string.in_app_camera_location_permission_title),
+            activity.getString(R.string.in_app_camera_location_access_explanation),
+            activity.getString(R.string.option_allow),
+            activity.getString(R.string.option_dismiss),
+            {
+                defaultKvStore.putBoolean("inAppCameraLocationPref", true)
+                createDialogsAndHandleLocationPermissions(
+                    activity,
+                    inAppCameraLocationPermissionLauncher, resultLauncher
+                )
+            },
+            {
+                showLongToast(activity, R.string.in_app_camera_location_permission_denied)
+                defaultKvStore.putBoolean("inAppCameraLocationPref", false)
+                initiateCameraUpload(activity, resultLauncher)
+            },
+            null
+        )
+    }
+
+    /**
+     * Initiate gallery picker
+     */
+    fun initiateGalleryPick(
+        activity: Activity,
+        resultLauncher: ActivityResultLauncher,
+        allowMultipleUploads: Boolean
+    ) {
+        initiateGalleryUpload(activity, resultLauncher, allowMultipleUploads)
+    }
+
+    /**
+     * Initiate gallery picker with permission
+     */
+    fun initiateCustomGalleryPickWithPermission(
+        activity: Activity,
+        resultLauncher: ActivityResultLauncher,
+        singleSelection: Boolean = false
+    ) {
+        setPickerConfiguration(activity, true)
+
+        checkPermissionsAndPerformAction(
+            activity,
+            { FilePicker.openCustomSelector(activity, resultLauncher, 0, singleSelection) },
+            R.string.storage_permission_title,
+            R.string.write_storage_permission_rationale,
+            *PERMISSIONS_STORAGE
+        )
+    }
+
+
+    /**
+     * Open chooser for gallery uploads
+     */
+    private fun initiateGalleryUpload(
+        activity: Activity, resultLauncher: ActivityResultLauncher,
+        allowMultipleUploads: Boolean
+    ) {
+        setPickerConfiguration(activity, allowMultipleUploads)
+        openGallery(activity, resultLauncher, 0, isDocumentPhotoPickerPreferred)
+    }
+
+    /**
+     * Sets configuration for file picker
+     */
+    private fun setPickerConfiguration(
+        activity: Activity,
+        allowMultipleUploads: Boolean
+    ) {
+        val copyToExternalStorage = defaultKvStore.getBoolean("useExternalStorage", true)
+        configuration(activity)
+            .setCopyTakenPhotosToPublicGalleryAppFolder(copyToExternalStorage)
+            .setAllowMultiplePickInGallery(allowMultipleUploads)
+    }
+
+    /**
+     * Initiate camera upload by opening camera
+     */
+    private fun initiateCameraUpload(
+        activity: Activity,
+        resultLauncher: ActivityResultLauncher
+    ) {
+        setPickerConfiguration(activity, false)
+        if (defaultKvStore.getBoolean("inAppCameraLocationPref", false)) {
+            locationBeforeImageCapture = locationManager!!.getLastLocation()
+        }
+        isInAppCameraUpload = true
+        openCameraForImage(activity, resultLauncher, 0)
+    }
+
+    private val isDocumentPhotoPickerPreferred: Boolean
+        get() = defaultKvStore.getBoolean(
+            "openDocumentPhotoPickerPref", true
+        )
+
+    fun onPictureReturnedFromGallery(
+        result: ActivityResult,
+        activity: Activity,
+        callbacks: FilePicker.Callbacks
+    ) {
+        if (isDocumentPhotoPickerPreferred) {
+            onPictureReturnedFromDocuments(result, activity, callbacks)
+        } else {
+            FilePicker.onPictureReturnedFromGallery(result, activity, callbacks)
+        }
+    }
+
+    fun onPictureReturnedFromCustomSelector(
+        result: ActivityResult,
+        activity: Activity,
+        callbacks: FilePicker.Callbacks
+    ) {
+        FilePicker.onPictureReturnedFromCustomSelector(result, activity, callbacks)
+    }
+
+    fun onPictureReturnedFromCamera(
+        result: ActivityResult,
+        activity: Activity,
+        callbacks: FilePicker.Callbacks
+    ) {
+        FilePicker.onPictureReturnedFromCamera(result, activity, callbacks)
+    }
+
+    /**
+     * Attaches callback for file picker.
+     */
+    fun handleActivityResultWithCallback(
+        activity: Activity,
+        handleActivityResult: HandleActivityResult
+    ) {
+        handleActivityResult.onHandleActivityResult(object : DefaultCallback() {
+            override fun onCanceled(source: FilePicker.ImageSource, type: Int) {
+                super.onCanceled(source, type)
+                defaultKvStore.remove(PLACE_OBJECT)
+            }
+
+            override fun onImagePickerError(
+                e: Exception, source: FilePicker.ImageSource,
+                type: Int
+            ) {
+                showShortToast(activity, R.string.error_occurred_in_picking_images)
+            }
+
+            override fun onImagesPicked(
+                imagesFiles: List,
+                source: FilePicker.ImageSource, type: Int
+            ) {
+                val intent = handleImagesPicked(activity, imagesFiles)
+                activity.startActivity(intent)
+            }
+        })
+    }
+
+    fun handleExternalImagesPicked(
+        activity: Activity,
+        data: Intent?
+    ): List {
+        return handleExternalImagesPicked(data, activity)
+    }
+
+    /**
+     * Returns intent to be passed to upload activity Attaches place object for nearby uploads and
+     * location before image capture if in-app camera is used
+     */
+    private fun handleImagesPicked(
+        context: Context,
+        imagesFiles: List
+    ): Intent {
+        val shareIntent = Intent(context, UploadActivity::class.java)
+        shareIntent.setAction(ACTION_INTERNAL_UPLOADS)
+        shareIntent
+            .putParcelableArrayListExtra(UploadActivity.EXTRA_FILES, ArrayList(imagesFiles))
+        val place = defaultKvStore.getJson(PLACE_OBJECT, Place::class.java)
+
+        if (place != null) {
+            shareIntent.putExtra(PLACE_OBJECT, place)
+        }
+
+        if (locationBeforeImageCapture != null) {
+            shareIntent.putExtra(
+                UploadActivity.LOCATION_BEFORE_IMAGE_CAPTURE,
+                locationBeforeImageCapture
+            )
+        }
+
+        shareIntent.putExtra(
+            UploadActivity.IN_APP_CAMERA_UPLOAD,
+            isInAppCameraUpload
+        )
+        isInAppCameraUpload = false // reset the flag for next use
+        return shareIntent
+    }
+
+    val pendingContributions: Unit
+        /**
+         * Fetches the contributions with the state "IN_PROGRESS", "QUEUED" and "PAUSED" and then it
+         * populates the `pendingContributionList`.
+         */
+        get() {
+            val pagedListConfig =
+                (PagedList.Config.Builder())
+                    .setPrefetchDistance(50)
+                    .setPageSize(10).build()
+            val factory = repository!!.fetchContributionsWithStates(
+                Arrays.asList(
+                    Contribution.STATE_IN_PROGRESS, Contribution.STATE_QUEUED,
+                    Contribution.STATE_PAUSED
+                )
+            )
+
+            val livePagedListBuilder = LivePagedListBuilder(factory, pagedListConfig)
+            pendingContributionList = livePagedListBuilder.build()
+        }
+
+    val failedContributions: Unit
+        /**
+         * Fetches the contributions with the state "FAILED" and populates the
+         * `failedContributionList`.
+         */
+        get() {
+            val pagedListConfig =
+                (PagedList.Config.Builder())
+                    .setPrefetchDistance(50)
+                    .setPageSize(10).build()
+            val factory = repository!!.fetchContributionsWithStates(
+                listOf(Contribution.STATE_FAILED)
+            )
+
+            val livePagedListBuilder = LivePagedListBuilder(factory, pagedListConfig)
+            failedContributionList = livePagedListBuilder.build()
+        }
+
+    /**
+     * Temporarily disabled, see issue [https://github.com/commons-app/apps-android-commons/issues/5847]
+     * Fetches the contributions with the state "IN_PROGRESS", "QUEUED", "PAUSED" and "FAILED" and
+     * then it populates the `failedAndPendingContributionList`.
+     */
+    //    void getFailedAndPendingContributions() {
+    //        final PagedList.Config pagedListConfig =
+    //            (new PagedList.Config.Builder())
+    //                .setPrefetchDistance(50)
+    //                .setPageSize(10).build();
+    //        Factory factory;
+    //        factory = repository.fetchContributionsWithStates(
+    //            Arrays.asList(Contribution.STATE_IN_PROGRESS, Contribution.STATE_QUEUED,
+    //                Contribution.STATE_PAUSED, Contribution.STATE_FAILED));
+    //
+    //        LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(factory,
+    //            pagedListConfig);
+    //        failedAndPendingContributionList = livePagedListBuilder.build();
+    //    }
+
+    companion object {
+        const val ACTION_INTERNAL_UPLOADS: String = "internalImageUploads"
+    }
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java
deleted file mode 100644
index 2e375145c..000000000
--- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java
+++ /dev/null
@@ -1,145 +0,0 @@
-package fr.free.nrw.commons.contributions;
-
-import android.database.sqlite.SQLiteException;
-import androidx.paging.DataSource;
-import androidx.room.Dao;
-import androidx.room.Delete;
-import androidx.room.Insert;
-import androidx.room.OnConflictStrategy;
-import androidx.room.Query;
-import androidx.room.Transaction;
-import androidx.room.Update;
-import io.reactivex.Completable;
-import io.reactivex.Single;
-import java.util.Calendar;
-import java.util.List;
-import timber.log.Timber;
-
-@Dao
-public abstract class ContributionDao {
-
-    @Query("SELECT * FROM contribution order by media_dateUploaded DESC")
-    abstract DataSource.Factory