mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 18:00:02 +01:00
Add selected photos access.
This commit is contained in:
committed by
mtang-signal
parent
4f001a0c95
commit
57adab858c
@@ -308,9 +308,9 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
|
||||
})
|
||||
.onSomePermanentlyDenied(deniedPermissions -> {
|
||||
if (deniedPermissions.containsAll(List.of(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO))) {
|
||||
showPermissionFragment(R.string.CameraXFragment_allow_access_camera_microphone, R.string.CameraXFragment_to_capture_photos_videos).show(getParentFragmentManager(), BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG);
|
||||
showPermissionFragment(R.string.CameraXFragment_allow_access_camera_microphone, R.string.CameraXFragment_to_capture_photos_videos, false).show(getParentFragmentManager(), BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG);
|
||||
} else if (deniedPermissions.contains(Manifest.permission.CAMERA)) {
|
||||
showPermissionFragment(R.string.CameraXFragment_allow_access_camera, R.string.CameraXFragment_to_capture_photos_videos).show(getParentFragmentManager(), BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG);
|
||||
showPermissionFragment(R.string.CameraXFragment_allow_access_camera, R.string.CameraXFragment_to_capture_photos_videos, false).show(getParentFragmentManager(), BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG);
|
||||
}
|
||||
})
|
||||
.onSomeDenied(deniedPermissions -> {
|
||||
|
||||
@@ -55,7 +55,7 @@ public class MediaRepository {
|
||||
* Retrieves a list of folders that contain media.
|
||||
*/
|
||||
public void getFolders(@NonNull Context context, @NonNull Callback<List<MediaFolder>> callback) {
|
||||
if (!StorageUtil.canReadFromMediaStore()) {
|
||||
if (!StorageUtil.canReadAnyFromMediaStore()) {
|
||||
Log.w(TAG, "No storage permissions!", new Throwable());
|
||||
callback.onComplete(Collections.emptyList());
|
||||
return;
|
||||
@@ -69,7 +69,7 @@ public class MediaRepository {
|
||||
*/
|
||||
public Single<List<Media>> getRecentMedia() {
|
||||
return Single.<List<Media>>fromCallable(() -> {
|
||||
if (!StorageUtil.canReadFromMediaStore()) {
|
||||
if (!StorageUtil.canReadAnyFromMediaStore()) {
|
||||
Log.w(TAG, "No storage permissions!", new Throwable());
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -87,7 +87,7 @@ public class MediaRepository {
|
||||
* Retrieves a list of media items (images and videos) that are present int he specified bucket.
|
||||
*/
|
||||
public void getMediaInBucket(@NonNull Context context, @NonNull String bucketId, @NonNull Callback<List<Media>> callback) {
|
||||
if (!StorageUtil.canReadFromMediaStore()) {
|
||||
if (!StorageUtil.canReadAnyFromMediaStore()) {
|
||||
Log.w(TAG, "No storage permissions!", new Throwable());
|
||||
callback.onComplete(Collections.emptyList());
|
||||
return;
|
||||
@@ -106,7 +106,7 @@ public class MediaRepository {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!StorageUtil.canReadFromMediaStore()) {
|
||||
if (!StorageUtil.canReadAnyFromMediaStore()) {
|
||||
Log.w(TAG, "No storage permissions!", new Throwable());
|
||||
callback.onComplete(media);
|
||||
return;
|
||||
@@ -117,7 +117,7 @@ public class MediaRepository {
|
||||
}
|
||||
|
||||
void getMostRecentItem(@NonNull Context context, @NonNull Callback<Optional<Media>> callback) {
|
||||
if (!StorageUtil.canReadFromMediaStore()) {
|
||||
if (!StorageUtil.canReadAnyFromMediaStore()) {
|
||||
Log.w(TAG, "No storage permissions!", new Throwable());
|
||||
callback.onComplete(Optional.empty());
|
||||
return;
|
||||
|
||||
@@ -29,7 +29,7 @@ class MediaCaptureRepository(context: Context) {
|
||||
private val context: Context = context.applicationContext
|
||||
|
||||
fun getMostRecentItem(callback: (Media?) -> Unit) {
|
||||
if (!StorageUtil.canReadFromMediaStore()) {
|
||||
if (!StorageUtil.canReadAnyFromMediaStore()) {
|
||||
Log.w(TAG, "Cannot read from storage.")
|
||||
callback(null)
|
||||
return
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.mediasend.v2.gallery
|
||||
import android.Manifest
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
@@ -17,6 +18,7 @@ import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import org.signal.core.util.Stopwatch
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.recyclerview.GridDividerDecoration
|
||||
import org.thoughtcrime.securesms.conversation.ManageContextMenu
|
||||
import org.thoughtcrime.securesms.databinding.V2MediaGalleryFragmentBinding
|
||||
import org.thoughtcrime.securesms.mediasend.Media
|
||||
import org.thoughtcrime.securesms.mediasend.MediaRepository
|
||||
@@ -24,6 +26,7 @@ import org.thoughtcrime.securesms.mediasend.camerax.CameraXUtil
|
||||
import org.thoughtcrime.securesms.permissions.PermissionCompat
|
||||
import org.thoughtcrime.securesms.permissions.Permissions
|
||||
import org.thoughtcrime.securesms.util.Material3OnScrollHelper
|
||||
import org.thoughtcrime.securesms.util.StorageUtil
|
||||
import org.thoughtcrime.securesms.util.SystemWindowInsetsSetter
|
||||
import org.thoughtcrime.securesms.util.ViewUtil
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||
@@ -164,8 +167,6 @@ class MediaGalleryFragment : Fragment(R.layout.v2_media_gallery_fragment) {
|
||||
binding.mediaGalleryToolbar.title = state.bucketTitle ?: requireContext().getString(R.string.AttachmentKeyboard_gallery)
|
||||
}
|
||||
|
||||
binding.mediaGalleryAllowAccess.setOnClickListener { requestRequiredPermissions() }
|
||||
|
||||
val galleryItemsWithSelection = LiveDataUtil.combineLatest(
|
||||
viewModel.state.map { it.items },
|
||||
viewStateLiveData.map { it.selectedMedia }
|
||||
@@ -180,20 +181,44 @@ class MediaGalleryFragment : Fragment(R.layout.v2_media_gallery_fragment) {
|
||||
}
|
||||
|
||||
galleryItemsWithSelection.observe(viewLifecycleOwner) {
|
||||
if (!Permissions.hasAll(requireContext(), *PermissionCompat.forImagesAndVideos())) {
|
||||
binding.mediaGalleryMissingPermissions.visibility = View.VISIBLE
|
||||
shouldEnableScrolling = false
|
||||
galleryAdapter.submitList((1..100).map { MediaGallerySelectableItem.PlaceholderModel() })
|
||||
} else {
|
||||
binding.mediaGalleryMissingPermissions.visibility = View.GONE
|
||||
if (StorageUtil.canReadAllFromMediaStore()) {
|
||||
binding.mediaGalleryMissingPermissions.visible = false
|
||||
binding.mediaGalleryManageContainer.visible = false
|
||||
shouldEnableScrolling = true
|
||||
galleryAdapter.submitList(it)
|
||||
} else if (StorageUtil.canOnlyReadSelectedMediaStore() && it.isEmpty()) {
|
||||
binding.mediaGalleryMissingPermissions.visible = true
|
||||
binding.mediaGalleryManageContainer.visible = false
|
||||
binding.mediaGalleryPermissionText.text = getString(R.string.MediaGalleryFragment__no_photos_found)
|
||||
binding.mediaGalleryAllowAccess.text = getString(R.string.AttachmentKeyboard_manage)
|
||||
binding.mediaGalleryAllowAccess.setOnClickListener { v -> showManageContextMenu(v, v.parent as ViewGroup, false, true) }
|
||||
shouldEnableScrolling = false
|
||||
galleryAdapter.submitList((1..100).map { MediaGallerySelectableItem.PlaceholderModel() })
|
||||
} else if (StorageUtil.canOnlyReadSelectedMediaStore()) {
|
||||
binding.mediaGalleryMissingPermissions.visible = false
|
||||
binding.mediaGalleryManageContainer.visible = true
|
||||
binding.mediaGalleryManageButton.setOnClickListener { v -> showManageContextMenu(v, v.rootView as ViewGroup, false, false) }
|
||||
shouldEnableScrolling = true
|
||||
galleryAdapter.submitList(it)
|
||||
} else {
|
||||
binding.mediaGalleryMissingPermissions.visible = true
|
||||
binding.mediaGalleryManageContainer.visible = false
|
||||
binding.mediaGalleryPermissionText.text = getString(R.string.AttachmentKeyboard_Signal_needs_permission_to_show_your_photos_and_videos)
|
||||
binding.mediaGalleryAllowAccess.text = getString(R.string.AttachmentKeyboard_allow_access)
|
||||
binding.mediaGalleryAllowAccess.setOnClickListener { requestRequiredPermissions() }
|
||||
shouldEnableScrolling = false
|
||||
galleryAdapter.submitList((1..100).map { MediaGallerySelectableItem.PlaceholderModel() })
|
||||
}
|
||||
}
|
||||
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, onBackPressedCallback)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
refreshMediaGallery()
|
||||
}
|
||||
|
||||
private fun refreshMediaGallery() {
|
||||
viewModel.refreshMediaGallery()
|
||||
}
|
||||
@@ -203,13 +228,37 @@ class MediaGalleryFragment : Fragment(R.layout.v2_media_gallery_fragment) {
|
||||
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults)
|
||||
}
|
||||
|
||||
private fun showManageContextMenu(view: View, rootView: ViewGroup, showAbove: Boolean, showAtStart: Boolean) {
|
||||
ManageContextMenu.show(
|
||||
context = requireContext(),
|
||||
anchorView = view,
|
||||
rootView = rootView,
|
||||
showAbove = showAbove,
|
||||
showAtStart = showAtStart,
|
||||
onSelectMore = { selectMorePhotos() },
|
||||
onSettings = { requireContext().startActivity(Permissions.getApplicationSettingsIntent(requireContext())) }
|
||||
)
|
||||
}
|
||||
|
||||
private fun selectMorePhotos() {
|
||||
Permissions.with(requireParentFragment())
|
||||
.request(*PermissionCompat.forImagesAndVideos())
|
||||
.onAnyResult { refreshMediaGallery() }
|
||||
.execute()
|
||||
}
|
||||
|
||||
private fun requestRequiredPermissions() {
|
||||
Permissions.with(this)
|
||||
.request(*PermissionCompat.forImagesAndVideos())
|
||||
.ifNecessary()
|
||||
.onAllGranted { refreshMediaGallery() }
|
||||
.withPermanentDenialDialog(getString(R.string.AttachmentManager_signal_requires_the_external_storage_permission_in_order_to_attach_photos_videos_or_audio), null, R.string.AttachmentManager_signal_allow_storage, R.string.AttachmentManager_signal_to_show_photos, parentFragmentManager)
|
||||
.onAnyDenied { Toast.makeText(requireContext(), R.string.AttachmentManager_signal_needs_storage_access, Toast.LENGTH_LONG).show() }
|
||||
.onAnyResult { refreshMediaGallery() }
|
||||
.withPermanentDenialDialog(getString(R.string.AttachmentManager_signal_requires_the_external_storage_permission_in_order_to_attach_photos_videos_or_audio), null, R.string.AttachmentManager_signal_allow_storage, R.string.AttachmentManager_signal_to_show_photos, true, parentFragmentManager)
|
||||
.onSomeDenied {
|
||||
val deniedPermission = PermissionCompat.getRequiredPermissionsForDenial()
|
||||
if (it.containsAll(deniedPermission.toList())) {
|
||||
Toast.makeText(requireContext(), R.string.AttachmentManager_signal_needs_storage_access, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
.execute()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user