mirror of
				https://github.com/commons-app/apps-android-commons.git
				synced 2025-10-31 14:53:59 +01:00 
			
		
		
		
	Merge branch 'commons-app:main' into main
This commit is contained in:
		
						commit
						65458ebd54
					
				
					 26 changed files with 407 additions and 487 deletions
				
			
		|  | @ -107,7 +107,6 @@ public class CommonsApplication extends MultiDexApplication { | |||
|     /** | ||||
|      * Constants begin | ||||
|      */ | ||||
|     public static final int OPEN_APPLICATION_DETAIL_SETTINGS = 1001; | ||||
| 
 | ||||
|     public static final String DEFAULT_EDIT_SUMMARY = "Uploaded using [[COM:MOA|Commons Mobile App]]"; | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ import android.view.ViewGroup; | |||
| import androidx.activity.result.ActivityResultCallback; | ||||
| import androidx.activity.result.ActivityResultLauncher; | ||||
| import androidx.activity.result.contract.ActivityResultContracts; | ||||
| import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.recyclerview.widget.LinearLayoutManager; | ||||
|  | @ -33,6 +34,23 @@ public class BookmarkLocationsFragment extends DaggerFragment { | |||
|     @Inject BookmarkLocationsDao bookmarkLocationDao; | ||||
|     @Inject CommonPlaceClickActions commonPlaceClickActions; | ||||
|     private PlaceAdapter adapter; | ||||
| 
 | ||||
|     private final ActivityResultLauncher<Intent> cameraPickLauncherForResult = | ||||
|         registerForActivityResult(new StartActivityForResult(), | ||||
|         result -> { | ||||
|             contributionController.handleActivityResultWithCallback(requireActivity(), callbacks -> { | ||||
|                 contributionController.onPictureReturnedFromCamera(result, requireActivity(), callbacks); | ||||
|             }); | ||||
|         }); | ||||
| 
 | ||||
|       private final ActivityResultLauncher<Intent> galleryPickLauncherForResult = | ||||
|           registerForActivityResult(new StartActivityForResult(), | ||||
|         result -> { | ||||
|               contributionController.handleActivityResultWithCallback(requireActivity(), callbacks -> { | ||||
|                 contributionController.onPictureReturnedFromGallery(result, requireActivity(), callbacks); | ||||
|             }); | ||||
|         }); | ||||
| 
 | ||||
|     private ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() { | ||||
|         @Override | ||||
|         public void onActivityResult(Map<String, Boolean> result) { | ||||
|  | @ -45,7 +63,7 @@ public class BookmarkLocationsFragment extends DaggerFragment { | |||
|                 contributionController.locationPermissionCallback.onLocationPermissionGranted(); | ||||
|             } else { | ||||
|                 if (shouldShowRequestPermissionRationale(permission.ACCESS_FINE_LOCATION)) { | ||||
|                     contributionController.handleShowRationaleFlowCameraLocation(getActivity(), inAppCameraLocationPermissionLauncher); | ||||
|                     contributionController.handleShowRationaleFlowCameraLocation(getActivity(), inAppCameraLocationPermissionLauncher, cameraPickLauncherForResult); | ||||
|                 } else { | ||||
|                     contributionController.locationPermissionCallback.onLocationPermissionDenied(getActivity().getString(R.string.in_app_camera_location_permission_denied)); | ||||
|                 } | ||||
|  | @ -83,7 +101,9 @@ public class BookmarkLocationsFragment extends DaggerFragment { | |||
|                 return Unit.INSTANCE; | ||||
|             }, | ||||
|             commonPlaceClickActions, | ||||
|             inAppCameraLocationPermissionLauncher | ||||
|             inAppCameraLocationPermissionLauncher, | ||||
|             galleryPickLauncherForResult, | ||||
|             cameraPickLauncherForResult | ||||
|         ); | ||||
|         binding.listView.setAdapter(adapter); | ||||
|     } | ||||
|  | @ -109,11 +129,6 @@ public class BookmarkLocationsFragment extends DaggerFragment { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onActivityResult(int requestCode, int resultCode, Intent data) { | ||||
|         contributionController.handleActivityResult(getActivity(), requestCode, resultCode, data); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onDestroy() { | ||||
|         super.onDestroy(); | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ 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.annotation.NonNull; | ||||
| import androidx.lifecycle.LiveData; | ||||
|  | @ -64,10 +65,11 @@ public class ContributionController { | |||
|      * Check for permissions and initiate camera click | ||||
|      */ | ||||
|     public void initiateCameraPick(Activity activity, | ||||
|         ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher) { | ||||
|         ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher, | ||||
|         ActivityResultLauncher<Intent> resultLauncher) { | ||||
|         boolean useExtStorage = defaultKvStore.getBoolean("useExternalStorage", true); | ||||
|         if (!useExtStorage) { | ||||
|             initiateCameraUpload(activity); | ||||
|             initiateCameraUpload(activity, resultLauncher); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|  | @ -75,12 +77,12 @@ public class ContributionController { | |||
|             () -> { | ||||
|                 if (defaultKvStore.getBoolean("inAppCameraFirstRun")) { | ||||
|                     defaultKvStore.putBoolean("inAppCameraFirstRun", false); | ||||
|                     askUserToAllowLocationAccess(activity, inAppCameraLocationPermissionLauncher); | ||||
|                     askUserToAllowLocationAccess(activity, inAppCameraLocationPermissionLauncher, resultLauncher); | ||||
|                 } else if (defaultKvStore.getBoolean("inAppCameraLocationPref")) { | ||||
|                     createDialogsAndHandleLocationPermissions(activity, | ||||
|                         inAppCameraLocationPermissionLauncher); | ||||
|                         inAppCameraLocationPermissionLauncher, resultLauncher); | ||||
|                 } else { | ||||
|                     initiateCameraUpload(activity); | ||||
|                     initiateCameraUpload(activity, resultLauncher); | ||||
|                 } | ||||
|             }, | ||||
|             R.string.storage_permission_title, | ||||
|  | @ -94,7 +96,8 @@ public class ContributionController { | |||
|      * @param activity | ||||
|      */ | ||||
|     private void createDialogsAndHandleLocationPermissions(Activity activity, | ||||
|         ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher) { | ||||
|         ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher, | ||||
|         ActivityResultLauncher<Intent> resultLauncher) { | ||||
|         locationPermissionCallback = new LocationPermissionCallback() { | ||||
|             @Override | ||||
|             public void onLocationPermissionDenied(String toastMessage) { | ||||
|  | @ -103,16 +106,16 @@ public class ContributionController { | |||
|                     toastMessage, | ||||
|                     Toast.LENGTH_LONG | ||||
|                 ).show(); | ||||
|                 initiateCameraUpload(activity); | ||||
|                 initiateCameraUpload(activity, resultLauncher); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void onLocationPermissionGranted() { | ||||
|                 if (!locationPermissionsHelper.isLocationAccessToAppsTurnedOn()) { | ||||
|                     showLocationOffDialog(activity, R.string.in_app_camera_needs_location, | ||||
|                         R.string.in_app_camera_location_unavailable); | ||||
|                         R.string.in_app_camera_location_unavailable, resultLauncher); | ||||
|                 } else { | ||||
|                     initiateCameraUpload(activity); | ||||
|                     initiateCameraUpload(activity, resultLauncher); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | @ -135,9 +138,10 @@ public class ContributionController { | |||
|      * @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 void showLocationOffDialog(Activity activity, int dialogTextResource, | ||||
|         int toastTextResource) { | ||||
|         int toastTextResource, ActivityResultLauncher<Intent> resultLauncher) { | ||||
|         DialogUtil | ||||
|             .showAlertDialog(activity, | ||||
|                 activity.getString(R.string.ask_to_turn_location_on), | ||||
|  | @ -148,20 +152,21 @@ public class ContributionController { | |||
|                 () -> { | ||||
|                     Toast.makeText(activity, activity.getString(toastTextResource), | ||||
|                         Toast.LENGTH_LONG).show(); | ||||
|                     initiateCameraUpload(activity); | ||||
|                     initiateCameraUpload(activity, resultLauncher); | ||||
|                 } | ||||
|             ); | ||||
|     } | ||||
| 
 | ||||
|     public void handleShowRationaleFlowCameraLocation(Activity activity, | ||||
|         ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher) { | ||||
|         ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher, | ||||
|         ActivityResultLauncher<Intent> 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); | ||||
|                     inAppCameraLocationPermissionLauncher, resultLauncher); | ||||
|             }, | ||||
|             () -> locationPermissionCallback.onLocationPermissionDenied( | ||||
|                 activity.getString(R.string.in_app_camera_location_permission_denied)), | ||||
|  | @ -181,7 +186,8 @@ public class ContributionController { | |||
|      * @param activity | ||||
|      */ | ||||
|     private void askUserToAllowLocationAccess(Activity activity, | ||||
|         ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher) { | ||||
|         ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher, | ||||
|         ActivityResultLauncher<Intent> resultLauncher) { | ||||
|         DialogUtil.showAlertDialog(activity, | ||||
|             activity.getString(R.string.in_app_camera_location_permission_title), | ||||
|             activity.getString(R.string.in_app_camera_location_access_explanation), | ||||
|  | @ -190,12 +196,12 @@ public class ContributionController { | |||
|             () -> { | ||||
|                 defaultKvStore.putBoolean("inAppCameraLocationPref", true); | ||||
|                 createDialogsAndHandleLocationPermissions(activity, | ||||
|                     inAppCameraLocationPermissionLauncher); | ||||
|                     inAppCameraLocationPermissionLauncher, resultLauncher); | ||||
|             }, | ||||
|             () -> { | ||||
|                 ViewUtil.showLongToast(activity, R.string.in_app_camera_location_permission_denied); | ||||
|                 defaultKvStore.putBoolean("inAppCameraLocationPref", false); | ||||
|                 initiateCameraUpload(activity); | ||||
|                 initiateCameraUpload(activity, resultLauncher); | ||||
|             }, | ||||
|             null, | ||||
|             true); | ||||
|  | @ -204,18 +210,18 @@ public class ContributionController { | |||
|     /** | ||||
|      * Initiate gallery picker | ||||
|      */ | ||||
|     public void initiateGalleryPick(final Activity activity, final boolean allowMultipleUploads) { | ||||
|         initiateGalleryUpload(activity, allowMultipleUploads); | ||||
|     public void initiateGalleryPick(final Activity activity, ActivityResultLauncher<Intent> resultLauncher, final boolean allowMultipleUploads) { | ||||
|         initiateGalleryUpload(activity, resultLauncher, allowMultipleUploads); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Initiate gallery picker with permission | ||||
|      */ | ||||
|     public void initiateCustomGalleryPickWithPermission(final Activity activity) { | ||||
|     public void initiateCustomGalleryPickWithPermission(final Activity activity, ActivityResultLauncher<Intent> resultLauncher) { | ||||
|         setPickerConfiguration(activity, true); | ||||
| 
 | ||||
|         PermissionUtils.checkPermissionsAndPerformAction(activity, | ||||
|             () -> FilePicker.openCustomSelector(activity, 0), | ||||
|             () -> FilePicker.openCustomSelector(activity, resultLauncher, 0), | ||||
|             R.string.storage_permission_title, | ||||
|             R.string.write_storage_permission_rationale, | ||||
|             PermissionUtils.PERMISSIONS_STORAGE); | ||||
|  | @ -225,12 +231,10 @@ public class ContributionController { | |||
|     /** | ||||
|      * Open chooser for gallery uploads | ||||
|      */ | ||||
|     private void initiateGalleryUpload(final Activity activity, | ||||
|     private void initiateGalleryUpload(final Activity activity, ActivityResultLauncher<Intent> resultLauncher, | ||||
|         final boolean allowMultipleUploads) { | ||||
|         setPickerConfiguration(activity, allowMultipleUploads); | ||||
|         boolean openDocumentIntentPreferred = defaultKvStore.getBoolean( | ||||
|             "openDocumentPhotoPickerPref", true); | ||||
|         FilePicker.openGallery(activity, 0, openDocumentIntentPreferred); | ||||
|         FilePicker.openGallery(activity, resultLauncher, 0, isDocumentPhotoPickerPreferred()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -247,22 +251,43 @@ public class ContributionController { | |||
|     /** | ||||
|      * Initiate camera upload by opening camera | ||||
|      */ | ||||
|     private void initiateCameraUpload(Activity activity) { | ||||
|     private void initiateCameraUpload(Activity activity, ActivityResultLauncher<Intent> resultLauncher) { | ||||
|         setPickerConfiguration(activity, false); | ||||
|         if (defaultKvStore.getBoolean("inAppCameraLocationPref", false)) { | ||||
|             locationBeforeImageCapture = locationManager.getLastLocation(); | ||||
|         } | ||||
|         isInAppCameraUpload = true; | ||||
|         FilePicker.openCameraForImage(activity, 0); | ||||
|         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 handleActivityResult(Activity activity, int requestCode, int resultCode, | ||||
|         Intent data) { | ||||
|         FilePicker.handleActivityResult(requestCode, resultCode, data, activity, | ||||
|             new DefaultCallback() { | ||||
|     public void handleActivityResultWithCallback(Activity activity, FilePicker.HandleActivityResult handleActivityResult) { | ||||
| 
 | ||||
|         handleActivityResult.onHandleActivityResult(new DefaultCallback() { | ||||
| 
 | ||||
|                 @Override | ||||
|                 public void onCanceled(final ImageSource source, final int type) { | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ import static fr.free.nrw.commons.di.NetworkingModule.NAMED_LANGUAGE_WIKI_PEDIA_ | |||
| 
 | ||||
| import android.Manifest.permission; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.res.Configuration; | ||||
| import android.net.Uri; | ||||
| import android.os.Bundle; | ||||
|  | @ -20,6 +21,7 @@ import android.widget.LinearLayout; | |||
| import androidx.activity.result.ActivityResultCallback; | ||||
| import androidx.activity.result.ActivityResultLauncher; | ||||
| import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions; | ||||
| import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.annotation.VisibleForTesting; | ||||
|  | @ -96,6 +98,30 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl | |||
|     private int contributionsSize; | ||||
|     private String userName; | ||||
| 
 | ||||
|     private final ActivityResultLauncher<Intent> galleryPickLauncherForResult = | ||||
|         registerForActivityResult(new StartActivityForResult(), | ||||
|         result -> { | ||||
|             controller.handleActivityResultWithCallback(requireActivity(), callbacks -> { | ||||
|                 controller.onPictureReturnedFromGallery(result, requireActivity(), callbacks); | ||||
|             }); | ||||
|         }); | ||||
| 
 | ||||
|     private final ActivityResultLauncher<Intent> customSelectorLauncherForResult = | ||||
|         registerForActivityResult(new StartActivityForResult(), | ||||
|         result -> { | ||||
|             controller.handleActivityResultWithCallback(requireActivity(), callbacks -> { | ||||
|                 controller.onPictureReturnedFromCustomSelector(result, requireActivity(), callbacks); | ||||
|             }); | ||||
|         }); | ||||
| 
 | ||||
|     private final ActivityResultLauncher<Intent> cameraPickLauncherForResult = | ||||
|         registerForActivityResult(new StartActivityForResult(), | ||||
|         result -> { | ||||
|             controller.handleActivityResultWithCallback(requireActivity(), callbacks -> { | ||||
|                 controller.onPictureReturnedFromCamera(result, requireActivity(), callbacks); | ||||
|             }); | ||||
|         }); | ||||
| 
 | ||||
|     private ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher = registerForActivityResult( | ||||
|         new RequestMultiplePermissions(), | ||||
|         new ActivityResultCallback<Map<String, Boolean>>() { | ||||
|  | @ -111,7 +137,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl | |||
|                 } else { | ||||
|                     if (shouldShowRequestPermissionRationale(permission.ACCESS_FINE_LOCATION)) { | ||||
|                         controller.handleShowRationaleFlowCameraLocation(getActivity(), | ||||
|                             inAppCameraLocationPermissionLauncher); | ||||
|                             inAppCameraLocationPermissionLauncher, cameraPickLauncherForResult); | ||||
|                     } else { | ||||
|                         controller.locationPermissionCallback.onLocationPermissionDenied( | ||||
|                             getActivity().getString( | ||||
|  | @ -322,7 +348,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl | |||
|     private void setListeners() { | ||||
|         binding.fabPlus.setOnClickListener(view -> animateFAB(isFabOpen)); | ||||
|         binding.fabCamera.setOnClickListener(view -> { | ||||
|             controller.initiateCameraPick(getActivity(), inAppCameraLocationPermissionLauncher); | ||||
|             controller.initiateCameraPick(getActivity(), inAppCameraLocationPermissionLauncher, cameraPickLauncherForResult); | ||||
|             animateFAB(isFabOpen); | ||||
|         }); | ||||
|         binding.fabCamera.setOnLongClickListener(view -> { | ||||
|  | @ -330,7 +356,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl | |||
|             return true; | ||||
|         }); | ||||
|         binding.fabGallery.setOnClickListener(view -> { | ||||
|             controller.initiateGalleryPick(getActivity(), true); | ||||
|             controller.initiateGalleryPick(getActivity(), galleryPickLauncherForResult, true); | ||||
|             animateFAB(isFabOpen); | ||||
|         }); | ||||
|         binding.fabGallery.setOnLongClickListener(view -> { | ||||
|  | @ -343,7 +369,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl | |||
|      * Launch Custom Selector. | ||||
|      */ | ||||
|     protected void launchCustomSelector() { | ||||
|         controller.initiateCustomGalleryPickWithPermission(getActivity()); | ||||
|         controller.initiateCustomGalleryPickWithPermission(getActivity(), customSelectorLauncherForResult); | ||||
|         animateFAB(isFabOpen); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -438,13 +438,6 @@ public class MainActivity extends BaseActivity | |||
|             }); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected void onActivityResult(int requestCode, int resultCode, Intent data) { | ||||
|         Timber.d(data != null ? data.toString() : "onActivityResult data is null"); | ||||
|         super.onActivityResult(requestCode, resultCode, data); | ||||
|         controller.handleActivityResult(this, requestCode, resultCode, data); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected void onResume() { | ||||
|         super.onResume(); | ||||
|  |  | |||
|  | @ -13,6 +13,8 @@ import android.view.Window | |||
| import android.widget.Button | ||||
| import android.widget.ImageButton | ||||
| import android.widget.TextView | ||||
| import androidx.activity.result.ActivityResult | ||||
| import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult | ||||
| import androidx.compose.foundation.BorderStroke | ||||
| import androidx.compose.foundation.layout.Row | ||||
| import androidx.compose.foundation.layout.fillMaxWidth | ||||
|  | @ -146,6 +148,10 @@ class CustomSelectorActivity : | |||
| 
 | ||||
|     private var showPartialAccessIndicator by mutableStateOf(false) | ||||
| 
 | ||||
|     private val startForResult = registerForActivityResult(StartActivityForResult()){ result -> | ||||
|         onFullScreenDataReceived(result) | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * onCreate Activity, sets theme, initialises the view model, setup view. | ||||
|      */ | ||||
|  | @ -224,17 +230,10 @@ class CustomSelectorActivity : | |||
|     /** | ||||
|      * When data will be send from full screen mode, it will be passed to fragment | ||||
|      */ | ||||
|     override fun onActivityResult( | ||||
|         requestCode: Int, | ||||
|         resultCode: Int, | ||||
|         data: Intent?, | ||||
|     ) { | ||||
|         super.onActivityResult(requestCode, resultCode, data) | ||||
|         if (requestCode == Constants.RequestCodes.RECEIVE_DATA_FROM_FULL_SCREEN_MODE && | ||||
|             resultCode == Activity.RESULT_OK | ||||
|         ) { | ||||
|     private fun onFullScreenDataReceived(result: ActivityResult){ | ||||
|         if (result.resultCode == Activity.RESULT_OK) { | ||||
|             val selectedImages: ArrayList<Image> = | ||||
|                 data!! | ||||
|                 result.data!! | ||||
|                     .getParcelableArrayListExtra(CustomSelectorConstants.NEW_SELECTED_IMAGES)!! | ||||
|             viewModel?.selectedImages?.value = selectedImages | ||||
|         } | ||||
|  | @ -509,7 +508,7 @@ class CustomSelectorActivity : | |||
|             selectedImages, | ||||
|         ) | ||||
|         intent.putExtra(CustomSelectorConstants.BUCKET_ID, bucketId) | ||||
|         startActivityForResult(intent, Constants.RequestCodes.RECEIVE_DATA_FROM_FULL_SCREEN_MODE) | ||||
|         startForResult.launch(intent) | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  |  | |||
|  | @ -6,6 +6,8 @@ import android.os.Bundle | |||
| import android.os.Parcelable | ||||
| import android.speech.RecognizerIntent | ||||
| import android.view.View | ||||
| import androidx.activity.result.ActivityResult | ||||
| import androidx.activity.result.contract.ActivityResultContracts | ||||
| import androidx.recyclerview.widget.LinearLayoutManager | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import fr.free.nrw.commons.CommonsApplication | ||||
|  | @ -70,10 +72,14 @@ class DescriptionEditActivity : | |||
| 
 | ||||
|     private lateinit var binding: ActivityDescriptionEditBinding | ||||
| 
 | ||||
|     private val requestCodeForVoiceInput = 1213 | ||||
| 
 | ||||
|     private var descriptionAndCaptions: ArrayList<UploadMediaDetail>? = null | ||||
| 
 | ||||
|     private val voiceInputResultLauncher = registerForActivityResult( | ||||
|         ActivityResultContracts.StartActivityForResult() | ||||
|     ) { result: ActivityResult -> | ||||
|         onVoiceInput(result) | ||||
|     } | ||||
| 
 | ||||
|     @Inject lateinit var descriptionEditHelper: DescriptionEditHelper | ||||
| 
 | ||||
|     @Inject lateinit var sessionManager: SessionManager | ||||
|  | @ -115,6 +121,7 @@ class DescriptionEditActivity : | |||
|                 savedLanguageValue, | ||||
|                 descriptionAndCaptions, | ||||
|                 recentLanguagesDao, | ||||
|                 voiceInputResultLauncher | ||||
|             ) | ||||
|         uploadMediaDetailAdapter.setCallback { titleStringID: Int, messageStringId: Int -> | ||||
|             showInfoAlert( | ||||
|  | @ -149,6 +156,15 @@ class DescriptionEditActivity : | |||
| 
 | ||||
|     override fun onPrimaryCaptionTextChange(isNotEmpty: Boolean) {} | ||||
| 
 | ||||
|     private fun onVoiceInput(result: ActivityResult) { | ||||
|         if (result.resultCode == RESULT_OK && result.data != null) { | ||||
|             val resultData = result.data!!.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS) | ||||
|             uploadMediaDetailAdapter.handleSpeechResult(resultData!![0]) | ||||
|         } else { | ||||
|             Timber.e("Error %s", result.resultCode) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Adds new language item to RecyclerView | ||||
|      */ | ||||
|  | @ -292,22 +308,6 @@ class DescriptionEditActivity : | |||
|         progressDialog!!.show() | ||||
|     } | ||||
| 
 | ||||
|     override fun onActivityResult( | ||||
|         requestCode: Int, | ||||
|         resultCode: Int, | ||||
|         data: Intent?, | ||||
|     ) { | ||||
|         super.onActivityResult(requestCode, resultCode, data) | ||||
|         if (requestCode == requestCodeForVoiceInput) { | ||||
|             if (resultCode == RESULT_OK && data != null) { | ||||
|                 val result = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS) | ||||
|                 uploadMediaDetailAdapter.handleSpeechResult(result!![0]) | ||||
|             } else { | ||||
|                 Timber.e("Error %s", resultCode) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     override fun onSaveInstanceState(outState: Bundle) { | ||||
|         super.onSaveInstanceState(outState) | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,20 +4,11 @@ public interface Constants { | |||
|     String DEFAULT_FOLDER_NAME = "CommonsContributions"; | ||||
| 
 | ||||
|     /** | ||||
|      * Provides the request codes utilised by the FilePicker | ||||
|      * Provides the request codes for permission handling | ||||
|      */ | ||||
|     interface RequestCodes { | ||||
|         int LOCATION = 1; | ||||
|         int STORAGE = 2; | ||||
|         int FILE_PICKER_IMAGE_IDENTIFICATOR = 0b1101101100; //876 | ||||
|         int SOURCE_CHOOSER = 1 << 15; | ||||
| 
 | ||||
|         int PICK_PICTURE_FROM_CUSTOM_SELECTOR = FILE_PICKER_IMAGE_IDENTIFICATOR + (1 << 10); | ||||
|         int PICK_PICTURE_FROM_DOCUMENTS = FILE_PICKER_IMAGE_IDENTIFICATOR + (1 << 11); | ||||
|         int PICK_PICTURE_FROM_GALLERY = FILE_PICKER_IMAGE_IDENTIFICATOR + (1 << 12); | ||||
|         int TAKE_PICTURE = FILE_PICKER_IMAGE_IDENTIFICATOR + (1 << 13); | ||||
| 
 | ||||
|         int RECEIVE_DATA_FROM_FULL_SCREEN_MODE = 1 << 9; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  |  | |||
|  | @ -12,6 +12,8 @@ import android.content.pm.ResolveInfo; | |||
| import android.net.Uri; | ||||
| import android.provider.MediaStore; | ||||
| import android.text.TextUtils; | ||||
| import androidx.activity.result.ActivityResult; | ||||
| import androidx.activity.result.ActivityResultLauncher; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.preference.PreferenceManager; | ||||
|  | @ -107,31 +109,25 @@ public class FilePicker implements Constants { | |||
|      * | ||||
|      * @param type Custom type of your choice, which will be returned with the images | ||||
|      */ | ||||
|     public static void openGallery(Activity activity, int type, boolean openDocumentIntentPreferred) { | ||||
|     public static void openGallery(Activity activity, ActivityResultLauncher<Intent> resultLauncher, int type, boolean openDocumentIntentPreferred) { | ||||
|         Intent intent = createGalleryIntent(activity, type, openDocumentIntentPreferred); | ||||
|         int requestCode = RequestCodes.PICK_PICTURE_FROM_GALLERY; | ||||
| 
 | ||||
|             if(openDocumentIntentPreferred){ | ||||
|                 requestCode = RequestCodes.PICK_PICTURE_FROM_DOCUMENTS; | ||||
|             } | ||||
| 
 | ||||
|         activity.startActivityForResult(intent, requestCode); | ||||
|         resultLauncher.launch(intent); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Opens Custom Selector | ||||
|      */ | ||||
|     public static void openCustomSelector(Activity activity, int type) { | ||||
|     public static void openCustomSelector(Activity activity, ActivityResultLauncher<Intent> resultLauncher, int type) { | ||||
|         Intent intent = createCustomSelectorIntent(activity, type); | ||||
|         activity.startActivityForResult(intent, RequestCodes.PICK_PICTURE_FROM_CUSTOM_SELECTOR); | ||||
|         resultLauncher.launch(intent); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Opens the camera app to pick image clicked by user  | ||||
|      */ | ||||
|     public static void openCameraForImage(Activity activity, int type) { | ||||
|     public static void openCameraForImage(Activity activity, ActivityResultLauncher<Intent> resultLauncher, int type) { | ||||
|         Intent intent = createCameraForImageIntent(activity, type); | ||||
|         activity.startActivityForResult(intent, RequestCodes.TAKE_PICTURE); | ||||
|         resultLauncher.launch(intent); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|  | @ -154,43 +150,6 @@ public class FilePicker implements Constants { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Any activity can use this method to attach their callback to the file picker | ||||
|      */ | ||||
|     public static void handleActivityResult(int requestCode, int resultCode, Intent data, Activity activity, @NonNull FilePicker.Callbacks callbacks) { | ||||
|         boolean isHandledPickedFile = (requestCode & RequestCodes.FILE_PICKER_IMAGE_IDENTIFICATOR) > 0; | ||||
|         if (isHandledPickedFile) { | ||||
|             requestCode &= ~RequestCodes.SOURCE_CHOOSER; | ||||
|             if (requestCode == RequestCodes.PICK_PICTURE_FROM_GALLERY || | ||||
|                     requestCode == RequestCodes.TAKE_PICTURE || | ||||
|                     requestCode == RequestCodes.PICK_PICTURE_FROM_DOCUMENTS || | ||||
|                     requestCode == RequestCodes.PICK_PICTURE_FROM_CUSTOM_SELECTOR) { | ||||
|                 if (resultCode == Activity.RESULT_OK) { | ||||
|                     if (requestCode == RequestCodes.PICK_PICTURE_FROM_DOCUMENTS && !isPhoto(data)) { | ||||
|                         onPictureReturnedFromDocuments(data, activity, callbacks); | ||||
|                     } else if (requestCode == RequestCodes.PICK_PICTURE_FROM_GALLERY && !isPhoto(data)) { | ||||
|                         onPictureReturnedFromGallery(data, activity, callbacks); | ||||
|                     } else if (requestCode == RequestCodes.PICK_PICTURE_FROM_CUSTOM_SELECTOR) { | ||||
|                         onPictureReturnedFromCustomSelector(data, activity, callbacks); | ||||
|                     } else if (requestCode == RequestCodes.TAKE_PICTURE) { | ||||
|                         onPictureReturnedFromCamera(activity, callbacks); | ||||
|                     } | ||||
|                 } else { | ||||
|                     if (requestCode == RequestCodes.PICK_PICTURE_FROM_DOCUMENTS) { | ||||
|                         callbacks.onCanceled(FilePicker.ImageSource.DOCUMENTS, restoreType(activity)); | ||||
|                     } else if (requestCode == RequestCodes.PICK_PICTURE_FROM_GALLERY) { | ||||
|                         callbacks.onCanceled(FilePicker.ImageSource.GALLERY, restoreType(activity)); | ||||
|                     } else if (requestCode == RequestCodes.PICK_PICTURE_FROM_CUSTOM_SELECTOR){ | ||||
|                         callbacks.onCanceled(ImageSource.CUSTOM_SELECTOR, restoreType(activity)); | ||||
|                     } | ||||
|                     else { | ||||
|                         callbacks.onCanceled(FilePicker.ImageSource.CAMERA_IMAGE, restoreType(activity)); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static List<UploadableFile> handleExternalImagesPicked(Intent data, Activity activity) { | ||||
|         try { | ||||
|             return getFilesFromGalleryPictures(data, activity); | ||||
|  | @ -243,18 +202,22 @@ public class FilePicker implements Constants { | |||
|         return intent; | ||||
|     } | ||||
| 
 | ||||
|     private static void onPictureReturnedFromDocuments(Intent data, Activity activity, @NonNull FilePicker.Callbacks callbacks) { | ||||
|         try { | ||||
|             Uri photoPath = data.getData(); | ||||
|             UploadableFile photoFile = PickedFiles.pickedExistingPicture(activity, photoPath); | ||||
|             callbacks.onImagesPicked(singleFileList(photoFile), FilePicker.ImageSource.DOCUMENTS, restoreType(activity)); | ||||
|     public static void onPictureReturnedFromDocuments(ActivityResult result, Activity activity, @NonNull FilePicker.Callbacks callbacks) { | ||||
|         if(result.getResultCode() == Activity.RESULT_OK && !isPhoto(result.getData())){ | ||||
|             try { | ||||
|                 Uri photoPath = result.getData().getData(); | ||||
|                 UploadableFile photoFile = PickedFiles.pickedExistingPicture(activity, photoPath); | ||||
|                 callbacks.onImagesPicked(singleFileList(photoFile), FilePicker.ImageSource.DOCUMENTS, restoreType(activity)); | ||||
| 
 | ||||
|             if (configuration(activity).shouldCopyPickedImagesToPublicGalleryAppFolder()) { | ||||
|                 PickedFiles.copyFilesInSeparateThread(activity, singleFileList(photoFile)); | ||||
|                 if (configuration(activity).shouldCopyPickedImagesToPublicGalleryAppFolder()) { | ||||
|                     PickedFiles.copyFilesInSeparateThread(activity, singleFileList(photoFile)); | ||||
|                 } | ||||
|             } catch (Exception e) { | ||||
|                 e.printStackTrace(); | ||||
|                 callbacks.onImagePickerError(e, FilePicker.ImageSource.DOCUMENTS, restoreType(activity)); | ||||
|             } | ||||
|         } catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
|             callbacks.onImagePickerError(e, FilePicker.ImageSource.DOCUMENTS, restoreType(activity)); | ||||
|         } else { | ||||
|             callbacks.onCanceled(FilePicker.ImageSource.DOCUMENTS, restoreType(activity)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -262,14 +225,18 @@ public class FilePicker implements Constants { | |||
|      * onPictureReturnedFromCustomSelector. | ||||
|      * Retrieve and forward the images to upload wizard through callback. | ||||
|      */ | ||||
|     private static void onPictureReturnedFromCustomSelector(Intent data, Activity activity, @NonNull FilePicker.Callbacks callbacks) { | ||||
|         try { | ||||
|             List<UploadableFile> files = getFilesFromCustomSelector(data, activity); | ||||
|             callbacks.onImagesPicked(files, ImageSource.CUSTOM_SELECTOR, restoreType(activity)); | ||||
|         } catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
|             callbacks.onImagePickerError(e, ImageSource.CUSTOM_SELECTOR, restoreType(activity)); | ||||
|         } | ||||
|     public static void onPictureReturnedFromCustomSelector(ActivityResult result, Activity activity, @NonNull FilePicker.Callbacks callbacks) { | ||||
|        if(result.getResultCode() == Activity.RESULT_OK){ | ||||
|            try { | ||||
|                List<UploadableFile> files = getFilesFromCustomSelector(result.getData(), activity); | ||||
|                callbacks.onImagesPicked(files, ImageSource.CUSTOM_SELECTOR, restoreType(activity)); | ||||
|            } catch (Exception e) { | ||||
|                e.printStackTrace(); | ||||
|                callbacks.onImagePickerError(e, ImageSource.CUSTOM_SELECTOR, restoreType(activity)); | ||||
|            } | ||||
|        } else { | ||||
|            callbacks.onCanceled(ImageSource.CUSTOM_SELECTOR, restoreType(activity)); | ||||
|        } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -292,13 +259,17 @@ public class FilePicker implements Constants { | |||
|         return files; | ||||
|     } | ||||
| 
 | ||||
|     private static void onPictureReturnedFromGallery(Intent data, Activity activity, @NonNull FilePicker.Callbacks callbacks) { | ||||
|         try { | ||||
|             List<UploadableFile> files = getFilesFromGalleryPictures(data, activity); | ||||
|             callbacks.onImagesPicked(files, FilePicker.ImageSource.GALLERY, restoreType(activity)); | ||||
|         } catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
|             callbacks.onImagePickerError(e, FilePicker.ImageSource.GALLERY, restoreType(activity)); | ||||
|     public static void onPictureReturnedFromGallery(ActivityResult result, Activity activity, @NonNull FilePicker.Callbacks callbacks) { | ||||
|         if(result.getResultCode() == Activity.RESULT_OK && !isPhoto(result.getData())){ | ||||
|             try { | ||||
|                 List<UploadableFile> files = getFilesFromGalleryPictures(result.getData(), activity); | ||||
|                 callbacks.onImagesPicked(files, FilePicker.ImageSource.GALLERY, restoreType(activity)); | ||||
|             } catch (Exception e) { | ||||
|                 e.printStackTrace(); | ||||
|                 callbacks.onImagePickerError(e, FilePicker.ImageSource.GALLERY, restoreType(activity)); | ||||
|             } | ||||
|         } else{ | ||||
|             callbacks.onCanceled(FilePicker.ImageSource.GALLERY, restoreType(activity)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -324,69 +295,40 @@ public class FilePicker implements Constants { | |||
|         return files; | ||||
|     } | ||||
| 
 | ||||
|     private static void onPictureReturnedFromCamera(Activity activity, @NonNull FilePicker.Callbacks callbacks) { | ||||
|         try { | ||||
|             String lastImageUri = PreferenceManager.getDefaultSharedPreferences(activity).getString(KEY_PHOTO_URI, null); | ||||
|             if (!TextUtils.isEmpty(lastImageUri)) { | ||||
|                 revokeWritePermission(activity, Uri.parse(lastImageUri)); | ||||
|             } | ||||
| 
 | ||||
|             UploadableFile photoFile = FilePicker.takenCameraPicture(activity); | ||||
|             List<UploadableFile> files = new ArrayList<>(); | ||||
|             files.add(photoFile); | ||||
| 
 | ||||
|             if (photoFile == null) { | ||||
|                 Exception e = new IllegalStateException("Unable to get the picture returned from camera"); | ||||
|                 callbacks.onImagePickerError(e, FilePicker.ImageSource.CAMERA_IMAGE, restoreType(activity)); | ||||
|             } else { | ||||
|                 if (configuration(activity).shouldCopyTakenPhotosToPublicGalleryAppFolder()) { | ||||
|                     PickedFiles.copyFilesInSeparateThread(activity, singleFileList(photoFile)); | ||||
|     public static void onPictureReturnedFromCamera(ActivityResult activityResult, Activity activity, @NonNull FilePicker.Callbacks callbacks) { | ||||
|         if(activityResult.getResultCode() == Activity.RESULT_OK){ | ||||
|             try { | ||||
|                 String lastImageUri = PreferenceManager.getDefaultSharedPreferences(activity).getString(KEY_PHOTO_URI, null); | ||||
|                 if (!TextUtils.isEmpty(lastImageUri)) { | ||||
|                     revokeWritePermission(activity, Uri.parse(lastImageUri)); | ||||
|                 } | ||||
| 
 | ||||
|                 callbacks.onImagesPicked(files, FilePicker.ImageSource.CAMERA_IMAGE, restoreType(activity)); | ||||
|             } | ||||
|                 UploadableFile photoFile = FilePicker.takenCameraPicture(activity); | ||||
|                 List<UploadableFile> files = new ArrayList<>(); | ||||
|                 files.add(photoFile); | ||||
| 
 | ||||
|             PreferenceManager.getDefaultSharedPreferences(activity) | ||||
|                 if (photoFile == null) { | ||||
|                     Exception e = new IllegalStateException("Unable to get the picture returned from camera"); | ||||
|                     callbacks.onImagePickerError(e, FilePicker.ImageSource.CAMERA_IMAGE, restoreType(activity)); | ||||
|                 } else { | ||||
|                     if (configuration(activity).shouldCopyTakenPhotosToPublicGalleryAppFolder()) { | ||||
|                         PickedFiles.copyFilesInSeparateThread(activity, singleFileList(photoFile)); | ||||
|                     } | ||||
| 
 | ||||
|                     callbacks.onImagesPicked(files, FilePicker.ImageSource.CAMERA_IMAGE, restoreType(activity)); | ||||
|                 } | ||||
| 
 | ||||
|                 PreferenceManager.getDefaultSharedPreferences(activity) | ||||
|                     .edit() | ||||
|                     .remove(KEY_LAST_CAMERA_PHOTO) | ||||
|                     .remove(KEY_PHOTO_URI) | ||||
|                     .apply(); | ||||
|         } catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
|             callbacks.onImagePickerError(e, FilePicker.ImageSource.CAMERA_IMAGE, restoreType(activity)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private static void onVideoReturnedFromCamera(Activity activity, @NonNull FilePicker.Callbacks callbacks) { | ||||
|         try { | ||||
|             String lastVideoUri = PreferenceManager.getDefaultSharedPreferences(activity).getString(KEY_VIDEO_URI, null); | ||||
|             if (!TextUtils.isEmpty(lastVideoUri)) { | ||||
|                 revokeWritePermission(activity, Uri.parse(lastVideoUri)); | ||||
|             } catch (Exception e) { | ||||
|                 e.printStackTrace(); | ||||
|                 callbacks.onImagePickerError(e, FilePicker.ImageSource.CAMERA_IMAGE, restoreType(activity)); | ||||
|             } | ||||
| 
 | ||||
|             UploadableFile photoFile = FilePicker.takenCameraVideo(activity); | ||||
|             List<UploadableFile> files = new ArrayList<>(); | ||||
|             files.add(photoFile); | ||||
| 
 | ||||
|             if (photoFile == null) { | ||||
|                 Exception e = new IllegalStateException("Unable to get the video returned from camera"); | ||||
|                 callbacks.onImagePickerError(e, FilePicker.ImageSource.CAMERA_VIDEO, restoreType(activity)); | ||||
|             } else { | ||||
|                 if (configuration(activity).shouldCopyTakenPhotosToPublicGalleryAppFolder()) { | ||||
|                     PickedFiles.copyFilesInSeparateThread(activity, singleFileList(photoFile)); | ||||
|                 } | ||||
| 
 | ||||
|                 callbacks.onImagesPicked(files, FilePicker.ImageSource.CAMERA_VIDEO, restoreType(activity)); | ||||
|             } | ||||
| 
 | ||||
|             PreferenceManager.getDefaultSharedPreferences(activity) | ||||
|                     .edit() | ||||
|                     .remove(KEY_LAST_CAMERA_VIDEO) | ||||
|                     .remove(KEY_VIDEO_URI) | ||||
|                     .apply(); | ||||
|         } catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
|             callbacks.onImagePickerError(e, FilePicker.ImageSource.CAMERA_VIDEO, restoreType(activity)); | ||||
|         } else { | ||||
|             callbacks.onCanceled(FilePicker.ImageSource.CAMERA_IMAGE, restoreType(activity)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -406,4 +348,8 @@ public class FilePicker implements Constants { | |||
| 
 | ||||
|         void onCanceled(FilePicker.ImageSource source, int type); | ||||
|     } | ||||
| 
 | ||||
|     public interface HandleActivityResult{ | ||||
|         void onHandleActivityResult(FilePicker.Callbacks callbacks); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,13 +1,10 @@ | |||
| package fr.free.nrw.commons.media; | ||||
| 
 | ||||
| import static android.app.Activity.RESULT_CANCELED; | ||||
| import static android.app.Activity.RESULT_OK; | ||||
| import static android.view.View.GONE; | ||||
| import static android.view.View.VISIBLE; | ||||
| import static fr.free.nrw.commons.category.CategoryClientKt.CATEGORY_NEEDING_CATEGORIES; | ||||
| import static fr.free.nrw.commons.category.CategoryClientKt.CATEGORY_UNCATEGORISED; | ||||
| import static fr.free.nrw.commons.description.EditDescriptionConstants.LIST_OF_DESCRIPTION_AND_CAPTION; | ||||
| import static fr.free.nrw.commons.description.EditDescriptionConstants.UPDATED_WIKITEXT; | ||||
| import static fr.free.nrw.commons.description.EditDescriptionConstants.WIKITEXT; | ||||
| import static fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.LAST_LOCATION; | ||||
| import static fr.free.nrw.commons.utils.LangCodeUtils.getLocalizedResources; | ||||
|  | @ -112,8 +109,6 @@ import timber.log.Timber; | |||
| public class MediaDetailFragment extends CommonsDaggerSupportFragment implements | ||||
|     CategoryEditHelper.Callback { | ||||
| 
 | ||||
|     private static final int REQUEST_CODE = 1001; | ||||
|     private static final int REQUEST_CODE_EDIT_DESCRIPTION = 1002; | ||||
|     private static final String IMAGE_BACKGROUND_COLOR = "image_background_color"; | ||||
|     static final int DEFAULT_IMAGE_BACKGROUND_COLOR = 0; | ||||
|      | ||||
|  | @ -1065,81 +1060,6 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements | |||
|         return captionList; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get the result from another activity and act accordingly. | ||||
|      * @param requestCode | ||||
|      * @param resultCode | ||||
|      * @param data | ||||
|      */ | ||||
|     @Override | ||||
|     public void onActivityResult(final int requestCode, final int resultCode, | ||||
|         @Nullable final Intent data) { | ||||
|         super.onActivityResult(requestCode, resultCode, data); | ||||
| 
 | ||||
|         if (requestCode == REQUEST_CODE_EDIT_DESCRIPTION && resultCode == RESULT_OK) { | ||||
|             final String updatedWikiText = data.getStringExtra(UPDATED_WIKITEXT); | ||||
| 
 | ||||
|             try { | ||||
|                 compositeDisposable.add(descriptionEditHelper.addDescription(getContext(), media, | ||||
|                         updatedWikiText) | ||||
|                     .subscribeOn(Schedulers.io()) | ||||
|                     .observeOn(AndroidSchedulers.mainThread()) | ||||
|                     .subscribe(s -> { | ||||
|                         Timber.d("Descriptions are added."); | ||||
|                     })); | ||||
|             } catch (Exception e) { | ||||
|                 if (e.getLocalizedMessage().equals(CsrfTokenClient.ANONYMOUS_TOKEN_MESSAGE)) { | ||||
|                     final String username = sessionManager.getUserName(); | ||||
|                     final CommonsApplication.BaseLogoutListener logoutListener = new CommonsApplication.BaseLogoutListener( | ||||
|                         getActivity(), | ||||
|                         requireActivity().getString(R.string.invalid_login_message), | ||||
|                         username | ||||
|                     ); | ||||
| 
 | ||||
|                     CommonsApplication.getInstance().clearApplicationData( | ||||
|                         requireActivity(), logoutListener); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             final ArrayList<UploadMediaDetail> uploadMediaDetails | ||||
|                 = data.getParcelableArrayListExtra(LIST_OF_DESCRIPTION_AND_CAPTION); | ||||
| 
 | ||||
|             LinkedHashMap<String, String> updatedCaptions = new LinkedHashMap<>(); | ||||
|             for (UploadMediaDetail mediaDetail: | ||||
|             uploadMediaDetails) { | ||||
|                 try { | ||||
|                     compositeDisposable.add(descriptionEditHelper.addCaption(getContext(), media, | ||||
|                             mediaDetail.getLanguageCode(), mediaDetail.getCaptionText()) | ||||
|                         .subscribeOn(Schedulers.io()) | ||||
|                         .observeOn(AndroidSchedulers.mainThread()) | ||||
|                         .subscribe(s -> { | ||||
|                                 updateCaptions(mediaDetail, updatedCaptions); | ||||
|                                 Timber.d("Caption is added."); | ||||
|                             })); | ||||
| 
 | ||||
|                 } catch (Exception e) { | ||||
|                     if (e.getLocalizedMessage().equals(CsrfTokenClient.ANONYMOUS_TOKEN_MESSAGE)) { | ||||
|                         final String username = sessionManager.getUserName(); | ||||
|                         final CommonsApplication.BaseLogoutListener logoutListener = new CommonsApplication.BaseLogoutListener( | ||||
|                             getActivity(), | ||||
|                             requireActivity().getString(R.string.invalid_login_message), | ||||
|                             username | ||||
|                         ); | ||||
| 
 | ||||
|                         CommonsApplication.getInstance().clearApplicationData( | ||||
|                             requireActivity(), logoutListener); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             binding.progressBarEdit.setVisibility(GONE); | ||||
|             binding.descriptionEdit.setVisibility(VISIBLE); | ||||
| 
 | ||||
|         } else if (requestCode == REQUEST_CODE_EDIT_DESCRIPTION && resultCode == RESULT_CANCELED) { | ||||
|             binding.progressBarEdit.setVisibility(GONE); | ||||
|             binding.descriptionEdit.setVisibility(VISIBLE); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Adds caption to the map and updates captions | ||||
|      * @param mediaDetail UploadMediaDetail | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| package fr.free.nrw.commons.nearby | ||||
| 
 | ||||
| import android.content.Intent | ||||
| import android.view.View | ||||
| import android.view.View.GONE | ||||
| import android.view.View.INVISIBLE | ||||
|  | @ -17,9 +18,9 @@ import fr.free.nrw.commons.databinding.ItemPlaceBinding | |||
| fun placeAdapterDelegate( | ||||
|     bookmarkLocationDao: BookmarkLocationsDao, | ||||
|     onItemClick: ((Place) -> Unit)? = null, | ||||
|     onCameraClicked: (Place, ActivityResultLauncher<Array<String>>) -> Unit, | ||||
|     onCameraClicked: (Place, ActivityResultLauncher<Array<String>>, ActivityResultLauncher<Intent>) -> Unit, | ||||
|     onCameraLongPressed: () -> Boolean, | ||||
|     onGalleryClicked: (Place) -> Unit, | ||||
|     onGalleryClicked: (Place, ActivityResultLauncher<Intent>) -> Unit, | ||||
|     onGalleryLongPressed: () -> Boolean, | ||||
|     onBookmarkClicked: (Place, Boolean) -> Unit, | ||||
|     onBookmarkLongPressed: () -> Boolean, | ||||
|  | @ -28,6 +29,8 @@ fun placeAdapterDelegate( | |||
|     onDirectionsClicked: (Place) -> Unit, | ||||
|     onDirectionsLongPressed: () -> Boolean, | ||||
|     inAppCameraLocationPermissionLauncher: ActivityResultLauncher<Array<String>>, | ||||
|     cameraPickLauncherForResult: ActivityResultLauncher<Intent>, | ||||
|     galleryPickLauncherForResult: ActivityResultLauncher<Intent> | ||||
| ) = adapterDelegateViewBinding<Place, Place, ItemPlaceBinding>({ layoutInflater, parent -> | ||||
|     ItemPlaceBinding.inflate(layoutInflater, parent, false) | ||||
| }) { | ||||
|  | @ -44,10 +47,10 @@ fun placeAdapterDelegate( | |||
|                 onItemClick?.invoke(item) | ||||
|             } | ||||
|         } | ||||
|         nearbyButtonLayout.cameraButton.setOnClickListener { onCameraClicked(item, inAppCameraLocationPermissionLauncher) } | ||||
|         nearbyButtonLayout.cameraButton.setOnClickListener { onCameraClicked(item, inAppCameraLocationPermissionLauncher, cameraPickLauncherForResult) } | ||||
|         nearbyButtonLayout.cameraButton.setOnLongClickListener { onCameraLongPressed() } | ||||
| 
 | ||||
|         nearbyButtonLayout.galleryButton.setOnClickListener { onGalleryClicked(item) } | ||||
|         nearbyButtonLayout.galleryButton.setOnClickListener { onGalleryClicked(item, galleryPickLauncherForResult) } | ||||
|         nearbyButtonLayout.galleryButton.setOnLongClickListener { onGalleryLongPressed() } | ||||
|         bookmarkButtonImage.setOnClickListener { | ||||
|             val isBookmarked = bookmarkLocationDao.updateBookmarkLocation(item) | ||||
|  |  | |||
|  | @ -28,14 +28,14 @@ class CommonPlaceClickActions | |||
|         private val activity: Activity, | ||||
|         private val contributionController: ContributionController, | ||||
|     ) { | ||||
|         fun onCameraClicked(): (Place, ActivityResultLauncher<Array<String>>) -> Unit = | ||||
|             { place, launcher -> | ||||
|         fun onCameraClicked(): (Place, ActivityResultLauncher<Array<String>>, ActivityResultLauncher<Intent>) -> Unit = | ||||
|             { place, launcher, resultLauncher -> | ||||
|                 if (applicationKvStore.getBoolean("login_skipped", false)) { | ||||
|                     showLoginDialog() | ||||
|                 } else { | ||||
|                     Timber.d("Camera button tapped. Image title: ${place.getName()}Image desc: ${place.longDescription}") | ||||
|                     storeSharedPrefs(place) | ||||
|                     contributionController.initiateCameraPick(activity, launcher) | ||||
|                     contributionController.initiateCameraPick(activity, launcher, resultLauncher) | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  | @ -72,14 +72,14 @@ class CommonPlaceClickActions | |||
|                 true | ||||
|             } | ||||
| 
 | ||||
|         fun onGalleryClicked(): (Place) -> Unit = | ||||
|             { | ||||
|         fun onGalleryClicked(): (Place, ActivityResultLauncher<Intent>) -> Unit = | ||||
|             {place, galleryPickLauncherForResult -> | ||||
|                 if (applicationKvStore.getBoolean("login_skipped", false)) { | ||||
|                     showLoginDialog() | ||||
|                 } else { | ||||
|                     Timber.d("Gallery button tapped. Image title: ${it.getName()}Image desc: ${it.getLongDescription()}") | ||||
|                     storeSharedPrefs(it) | ||||
|                     contributionController.initiateGalleryPick(activity, false) | ||||
|                     Timber.d("Gallery button tapped. Image title: ${place.getName()}Image desc: ${place.getLongDescription()}") | ||||
|                     storeSharedPrefs(place) | ||||
|                     contributionController.initiateGalleryPick(activity, galleryPickLauncherForResult, false) | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  |  | |||
|  | @ -49,6 +49,7 @@ import androidx.activity.result.ActivityResultCallback; | |||
| import androidx.activity.result.ActivityResultLauncher; | ||||
| import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions; | ||||
| import androidx.activity.result.contract.ActivityResultContracts.RequestPermission; | ||||
| import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult; | ||||
| import androidx.annotation.DrawableRes; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
|  | @ -225,6 +226,31 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|     private GridLayoutManager gridLayoutManager; | ||||
|     private List<BottomSheetItem> dataList; | ||||
|     private BottomSheetAdapter bottomSheetAdapter; | ||||
| 
 | ||||
|     private final ActivityResultLauncher<Intent> galleryPickLauncherForResult = | ||||
|         registerForActivityResult(new StartActivityForResult(), | ||||
|         result -> { | ||||
|             controller.handleActivityResultWithCallback(requireActivity(), callbacks -> { | ||||
|                 controller.onPictureReturnedFromGallery(result, requireActivity(), callbacks); | ||||
|             }); | ||||
|         }); | ||||
| 
 | ||||
|     private final ActivityResultLauncher<Intent> customSelectorLauncherForResult = | ||||
|         registerForActivityResult(new StartActivityForResult(), | ||||
|         result -> { | ||||
|             controller.handleActivityResultWithCallback(requireActivity(), callbacks -> { | ||||
|                 controller.onPictureReturnedFromCustomSelector(result, requireActivity(), callbacks); | ||||
|             }); | ||||
|         }); | ||||
| 
 | ||||
|     private final ActivityResultLauncher<Intent> cameraPickLauncherForResult = | ||||
|         registerForActivityResult(new StartActivityForResult(), | ||||
|         result -> { | ||||
|             controller.handleActivityResultWithCallback(requireActivity(), callbacks -> { | ||||
|                 controller.onPictureReturnedFromCamera(result, requireActivity(), callbacks); | ||||
|             }); | ||||
|         }); | ||||
| 
 | ||||
|     private ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher = registerForActivityResult( | ||||
|         new RequestMultiplePermissions(), | ||||
|         new ActivityResultCallback<Map<String, Boolean>>() { | ||||
|  | @ -240,7 +266,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|                 } else { | ||||
|                     if (shouldShowRequestPermissionRationale(permission.ACCESS_FINE_LOCATION)) { | ||||
|                         controller.handleShowRationaleFlowCameraLocation(getActivity(), | ||||
|                             inAppCameraLocationPermissionLauncher); | ||||
|                             inAppCameraLocationPermissionLauncher, cameraPickLauncherForResult); | ||||
|                     } else { | ||||
|                         controller.locationPermissionCallback.onLocationPermissionDenied( | ||||
|                             getActivity().getString( | ||||
|  | @ -570,7 +596,9 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|                 return Unit.INSTANCE; | ||||
|             }, | ||||
|             commonPlaceClickActions, | ||||
|             inAppCameraLocationPermissionLauncher | ||||
|             inAppCameraLocationPermissionLauncher, | ||||
|             galleryPickLauncherForResult, | ||||
|             cameraPickLauncherForResult | ||||
|         ); | ||||
|         binding.bottomSheetNearby.rvNearbyList.setAdapter(adapter); | ||||
|     } | ||||
|  | @ -2201,7 +2229,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|             if (binding.fabCamera.isShown()) { | ||||
|                 Timber.d("Camera button tapped. Place: %s", selectedPlace.toString()); | ||||
|                 storeSharedPrefs(selectedPlace); | ||||
|                 controller.initiateCameraPick(getActivity(), inAppCameraLocationPermissionLauncher); | ||||
|                 controller.initiateCameraPick(getActivity(), inAppCameraLocationPermissionLauncher, cameraPickLauncherForResult); | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|  | @ -2210,6 +2238,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|                 Timber.d("Gallery button tapped. Place: %s", selectedPlace.toString()); | ||||
|                 storeSharedPrefs(selectedPlace); | ||||
|                 controller.initiateGalleryPick(getActivity(), | ||||
|                     galleryPickLauncherForResult, | ||||
|                     false); | ||||
|             } | ||||
|         }); | ||||
|  | @ -2218,7 +2247,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|             if (binding.fabCustomGallery.isShown()) { | ||||
|                 Timber.d("Gallery button tapped. Place: %s", selectedPlace.toString()); | ||||
|                 storeSharedPrefs(selectedPlace); | ||||
|                 controller.initiateCustomGalleryPickWithPermission(getActivity()); | ||||
|                 controller.initiateCustomGalleryPickWithPermission(getActivity(), customSelectorLauncherForResult); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| package fr.free.nrw.commons.nearby.fragments | ||||
| 
 | ||||
| import android.content.Intent | ||||
| import androidx.activity.result.ActivityResultLauncher | ||||
| import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao | ||||
| import fr.free.nrw.commons.nearby.Place | ||||
|  | @ -12,6 +13,8 @@ class PlaceAdapter( | |||
|     onBookmarkClicked: (Place, Boolean) -> Unit, | ||||
|     commonPlaceClickActions: CommonPlaceClickActions, | ||||
|     inAppCameraLocationPermissionLauncher: ActivityResultLauncher<Array<String>>, | ||||
|     galleryPickLauncherForResult: ActivityResultLauncher<Intent>, | ||||
|     cameraPickLauncherForResult: ActivityResultLauncher<Intent> | ||||
| ) : BaseDelegateAdapter<Place>( | ||||
|         placeAdapterDelegate( | ||||
|             bookmarkLocationsDao, | ||||
|  | @ -27,6 +30,8 @@ class PlaceAdapter( | |||
|             commonPlaceClickActions.onDirectionsClicked(), | ||||
|             commonPlaceClickActions.onDirectionsLongPressed(), | ||||
|             inAppCameraLocationPermissionLauncher, | ||||
|             cameraPickLauncherForResult, | ||||
|             galleryPickLauncherForResult | ||||
|         ), | ||||
|         areItemsTheSame = { oldItem, newItem -> oldItem.wikiDataEntityId == newItem.wikiDataEntityId }, | ||||
|     ) | ||||
|  |  | |||
|  | @ -21,6 +21,7 @@ import android.widget.TextView; | |||
| import androidx.activity.result.ActivityResultCallback; | ||||
| import androidx.activity.result.ActivityResultLauncher; | ||||
| import androidx.activity.result.contract.ActivityResultContracts; | ||||
| import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult; | ||||
| import androidx.preference.ListPreference; | ||||
| import androidx.preference.MultiSelectListPreference; | ||||
| import androidx.preference.Preference; | ||||
|  | @ -85,6 +86,15 @@ public class SettingsFragment extends PreferenceFragmentCompat { | |||
|     private View separator; | ||||
|     private ListView languageHistoryListView; | ||||
|     private static final String GET_CONTENT_PICKER_HELP_URL = "https://commons-app.github.io/docs.html#get-content"; | ||||
| 
 | ||||
|     private final ActivityResultLauncher<Intent> cameraPickLauncherForResult = | ||||
|         registerForActivityResult(new StartActivityForResult(), | ||||
|         result -> { | ||||
|             contributionController.handleActivityResultWithCallback(requireActivity(), callbacks -> { | ||||
|                 contributionController.onPictureReturnedFromCamera(result, requireActivity(), callbacks); | ||||
|             }); | ||||
|         }); | ||||
| 
 | ||||
|     private ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() { | ||||
|         @Override | ||||
|         public void onActivityResult(Map<String, Boolean> result) { | ||||
|  | @ -93,7 +103,7 @@ public class SettingsFragment extends PreferenceFragmentCompat { | |||
|                 areAllGranted = areAllGranted && b; | ||||
|             } | ||||
|             if (!areAllGranted && shouldShowRequestPermissionRationale(permission.ACCESS_FINE_LOCATION)) { | ||||
|                 contributionController.handleShowRationaleFlowCameraLocation(getActivity(), inAppCameraLocationPermissionLauncher); | ||||
|                 contributionController.handleShowRationaleFlowCameraLocation(getActivity(), inAppCameraLocationPermissionLauncher, cameraPickLauncherForResult); | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
|  |  | |||
|  | @ -441,14 +441,6 @@ public class UploadActivity extends BaseActivity implements UploadContract.View, | |||
|         super.onRequestPermissionsResult(requestCode, permissions, grantResults); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected void onActivityResult(int requestCode, int resultCode, Intent data) { | ||||
|         super.onActivityResult(requestCode, resultCode, data); | ||||
|         if (requestCode == CommonsApplication.OPEN_APPLICATION_DETAIL_SETTINGS) { | ||||
|             //TODO: Confirm if handling manual permission enabled is required | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Sets the flag indicating whether the upload is of a specific place. | ||||
|      * | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ import android.widget.ImageView; | |||
| import android.widget.LinearLayout; | ||||
| import android.widget.ListView; | ||||
| import android.widget.TextView; | ||||
| import androidx.activity.result.ActivityResultLauncher; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.constraintlayout.widget.ConstraintLayout; | ||||
|  | @ -57,27 +58,29 @@ public class UploadMediaDetailAdapter extends | |||
|     private int currentPosition; | ||||
|     private Fragment fragment; | ||||
|     private Activity activity; | ||||
|     private final ActivityResultLauncher<Intent> voiceInputResultLauncher; | ||||
|     private SelectedVoiceIcon selectedVoiceIcon; | ||||
|     private static final int REQUEST_CODE_FOR_VOICE_INPUT = 1213; | ||||
| 
 | ||||
|     private RowItemDescriptionBinding binding; | ||||
| 
 | ||||
|     public UploadMediaDetailAdapter(Fragment fragment, String savedLanguageValue, | ||||
|         RecentLanguagesDao recentLanguagesDao) { | ||||
|         RecentLanguagesDao recentLanguagesDao, ActivityResultLauncher<Intent> voiceInputResultLauncher) { | ||||
|         uploadMediaDetails = new ArrayList<>(); | ||||
|         selectedLanguages = new HashMap<>(); | ||||
|         this.savedLanguageValue = savedLanguageValue; | ||||
|         this.recentLanguagesDao = recentLanguagesDao; | ||||
|         this.fragment = fragment; | ||||
|         this.voiceInputResultLauncher = voiceInputResultLauncher; | ||||
|     } | ||||
| 
 | ||||
|     public UploadMediaDetailAdapter(Activity activity, final String savedLanguageValue, | ||||
|         List<UploadMediaDetail> uploadMediaDetails, RecentLanguagesDao recentLanguagesDao) { | ||||
|         List<UploadMediaDetail> uploadMediaDetails, RecentLanguagesDao recentLanguagesDao, ActivityResultLauncher<Intent> voiceInputResultLauncher) { | ||||
|         this.uploadMediaDetails = uploadMediaDetails; | ||||
|         selectedLanguages = new HashMap<>(); | ||||
|         this.savedLanguageValue = savedLanguageValue; | ||||
|         this.recentLanguagesDao = recentLanguagesDao; | ||||
|         this.activity = activity; | ||||
|         this.voiceInputResultLauncher = voiceInputResultLauncher; | ||||
|     } | ||||
| 
 | ||||
|     public void setCallback(Callback callback) { | ||||
|  | @ -150,11 +153,7 @@ public class UploadMediaDetailAdapter extends | |||
|         ); | ||||
| 
 | ||||
|         try { | ||||
|             if (activity == null) { | ||||
|                 fragment.startActivityForResult(intent, REQUEST_CODE_FOR_VOICE_INPUT); | ||||
|             } else { | ||||
|                 activity.startActivityForResult(intent, REQUEST_CODE_FOR_VOICE_INPUT); | ||||
|             } | ||||
|             voiceInputResultLauncher.launch(intent); | ||||
|         } catch (Exception e) { | ||||
|             Timber.e(e.getMessage()); | ||||
|         } | ||||
|  |  | |||
|  | @ -18,6 +18,9 @@ import android.view.ViewGroup; | |||
| import android.widget.CheckBox; | ||||
| import android.widget.ImageView; | ||||
| import android.widget.Toast; | ||||
| import androidx.activity.result.ActivityResult; | ||||
| import androidx.activity.result.ActivityResultLauncher; | ||||
| import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.exifinterface.media.ExifInterface; | ||||
|  | @ -58,9 +61,24 @@ import timber.log.Timber; | |||
| public class UploadMediaDetailFragment extends UploadBaseFragment implements | ||||
|     UploadMediaDetailsContract.View, UploadMediaDetailAdapter.EventListener { | ||||
| 
 | ||||
|     private static final int REQUEST_CODE = 1211; | ||||
|     private static final int REQUEST_CODE_FOR_EDIT_ACTIVITY = 1212; | ||||
|     private static final int REQUEST_CODE_FOR_VOICE_INPUT = 1213; | ||||
|     private UploadMediaDetailAdapter uploadMediaDetailAdapter; | ||||
| 
 | ||||
|     private final ActivityResultLauncher<Intent> startForResult = registerForActivityResult( | ||||
|         new StartActivityForResult(), result -> { | ||||
|                 onCameraPosition(result); | ||||
|         }); | ||||
| 
 | ||||
|     private final ActivityResultLauncher<Intent> startForEditActivityResult = registerForActivityResult( | ||||
|         new StartActivityForResult(), result -> { | ||||
|             onEditActivityResult(result); | ||||
|         } | ||||
|     ); | ||||
| 
 | ||||
|     private final ActivityResultLauncher<Intent> voiceInputResultLauncher = registerForActivityResult( | ||||
|         new StartActivityForResult(), result -> { | ||||
|             onVoiceInput(result); | ||||
|         } | ||||
|     ); | ||||
| 
 | ||||
|     public static Activity activity ; | ||||
| 
 | ||||
|  | @ -84,8 +102,6 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements | |||
|     private boolean hasUserRemovedLocation; | ||||
| 
 | ||||
| 
 | ||||
|     private UploadMediaDetailAdapter uploadMediaDetailAdapter; | ||||
| 
 | ||||
|     @Inject | ||||
|     UploadMediaDetailsContract.UserActionListener presenter; | ||||
| 
 | ||||
|  | @ -279,7 +295,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements | |||
|      */ | ||||
|     private void initRecyclerView() { | ||||
|         uploadMediaDetailAdapter = new UploadMediaDetailAdapter(this, | ||||
|             defaultKvStore.getString(Prefs.DESCRIPTION_LANGUAGE, ""), recentLanguagesDao); | ||||
|             defaultKvStore.getString(Prefs.DESCRIPTION_LANGUAGE, ""), recentLanguagesDao, voiceInputResultLauncher); | ||||
|         uploadMediaDetailAdapter.setCallback(this::showInfoAlert); | ||||
|         uploadMediaDetailAdapter.setEventListener(this); | ||||
|         binding.rvDescriptions.setLayoutManager(new LinearLayoutManager(getContext())); | ||||
|  | @ -593,14 +609,14 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements | |||
|      * This method is called to start the image editing activity for a specific UploadItem. | ||||
|      * It sets the UploadItem as the currently editable item, creates an intent to launch the | ||||
|      * EditActivity, and passes the image file path as an extra in the intent. The activity | ||||
|      * is started with a request code, allowing the result to be handled in onActivityResult. | ||||
|      * is started using resultLauncher that handles the result in respective callback. | ||||
|      */ | ||||
|     @Override | ||||
|     public void showEditActivity(UploadItem uploadItem) { | ||||
|         editableUploadItem = uploadItem; | ||||
|         Intent intent = new Intent(getContext(), EditActivity.class); | ||||
|         intent.putExtra("image", uploadableFile.getFilePath().toString()); | ||||
|         startActivityForResult(intent, REQUEST_CODE_FOR_EDIT_ACTIVITY); | ||||
|         startForEditActivityResult.launch(intent); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -615,6 +631,8 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements | |||
|         double defaultLongitude = -122.431297; | ||||
|         double defaultZoom = 16.0; | ||||
| 
 | ||||
|         final Intent locationPickerIntent; | ||||
| 
 | ||||
|         /* Retrieve image location from EXIF if present or | ||||
|            check if user has provided location while using the in-app camera. | ||||
|            Use location of last UploadItem if none of them is available */ | ||||
|  | @ -624,10 +642,11 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements | |||
|                 .getDecLatitude(); | ||||
|             defaultLongitude = uploadItem.getGpsCoords().getDecLongitude(); | ||||
|             defaultZoom = uploadItem.getGpsCoords().getZoomLevel(); | ||||
|             startActivityForResult(new LocationPicker.IntentBuilder() | ||||
| 
 | ||||
|             locationPickerIntent = new LocationPicker.IntentBuilder() | ||||
|                 .defaultLocation(new CameraPosition(defaultLatitude,defaultLongitude,defaultZoom)) | ||||
|                 .activityKey("UploadActivity") | ||||
|                 .build(getActivity()), REQUEST_CODE); | ||||
|                 .build(getActivity()); | ||||
|         } else { | ||||
|             if (defaultKvStore.getString(LAST_LOCATION) != null) { | ||||
|                 final String[] locationLatLng | ||||
|  | @ -638,27 +657,20 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements | |||
|             if (defaultKvStore.getString(LAST_ZOOM) != null) { | ||||
|                 defaultZoom = Double.parseDouble(defaultKvStore.getString(LAST_ZOOM)); | ||||
|             } | ||||
|             startActivityForResult(new LocationPicker.IntentBuilder() | ||||
| 
 | ||||
|             locationPickerIntent = new LocationPicker.IntentBuilder() | ||||
|                 .defaultLocation(new CameraPosition(defaultLatitude,defaultLongitude,defaultZoom)) | ||||
|                 .activityKey("NoLocationUploadActivity") | ||||
|                 .build(getActivity()), REQUEST_CODE); | ||||
|                 .build(getActivity()); | ||||
|         } | ||||
|         startForResult.launch(locationPickerIntent); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get the coordinates and update the existing coordinates. | ||||
|      * @param requestCode code of request | ||||
|      * @param resultCode code of result | ||||
|      * @param data intent | ||||
|      */ | ||||
|     @Override | ||||
|     public void onActivityResult(final int requestCode, final int resultCode, | ||||
|         @Nullable final Intent data) { | ||||
|         super.onActivityResult(requestCode, resultCode, data); | ||||
|         if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) { | ||||
|     private void onCameraPosition(ActivityResult result){ | ||||
|         if (result.getResultCode() == RESULT_OK) { | ||||
| 
 | ||||
|             assert data != null; | ||||
|             final CameraPosition cameraPosition = LocationPicker.getCameraPosition(data); | ||||
|             assert result.getData() != null; | ||||
|             final CameraPosition cameraPosition = LocationPicker.getCameraPosition(result.getData()); | ||||
| 
 | ||||
|             if (cameraPosition != null) { | ||||
| 
 | ||||
|  | @ -678,8 +690,21 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements | |||
|                 removeLocation(); | ||||
|             } | ||||
|         } | ||||
|         if (requestCode == REQUEST_CODE_FOR_EDIT_ACTIVITY && resultCode == RESULT_OK) { | ||||
|             String result = data.getStringExtra("editedImageFilePath"); | ||||
|     } | ||||
| 
 | ||||
|     private void onVoiceInput(ActivityResult result) { | ||||
|         if (result.getResultCode() == RESULT_OK && result.getData() != null) { | ||||
|             ArrayList<String> resultData = result.getData().getStringArrayListExtra( | ||||
|                 RecognizerIntent.EXTRA_RESULTS); | ||||
|             uploadMediaDetailAdapter.handleSpeechResult(resultData.get(0)); | ||||
|         }else { | ||||
|             Timber.e("Error %s", result.getResultCode()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void onEditActivityResult(ActivityResult result){ | ||||
|         if (result.getResultCode() == RESULT_OK) { | ||||
|             String path = result.getData().getStringExtra("editedImageFilePath"); | ||||
| 
 | ||||
|             if (Objects.equals(result, "Error")) { | ||||
|                 Timber.e("Error in rotating image"); | ||||
|  | @ -687,24 +712,15 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements | |||
|             } | ||||
|             try { | ||||
|                 if (binding != null){ | ||||
|                     binding.backgroundImage.setImageURI(Uri.fromFile(new File(result))); | ||||
|                     binding.backgroundImage.setImageURI(Uri.fromFile(new File(path))); | ||||
|                 } | ||||
|                 editableUploadItem.setContentUri(Uri.fromFile(new File(result))); | ||||
|                 editableUploadItem.setContentUri(Uri.fromFile(new File(path))); | ||||
|                 callback.changeThumbnail(indexOfFragment, | ||||
|                     result); | ||||
|                     path); | ||||
|             } catch (Exception e) { | ||||
|                 Timber.e(e); | ||||
|             } | ||||
|         } | ||||
|         else if (requestCode == REQUEST_CODE_FOR_VOICE_INPUT) { | ||||
|             if (resultCode == RESULT_OK && data != null) { | ||||
|                 ArrayList<String> result = data.getStringArrayListExtra( | ||||
|                     RecognizerIntent.EXTRA_RESULTS); | ||||
|                 uploadMediaDetailAdapter.handleSpeechResult(result.get(0)); | ||||
|             }else { | ||||
|                 Timber.e("Error %s", resultCode); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  |  | |||
|  | @ -54,8 +54,7 @@ public class PermissionUtils { | |||
|         final Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); | ||||
|         final Uri uri = Uri.fromParts("package", activity.getPackageName(), null); | ||||
|         intent.setData(uri); | ||||
|         activity.startActivityForResult(intent, | ||||
|             CommonsApplication.OPEN_APPLICATION_DETAIL_SETTINGS); | ||||
|         activity.startActivity(intent); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  |  | |||
|  | @ -340,20 +340,6 @@ class MainActivityUnitTests { | |||
|         method.invoke(activity, null, true) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @Throws(Exception::class) | ||||
|     fun testOnActivityResult() { | ||||
|         val method: Method = | ||||
|             MainActivity::class.java.getDeclaredMethod( | ||||
|                 "onActivityResult", | ||||
|                 Int::class.java, | ||||
|                 Int::class.java, | ||||
|                 Intent::class.java, | ||||
|             ) | ||||
|         method.isAccessible = true | ||||
|         method.invoke(activity, 0, 0, null) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @Throws(Exception::class) | ||||
|     fun testOnResume() { | ||||
|  |  | |||
|  | @ -1,8 +1,10 @@ | |||
| package fr.free.nrw.commons.customselector.ui.selector | ||||
| 
 | ||||
| import android.app.Activity | ||||
| import android.content.Intent | ||||
| import android.net.Uri | ||||
| import android.os.Bundle | ||||
| import androidx.activity.result.ActivityResult | ||||
| import fr.free.nrw.commons.OkHttpConnectionFactory | ||||
| import fr.free.nrw.commons.TestCommonsApplication | ||||
| import fr.free.nrw.commons.contributions.ContributionDao | ||||
|  | @ -98,20 +100,20 @@ class CustomSelectorActivityTest { | |||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Test onActivityResult function. | ||||
|      * Test callback when result received. | ||||
|      */ | ||||
|     @Test | ||||
|     @Throws(Exception::class) | ||||
|     fun testOnActivityResult() { | ||||
|     fun testResultLauncher() { | ||||
|         val intent = Mockito.mock(Intent::class.java) | ||||
|         val activityResult = ActivityResult(Activity.RESULT_OK, intent) | ||||
|         val func = | ||||
|             activity.javaClass.getDeclaredMethod( | ||||
|                 "onActivityResult", | ||||
|                 Int::class.java, | ||||
|                 Int::class.java, | ||||
|                 Intent::class.java, | ||||
|                 "onFullScreenDataReceived", | ||||
|                 ActivityResult::class.java, | ||||
|             ) | ||||
|         func.isAccessible = true | ||||
|         func.invoke(activity, 512, -1, Mockito.mock(Intent::class.java)) | ||||
|         func.invoke(activity, activityResult) | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  |  | |||
|  | @ -6,18 +6,19 @@ import android.content.Context | |||
| import android.content.Intent | ||||
| import android.content.SharedPreferences | ||||
| import android.net.Uri | ||||
| import android.provider.MediaStore | ||||
| import androidx.activity.result.ActivityResultLauncher | ||||
| import androidx.preference.PreferenceManager | ||||
| import androidx.test.core.app.ApplicationProvider | ||||
| import com.nhaarman.mockitokotlin2.KArgumentCaptor | ||||
| import com.nhaarman.mockitokotlin2.argumentCaptor | ||||
| import com.nhaarman.mockitokotlin2.verify | ||||
| import fr.free.nrw.commons.TestCommonsApplication | ||||
| import fr.free.nrw.commons.filepicker.Constants.RequestCodes | ||||
| import fr.free.nrw.commons.customselector.ui.selector.CustomSelectorActivity | ||||
| import org.junit.Assert.assertEquals | ||||
| import org.junit.Before | ||||
| import org.junit.Test | ||||
| import org.junit.runner.RunWith | ||||
| import org.mockito.ArgumentCaptor | ||||
| import org.mockito.ArgumentMatchers | ||||
| import org.mockito.Captor | ||||
| import org.mockito.Mock | ||||
| import org.mockito.Mockito.mock | ||||
| import org.mockito.Mockito.`when` | ||||
|  | @ -48,8 +49,10 @@ class FilePickerTest { | |||
|     @Mock | ||||
|     var unit: Unit? = null | ||||
| 
 | ||||
|     @Captor | ||||
|     var requestCodeCaptor: ArgumentCaptor<Integer>? = null | ||||
|     @Mock | ||||
|     private lateinit var mockResultLauncher: ActivityResultLauncher<Intent> | ||||
| 
 | ||||
|     private val intentCaptor: KArgumentCaptor<Intent> = argumentCaptor() | ||||
| 
 | ||||
|     private lateinit var context: Context | ||||
| 
 | ||||
|  | @ -65,15 +68,17 @@ class FilePickerTest { | |||
|         `when`(sharedPref.edit()).thenReturn(sharedPreferencesEditor) | ||||
|         `when`(sharedPref.edit().putInt("type", 0)).thenReturn(sharedPreferencesEditor) | ||||
|         val openDocumentPreferred = nextBoolean() | ||||
|         FilePicker.openGallery(activity, 0, openDocumentPreferred) | ||||
|         verify(activity).startActivityForResult( | ||||
|             ArgumentMatchers.any(), | ||||
|             requestCodeCaptor?.capture()?.toInt()!!, | ||||
|         ) | ||||
|         if(openDocumentPreferred){ | ||||
|             assertEquals(requestCodeCaptor?.value, RequestCodes.PICK_PICTURE_FROM_DOCUMENTS) | ||||
|         }else{ | ||||
|             assertEquals(requestCodeCaptor?.value, RequestCodes.PICK_PICTURE_FROM_GALLERY) | ||||
| 
 | ||||
|         FilePicker.openGallery(activity, mockResultLauncher, 0, openDocumentPreferred) | ||||
| 
 | ||||
|         verify(mockResultLauncher).launch(intentCaptor.capture()) | ||||
| 
 | ||||
|         val capturedIntent = intentCaptor.firstValue | ||||
| 
 | ||||
|         if (openDocumentPreferred) { | ||||
|             assertEquals(Intent.ACTION_OPEN_DOCUMENT, capturedIntent.action) | ||||
|         } else { | ||||
|             assertEquals(Intent.ACTION_GET_CONTENT, capturedIntent.action) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -84,12 +89,13 @@ class FilePickerTest { | |||
|         `when`(sharedPref.edit().putInt("type", 0)).thenReturn(sharedPreferencesEditor) | ||||
|         val mockApplication = mock(Application::class.java) | ||||
|         `when`(activity.applicationContext).thenReturn(mockApplication) | ||||
|         FilePicker.openCameraForImage(activity, 0) | ||||
|         verify(activity).startActivityForResult( | ||||
|             ArgumentMatchers.any(), | ||||
|             requestCodeCaptor?.capture()?.toInt()!!, | ||||
|         ) | ||||
|         assertEquals(requestCodeCaptor?.value, RequestCodes.TAKE_PICTURE) | ||||
|         FilePicker.openCameraForImage(activity, mockResultLauncher, 0) | ||||
| 
 | ||||
|         verify(mockResultLauncher).launch(intentCaptor.capture()) | ||||
| 
 | ||||
|         val capturedIntent = intentCaptor.firstValue | ||||
|          | ||||
|         assertEquals(MediaStore.ACTION_IMAGE_CAPTURE, capturedIntent.action) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|  | @ -183,46 +189,20 @@ class FilePickerTest { | |||
|         method.invoke(mockFilePicker, mockIntent) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun testHandleActivityResultCaseOne() { | ||||
|         val mockIntent = mock(Intent::class.java) | ||||
|         FilePicker.handleActivityResult( | ||||
|             RequestCodes.FILE_PICKER_IMAGE_IDENTIFICATOR, | ||||
|             Activity.RESULT_OK, | ||||
|             mockIntent, | ||||
|             activity, | ||||
|             object : DefaultCallback() { | ||||
|                 override fun onCanceled( | ||||
|                     source: FilePicker.ImageSource, | ||||
|                     type: Int, | ||||
|                 ) { | ||||
|                     super.onCanceled(source, type) | ||||
|                 } | ||||
| 
 | ||||
|                 override fun onImagePickerError( | ||||
|                     e: Exception, | ||||
|                     source: FilePicker.ImageSource, | ||||
|                     type: Int, | ||||
|                 ) { | ||||
|                 } | ||||
| 
 | ||||
|                 override fun onImagesPicked( | ||||
|                     imagesFiles: List<UploadableFile>, | ||||
|                     source: FilePicker.ImageSource, | ||||
|                     type: Int, | ||||
|                 ) { | ||||
|                 } | ||||
|             }, | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun testOpenCustomSelectorRequestCode() { | ||||
|         `when`(PreferenceManager.getDefaultSharedPreferences(activity)).thenReturn(sharedPref) | ||||
|         `when`(sharedPref.edit()).thenReturn(sharedPreferencesEditor) | ||||
|         `when`(sharedPref.edit().putInt("type", 0)).thenReturn(sharedPreferencesEditor) | ||||
|         FilePicker.openCustomSelector(activity, 0) | ||||
|         verify(activity).startActivityForResult(ArgumentMatchers.any(), requestCodeCaptor?.capture()?.toInt()!!) | ||||
|         assertEquals(requestCodeCaptor?.value, RequestCodes.PICK_PICTURE_FROM_CUSTOM_SELECTOR) | ||||
|         FilePicker.openCustomSelector(activity, mockResultLauncher, 0) | ||||
| 
 | ||||
|         verify(mockResultLauncher).launch(intentCaptor.capture()) | ||||
| 
 | ||||
|         val capturedIntent = intentCaptor.firstValue | ||||
| 
 | ||||
|         assertEquals( | ||||
|             CustomSelectorActivity.Companion::class.java.declaringClass.name, | ||||
|             capturedIntent.component?.className | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ import android.widget.ProgressBar | |||
| import android.widget.ScrollView | ||||
| import android.widget.Spinner | ||||
| import android.widget.TextView | ||||
| import androidx.activity.result.ActivityResult | ||||
| import androidx.fragment.app.FragmentManager | ||||
| import androidx.fragment.app.FragmentTransaction | ||||
| import androidx.test.core.app.ApplicationProvider | ||||
|  | @ -76,7 +77,6 @@ import java.util.Locale | |||
| @Config(sdk = [21], application = TestCommonsApplication::class) | ||||
| @LooperMode(LooperMode.Mode.PAUSED) | ||||
| class MediaDetailFragmentUnitTests { | ||||
|     private val requestCode = 1001 | ||||
|     private val lastLocation = "last_location_while_uploading" | ||||
|     private lateinit var fragment: MediaDetailFragment | ||||
|     private lateinit var fragmentManager: FragmentManager | ||||
|  | @ -231,24 +231,6 @@ class MediaDetailFragmentUnitTests { | |||
|         fragment.onCreateView(layoutInflater, null, savedInstanceState) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @Throws(Exception::class) | ||||
|     fun testOnActivityResultLocationPickerActivity() { | ||||
|         fragment.onActivityResult(requestCode, Activity.RESULT_CANCELED, intent) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @Throws(Exception::class) | ||||
|     fun `test OnActivity Result Cancelled LocationPickerActivity`() { | ||||
|         fragment.onActivityResult(requestCode, Activity.RESULT_CANCELED, intent) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @Throws(Exception::class) | ||||
|     fun `test OnActivity Result Cancelled DescriptionEditActivity`() { | ||||
|         fragment.onActivityResult(requestCode, Activity.RESULT_OK, intent) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @Throws(Exception::class) | ||||
|     fun testOnSaveInstanceState() { | ||||
|  |  | |||
|  | @ -167,20 +167,6 @@ class UploadActivityUnitTests { | |||
|         activity.makeUploadRequest() | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @Throws(Exception::class) | ||||
|     fun testOnActivityResult() { | ||||
|         val method: Method = | ||||
|             UploadActivity::class.java.getDeclaredMethod( | ||||
|                 "onActivityResult", | ||||
|                 Int::class.java, | ||||
|                 Int::class.java, | ||||
|                 Intent::class.java, | ||||
|             ) | ||||
|         method.isAccessible = true | ||||
|         method.invoke(activity, CommonsApplication.OPEN_APPLICATION_DETAIL_SETTINGS, 0, Intent()) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @Throws(Exception::class) | ||||
|     fun testReceiveSharedItems() { | ||||
|  |  | |||
|  | @ -2,11 +2,13 @@ package fr.free.nrw.commons.upload | |||
| 
 | ||||
| import android.app.Dialog | ||||
| import android.content.Context | ||||
| import android.content.Intent | ||||
| import android.view.View | ||||
| import android.widget.AdapterView | ||||
| import android.widget.GridLayout | ||||
| import android.widget.ListView | ||||
| import android.widget.TextView | ||||
| import androidx.activity.result.ActivityResultLauncher | ||||
| import androidx.test.core.app.ApplicationProvider | ||||
| import com.nhaarman.mockitokotlin2.any | ||||
| import com.nhaarman.mockitokotlin2.times | ||||
|  | @ -67,13 +69,16 @@ class UploadMediaDetailAdapterUnitTest { | |||
|     @Mock | ||||
|     private lateinit var adapterView: AdapterView<RecentLanguagesAdapter> | ||||
| 
 | ||||
|     @Mock | ||||
|     private lateinit var mockResultLauncher: ActivityResultLauncher<Intent> | ||||
| 
 | ||||
|     @Before | ||||
|     fun setUp() { | ||||
|         MockitoAnnotations.openMocks(this) | ||||
|         uploadMediaDetails = mutableListOf(uploadMediaDetail, uploadMediaDetail) | ||||
|         activity = Robolectric.buildActivity(UploadActivity::class.java).get() | ||||
|         fragment = mock(UploadMediaDetailFragment::class.java) | ||||
|         adapter = UploadMediaDetailAdapter(fragment, "", recentLanguagesDao) | ||||
|         adapter = UploadMediaDetailAdapter(fragment, "", recentLanguagesDao, mockResultLauncher) | ||||
|         context = ApplicationProvider.getApplicationContext() | ||||
|         Whitebox.setInternalState(adapter, "uploadMediaDetails", uploadMediaDetails) | ||||
|         Whitebox.setInternalState(adapter, "eventListener", eventListener) | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ import android.view.View | |||
| import android.widget.ImageView | ||||
| import android.widget.LinearLayout | ||||
| import android.widget.TextView | ||||
| import androidx.activity.result.ActivityResult | ||||
| import androidx.appcompat.widget.AppCompatButton | ||||
| import androidx.appcompat.widget.AppCompatImageButton | ||||
| import androidx.fragment.app.FragmentManager | ||||
|  | @ -348,7 +349,7 @@ class UploadMediaDetailFragmentUnitTest { | |||
| 
 | ||||
|     @Test | ||||
|     @Throws(Exception::class) | ||||
|     fun testOnActivityResultOnMapIconClicked() { | ||||
|     fun testOnCameraPositionCallbackOnMapIconClicked() { | ||||
|         shadowOf(Looper.getMainLooper()).idle() | ||||
|         Mockito.mock(LocationPicker::class.java) | ||||
|         val intent = Mockito.mock(Intent::class.java) | ||||
|  | @ -363,13 +364,18 @@ class UploadMediaDetailFragmentUnitTest { | |||
|         `when`(latLng.latitude).thenReturn(0.0) | ||||
|         `when`(latLng.longitude).thenReturn(0.0) | ||||
|         `when`(uploadItem.gpsCoords).thenReturn(imageCoordinates) | ||||
|         fragment.onActivityResult(1211, Activity.RESULT_OK, intent) | ||||
|         val activityResult = ActivityResult(Activity.RESULT_OK, intent) | ||||
| 
 | ||||
|         val handleResultMethod = UploadMediaDetailFragment::class.java.getDeclaredMethod("onCameraPosition", ActivityResult::class.java) | ||||
|         handleResultMethod.isAccessible = true | ||||
| 
 | ||||
|         handleResultMethod.invoke(fragment, activityResult) | ||||
|         Mockito.verify(presenter, Mockito.times(0)).getImageQuality(0, location, activity) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @Throws(Exception::class) | ||||
|     fun testOnActivityResultAddLocationDialog() { | ||||
|     fun testOnCameraPositionCallbackAddLocationDialog() { | ||||
|         shadowOf(Looper.getMainLooper()).idle() | ||||
|         Mockito.mock(LocationPicker::class.java) | ||||
|         val intent = Mockito.mock(Intent::class.java) | ||||
|  | @ -387,7 +393,13 @@ class UploadMediaDetailFragmentUnitTest { | |||
|         `when`(latLng.latitude).thenReturn(0.0) | ||||
|         `when`(latLng.longitude).thenReturn(0.0) | ||||
|         `when`(uploadItem.gpsCoords).thenReturn(imageCoordinates) | ||||
|         fragment.onActivityResult(1211, Activity.RESULT_OK, intent) | ||||
| 
 | ||||
|         val activityResult = ActivityResult(Activity.RESULT_OK,intent) | ||||
| 
 | ||||
|         val handleResultMethod = UploadMediaDetailFragment::class.java.getDeclaredMethod("onCameraPosition", ActivityResult::class.java) | ||||
|         handleResultMethod.isAccessible = true | ||||
| 
 | ||||
|         handleResultMethod.invoke(fragment, activityResult) | ||||
|         Mockito.verify(presenter, Mockito.times(1)).displayLocDialog(0, null, false) | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 u7119288
						u7119288