diff --git a/app/src/main/java/awais/instagrabber/adapters/MediaItemsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/MediaItemsAdapter.java deleted file mode 100644 index e76429ef..00000000 --- a/app/src/main/java/awais/instagrabber/adapters/MediaItemsAdapter.java +++ /dev/null @@ -1,111 +0,0 @@ -package awais.instagrabber.adapters; - -import android.net.Uri; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.DiffUtil; -import androidx.recyclerview.widget.ListAdapter; -import androidx.recyclerview.widget.RecyclerView; - -import com.facebook.drawee.backends.pipeline.Fresco; -import com.facebook.drawee.backends.pipeline.PipelineDraweeControllerBuilder; -import com.facebook.drawee.controller.BaseControllerListener; -import com.facebook.imagepipeline.common.ResizeOptions; -import com.facebook.imagepipeline.image.ImageInfo; -import com.facebook.imagepipeline.request.ImageRequest; -import com.facebook.imagepipeline.request.ImageRequestBuilder; - -import java.io.File; - -import awais.instagrabber.databinding.ItemMediaBinding; -import awais.instagrabber.utils.MediaController.MediaEntry; -import awais.instagrabber.utils.TextUtils; -import awais.instagrabber.utils.Utils; - -public class MediaItemsAdapter extends ListAdapter { - - private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() { - @Override - public boolean areItemsTheSame(@NonNull final MediaEntry oldItem, @NonNull final MediaEntry newItem) { - return oldItem.imageId == newItem.imageId; - } - - @Override - public boolean areContentsTheSame(@NonNull final MediaEntry oldItem, @NonNull final MediaEntry newItem) { - return oldItem.imageId == newItem.imageId; - } - }; - - private final OnItemClickListener onItemClickListener; - - public MediaItemsAdapter(final OnItemClickListener onItemClickListener) { - super(diffCallback); - this.onItemClickListener = onItemClickListener; - } - - @NonNull - @Override - public MediaItemViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) { - final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); - final ItemMediaBinding binding = ItemMediaBinding.inflate(layoutInflater, parent, false); - return new MediaItemViewHolder(binding, onItemClickListener); - } - - @Override - public void onBindViewHolder(@NonNull final MediaItemViewHolder holder, final int position) { - holder.bind(getItem(position)); - } - - public static class MediaItemViewHolder extends RecyclerView.ViewHolder { - private static final String TAG = MediaItemViewHolder.class.getSimpleName(); - private static final int size = Utils.displayMetrics.widthPixels / 3; - - private final ItemMediaBinding binding; - private final OnItemClickListener onItemClickListener; - - public MediaItemViewHolder(@NonNull final ItemMediaBinding binding, - final OnItemClickListener onItemClickListener) { - super(binding.getRoot()); - this.binding = binding; - this.onItemClickListener = onItemClickListener; - } - - public void bind(final MediaEntry item) { - final Uri uri = Uri.fromFile(new File(item.path)); - if (onItemClickListener != null) { - itemView.setOnClickListener(v -> onItemClickListener.onItemClick(item)); - } - final BaseControllerListener controllerListener = new BaseControllerListener() { - @Override - public void onFailure(final String id, final Throwable throwable) { - Log.e(TAG, "onFailure: ", throwable); - } - }; - final ImageRequest request = ImageRequestBuilder - .newBuilderWithSource(uri) - .setLocalThumbnailPreviewsEnabled(true) - .setProgressiveRenderingEnabled(false) - .setResizeOptions(ResizeOptions.forDimensions(size, size)) - .build(); - final PipelineDraweeControllerBuilder builder = Fresco.newDraweeControllerBuilder() - .setImageRequest(request) - .setControllerListener(controllerListener); - binding.item.setController(builder.build()); - if (item.isVideo && item.duration >= 0) { - final String timeString = TextUtils.millisToTimeString(item.duration); - binding.duration.setVisibility(View.VISIBLE); - binding.duration.setText(timeString); - } else { - binding.duration.setVisibility(View.GONE); - } - } - } - - public interface OnItemClickListener { - void onItemClick(MediaEntry entry); - } -} diff --git a/app/src/main/java/awais/instagrabber/dialogs/MediaPickerBottomDialogFragment.java b/app/src/main/java/awais/instagrabber/dialogs/MediaPickerBottomDialogFragment.java deleted file mode 100644 index d36cb9dd..00000000 --- a/app/src/main/java/awais/instagrabber/dialogs/MediaPickerBottomDialogFragment.java +++ /dev/null @@ -1,194 +0,0 @@ -package awais.instagrabber.dialogs; - -import android.app.Dialog; -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.DialogFragment; -import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.GridLayoutManager; - -import com.google.android.material.bottomsheet.BottomSheetDialog; -import com.google.android.material.bottomsheet.BottomSheetDialogFragment; - -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import awais.instagrabber.R; -import awais.instagrabber.adapters.MediaItemsAdapter; -import awais.instagrabber.databinding.LayoutMediaPickerBinding; -import awais.instagrabber.utils.MediaController; -import awais.instagrabber.utils.PermissionUtils; -import awais.instagrabber.utils.TextUtils; -import awais.instagrabber.viewmodels.MediaPickerViewModel; - -public class MediaPickerBottomDialogFragment extends BottomSheetDialogFragment { - private static final String TAG = MediaPickerBottomDialogFragment.class.getSimpleName(); - private static final int ATTACH_MEDIA_REQUEST_CODE = 100; - // private static final int HEIGHT_PIXELS = Utils.displayMetrics.heightPixels; - - private LayoutMediaPickerBinding binding; - private MediaPickerViewModel viewModel; - private MediaItemsAdapter mediaItemsAdapter; - private OnSelectListener onSelectListener; - // private int actionBarHeight; - // private int statusBarHeight; - - // private final BottomSheetBehavior.BottomSheetCallback bottomSheetCallback = new BottomSheetBehavior.BottomSheetCallback() { - // @Override - // public void onStateChanged(@NonNull final View bottomSheet, final int newState) { - // - // } - // - // @Override - // public void onSlide(@NonNull final View bottomSheet, final float slideOffset) { - // // Log.d(TAG, "onSlide: " + slideOffset); - // final float sheetHeight = HEIGHT_PIXELS * slideOffset; - // final Context context = getContext(); - // if (context == null) return; - // final float remaining = HEIGHT_PIXELS - sheetHeight - statusBarHeight; - // if (remaining <= actionBarHeight) { - // final ViewGroup.LayoutParams layoutParams = binding.toolbar.getLayoutParams(); - // layoutParams.height = (int) (actionBarHeight - remaining); - // binding.toolbar.requestLayout(); - // } - // } - // }; - - public static MediaPickerBottomDialogFragment newInstance() { - final Bundle args = new Bundle(); - final MediaPickerBottomDialogFragment fragment = new MediaPickerBottomDialogFragment(); - fragment.setArguments(args); - return fragment; - } - - @Override - public void onCreate(@Nullable final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setStyle(DialogFragment.STYLE_NORMAL, R.style.ThemeOverlay_Rounded_BottomSheetDialog); - } - - @Nullable - @Override - public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) { - binding = LayoutMediaPickerBinding.inflate(inflater, container, false); - viewModel = new ViewModelProvider(this).get(MediaPickerViewModel.class); - // final Context context = getContext(); - // if (context == null) return binding.getRoot(); - // actionBarHeight = Utils.getActionBarHeight(context); - // statusBarHeight = Utils.getStatusBarHeight(context); - return binding.getRoot(); - } - - @Override - public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { - init(); - // final Dialog dialog = getDialog(); - // if (dialog == null) return; - // dialog.setOnShowListener(dialog1 -> { - // final BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) dialog; - // final View bottomSheetInternal = bottomSheetDialog.findViewById(com.google.android.material.R.id.design_bottom_sheet); - // if (bottomSheetInternal == null) return; - // final BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheetInternal); - // behavior.setState(BottomSheetBehavior.STATE_EXPANDED); - // }); - } - - @Override - public void onStart() { - super.onStart(); - final Dialog dialog = getDialog(); - if (dialog == null) return; - final BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) dialog; - final View bottomSheetInternal = bottomSheetDialog.findViewById(com.google.android.material.R.id.design_bottom_sheet); - if (bottomSheetInternal == null) return; - bottomSheetInternal.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT; - bottomSheetInternal.requestLayout(); - // final BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheetInternal); - // behavior.addBottomSheetCallback(bottomSheetCallback); - } - - @Override - public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) { - if (requestCode == ATTACH_MEDIA_REQUEST_CODE) { - final Context context = getContext(); - if (context == null) return; - final boolean hasAttachMediaPerms = PermissionUtils.hasAttachMediaPerms(context); - if (hasAttachMediaPerms) { - viewModel.loadMedia(context); - } - } - } - - private void init() { - setupList(); - setupAlbumPicker(); - final Context context = getContext(); - if (context == null) return; - if (!PermissionUtils.hasAttachMediaPerms(context)) { - PermissionUtils.requestAttachMediaPerms(this, ATTACH_MEDIA_REQUEST_CODE); - return; - } - viewModel.loadMedia(context); - } - - private void setupList() { - final Context context = getContext(); - if (context == null) return; - binding.mediaList.setLayoutManager(new GridLayoutManager(context, 3)); - binding.mediaList.setHasFixedSize(true); - mediaItemsAdapter = new MediaItemsAdapter(entry -> { - if (onSelectListener == null) return; - onSelectListener.onSelect(entry); - }); - binding.mediaList.setAdapter(mediaItemsAdapter); - } - - private void setupAlbumPicker() { - final Context context = getContext(); - if (context == null) return; - final ArrayAdapter albumPickerAdapter = new ArrayAdapter<>(context, android.R.layout.simple_spinner_item); - albumPickerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - binding.albumPicker.setAdapter(albumPickerAdapter); - binding.albumPicker.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(final AdapterView parent, final View view, final int position, final long id) { - final List albumEntries = viewModel.getAllAlbums().getValue(); - if (albumEntries == null) return; - final MediaController.AlbumEntry albumEntry = albumEntries.get(position); - mediaItemsAdapter.submitList(albumEntry.photos, () -> binding.mediaList.scrollToPosition(0)); - } - - @Override - public void onNothingSelected(final AdapterView parent) { - mediaItemsAdapter.submitList(Collections.emptyList()); - } - }); - viewModel.getAllAlbums().observe(getViewLifecycleOwner(), albums -> { - albumPickerAdapter.clear(); - albumPickerAdapter.addAll(albums.stream() - .map(albumEntry -> albumEntry.bucketName) - .filter(name -> !TextUtils.isEmpty(name)) - .collect(Collectors.toList())); - albumPickerAdapter.notifyDataSetChanged(); - if (albums.isEmpty()) return; - mediaItemsAdapter.submitList(albums.get(0).photos); - }); - } - - public void setOnSelectListener(final OnSelectListener onSelectListener) { - this.onSelectListener = onSelectListener; - } - - public interface OnSelectListener { - void onSelect(MediaController.MediaEntry entry); - } -} diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java index 72a8568b..b9b91fa1 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java @@ -8,11 +8,11 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.Intent; -import android.content.pm.PackageManager; import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; +import android.provider.DocumentsContract; import android.text.Editable; import android.util.Log; import android.util.Pair; @@ -32,7 +32,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.appcompat.view.menu.ActionMenuItemView; -import androidx.core.content.ContextCompat; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsAnimationCompat; import androidx.core.view.WindowInsetsAnimationControlListenerCompat; @@ -97,7 +96,6 @@ import awais.instagrabber.customviews.helpers.TranslateDeferringInsetsAnimationC import awais.instagrabber.databinding.FragmentDirectMessagesThreadBinding; import awais.instagrabber.dialogs.DirectItemReactionDialogFragment; import awais.instagrabber.dialogs.GifPickerBottomDialogFragment; -import awais.instagrabber.dialogs.MediaPickerBottomDialogFragment; import awais.instagrabber.fragments.PostViewV2Fragment; import awais.instagrabber.fragments.UserSearchFragment; import awais.instagrabber.fragments.UserSearchFragmentDirections; @@ -130,6 +128,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact private static final String TAG = DirectMessageThreadFragment.class.getSimpleName(); private static final int AUDIO_RECORD_PERM_REQUEST_CODE = 1000; private static final int CAMERA_REQUEST_CODE = 200; + private static final int FILE_PICKER_REQUEST_CODE = 500; private static final String TRANSLATION_Y = "translationY"; private DirectItemsAdapter itemsAdapter; @@ -474,6 +473,24 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact @Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); + if (requestCode == FILE_PICKER_REQUEST_CODE && resultCode == Activity.RESULT_OK) { + if (data == null || data.getData() == null) { + Log.w(TAG, "data is null!"); + return; + } + final Context context = getContext(); + if (context == null) { + Log.w(TAG, "conetxt is null!"); + return; + } + final Uri uri = data.getData(); + final String mimeType = Utils.getMimeType(uri, context.getContentResolver()); + if (mimeType.startsWith("image")) { + navigateToImageEditFragment(uri); + return; + } + handleSentMessage(viewModel.sendUri(uri)); + } if (requestCode == CAMERA_REQUEST_CODE && resultCode == Activity.RESULT_OK) { if (data == null || data.getData() == null) { Log.w(TAG, "data is null!"); @@ -1109,17 +1126,15 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact setupInsetsCallback(); setupEmojiPicker(); binding.gallery.setOnClickListener(v -> { - final MediaPickerBottomDialogFragment mediaPicker = MediaPickerBottomDialogFragment.newInstance(); - mediaPicker.setOnSelectListener(entry -> { - mediaPicker.dismiss(); - if (!isAdded()) return; - if (!entry.isVideo) { - navigateToImageEditFragment(entry.path); - return; - } - handleSentMessage(viewModel.sendUri(entry)); + final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + intent.setType("*/*"); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[]{ + "image/*", + "video/mp4" }); - mediaPicker.show(getChildFragmentManager(), "MediaPicker"); + startActivityForResult(intent, FILE_PICKER_REQUEST_CODE); }); binding.gif.setOnClickListener(v -> { final GifPickerBottomDialogFragment gifPicker = GifPickerBottomDialogFragment.newInstance(); diff --git a/app/src/main/java/awais/instagrabber/managers/ThreadManager.kt b/app/src/main/java/awais/instagrabber/managers/ThreadManager.kt index 88517de9..40c52457 100644 --- a/app/src/main/java/awais/instagrabber/managers/ThreadManager.kt +++ b/app/src/main/java/awais/instagrabber/managers/ThreadManager.kt @@ -367,17 +367,6 @@ class ThreadManager( return data } - fun sendUri(entry: MediaController.MediaEntry, scope: CoroutineScope): LiveData> { - val data = MutableLiveData>() - val uri = Uri.fromFile(File(entry.path)) - if (!entry.isVideo) { - sendPhoto(data, uri, entry.width, entry.height, scope) - return data - } - sendVideo(data, uri, entry.size, entry.duration, entry.width, entry.height, scope) - return data - } - fun sendUri(uri: Uri, scope: CoroutineScope): LiveData> { val data = MutableLiveData>() val mimeType = Utils.getMimeType(uri, contentResolver) diff --git a/app/src/main/java/awais/instagrabber/utils/MediaController.java b/app/src/main/java/awais/instagrabber/utils/MediaController.java deleted file mode 100644 index cbfec5c5..00000000 --- a/app/src/main/java/awais/instagrabber/utils/MediaController.java +++ /dev/null @@ -1,386 +0,0 @@ -package awais.instagrabber.utils; - -import android.content.Context; -import android.database.Cursor; -import android.os.Build; -import android.os.Environment; -import android.provider.MediaStore; -import android.util.Log; -import android.util.SparseArray; - -import java.util.ArrayList; -import java.util.Collections; - -import awais.instagrabber.R; - -/* - * This is the source code of Telegram for Android v. 1.3.x. - * It is licensed under GNU GPL v. 2 or later. - * You should have received a copy of the license in this archive (see LICENSE). - * - * Copyright Nikolai Kudashov, 2013-2018. - */ -public class MediaController { - private static final String TAG = MediaController.class.getSimpleName(); - private static final String[] PROJECTION_PHOTOS = { - MediaStore.Images.Media._ID, - MediaStore.Images.Media.BUCKET_ID, - MediaStore.Images.Media.BUCKET_DISPLAY_NAME, - MediaStore.Images.Media.DATA, - Build.VERSION.SDK_INT > 28 ? MediaStore.Images.Media.DATE_TAKEN : MediaStore.Images.Media.DATE_MODIFIED, - MediaStore.Images.Media.ORIENTATION, - MediaStore.Images.Media.WIDTH, - MediaStore.Images.Media.HEIGHT, - MediaStore.Images.Media.SIZE - }; - private static final String[] PROJECTION_VIDEO = { - MediaStore.Video.Media._ID, - MediaStore.Video.Media.BUCKET_ID, - MediaStore.Video.Media.BUCKET_DISPLAY_NAME, - MediaStore.Video.Media.DATA, - Build.VERSION.SDK_INT > 28 ? MediaStore.Video.Media.DATE_TAKEN : MediaStore.Images.Media.DATE_MODIFIED, - MediaStore.Video.Media.DURATION, - MediaStore.Video.Media.WIDTH, - MediaStore.Video.Media.HEIGHT, - MediaStore.Video.Media.SIZE - }; - - private final Context context; - private final OnLoadListener onLoadListener; - private final AppExecutors appExecutors; - - private static Runnable broadcastPhotosRunnable; - - private ArrayList allMediaAlbums; - private ArrayList allPhotoAlbums; - private AlbumEntry allPhotosAlbumEntry; - private AlbumEntry allMediaAlbumEntry; - private AlbumEntry allVideosAlbumEntry; - - public MediaController(final Context context, final OnLoadListener onLoadListener) { - this.context = context; - this.onLoadListener = onLoadListener; - appExecutors = AppExecutors.INSTANCE; - } - - public void load() { - loadGalleryAlbums(); - } - - private void loadGalleryAlbums() { - final Thread thread = new Thread(() -> { - final ArrayList mediaAlbumsSorted = new ArrayList<>(); - final ArrayList photoAlbumsSorted = new ArrayList<>(); - SparseArray mediaAlbums = new SparseArray<>(); - SparseArray photoAlbums = new SparseArray<>(); - AlbumEntry allPhotosAlbum = null; - AlbumEntry allVideosAlbum = null; - AlbumEntry allMediaAlbum = null; - String cameraFolder = null; - try { - cameraFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath() + "/" + "Camera/"; - } catch (Exception e) { - Log.e(TAG, "loadGalleryAlbums: ", e); - } - Integer mediaCameraAlbumId = null; - Integer photoCameraAlbumId = null; - - Cursor cursor = null; - try { - if (PermissionUtils.hasAttachMediaPerms(context)) { - cursor = MediaStore.Images.Media.query(context.getContentResolver(), - MediaStore.Images.Media.EXTERNAL_CONTENT_URI, - PROJECTION_PHOTOS, - null, - null, - (Build.VERSION.SDK_INT > 28 - ? MediaStore.Images.Media.DATE_TAKEN - : MediaStore.Images.Media.DATE_MODIFIED) + " DESC"); - if (cursor != null) { - int imageIdColumn = cursor.getColumnIndex(MediaStore.Images.Media._ID); - int bucketIdColumn = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_ID); - int bucketNameColumn = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME); - int dataColumn = cursor.getColumnIndex(MediaStore.Images.Media.DATA); - int dateColumn = cursor.getColumnIndex(Build.VERSION.SDK_INT > 28 ? MediaStore.Images.Media.DATE_TAKEN - : MediaStore.Images.Media.DATE_MODIFIED); - int orientationColumn = cursor.getColumnIndex(MediaStore.Images.Media.ORIENTATION); - int widthColumn = cursor.getColumnIndex(MediaStore.Images.Media.WIDTH); - int heightColumn = cursor.getColumnIndex(MediaStore.Images.Media.HEIGHT); - int sizeColumn = cursor.getColumnIndex(MediaStore.Images.Media.SIZE); - - while (cursor.moveToNext()) { - String path = cursor.getString(dataColumn); - if (TextUtils.isEmpty(path)) { - continue; - } - - int imageId = cursor.getInt(imageIdColumn); - int bucketId = cursor.getInt(bucketIdColumn); - String bucketName = cursor.getString(bucketNameColumn); - long dateTaken = cursor.getLong(dateColumn); - int orientation = cursor.getInt(orientationColumn); - int width = cursor.getInt(widthColumn); - int height = cursor.getInt(heightColumn); - long size = cursor.getLong(sizeColumn); - - MediaEntry mediaEntry = new MediaEntry(bucketId, imageId, dateTaken, path, orientation, -1, false, width, height, size); - - if (allPhotosAlbum == null) { - allPhotosAlbum = new AlbumEntry(0, context.getString(R.string.all_photos), mediaEntry); - photoAlbumsSorted.add(0, allPhotosAlbum); - } - if (allMediaAlbum == null) { - allMediaAlbum = new AlbumEntry(0, context.getString(R.string.all_media), mediaEntry); - mediaAlbumsSorted.add(0, allMediaAlbum); - } - allPhotosAlbum.addPhoto(mediaEntry); - allMediaAlbum.addPhoto(mediaEntry); - - AlbumEntry albumEntry = mediaAlbums.get(bucketId); - if (albumEntry == null) { - albumEntry = new AlbumEntry(bucketId, bucketName, mediaEntry); - mediaAlbums.put(bucketId, albumEntry); - if (mediaCameraAlbumId == null && cameraFolder != null && path.startsWith(cameraFolder)) { - mediaAlbumsSorted.add(0, albumEntry); - mediaCameraAlbumId = bucketId; - } else { - mediaAlbumsSorted.add(albumEntry); - } - } - albumEntry.addPhoto(mediaEntry); - - albumEntry = photoAlbums.get(bucketId); - if (albumEntry == null) { - albumEntry = new AlbumEntry(bucketId, bucketName, mediaEntry); - photoAlbums.put(bucketId, albumEntry); - if (photoCameraAlbumId == null && cameraFolder != null && path.startsWith(cameraFolder)) { - photoAlbumsSorted.add(0, albumEntry); - photoCameraAlbumId = bucketId; - } else { - photoAlbumsSorted.add(albumEntry); - } - } - albumEntry.addPhoto(mediaEntry); - } - } - } - } catch (Throwable e) { - Log.e(TAG, "loadGalleryAlbums: ", e); - } finally { - if (cursor != null) { - try { - cursor.close(); - } catch (Exception e) { - Log.e(TAG, "loadGalleryAlbums: ", e); - } - } - } - - try { - if (PermissionUtils.hasAttachMediaPerms(context)) { - cursor = MediaStore.Images.Media.query(context.getContentResolver(), - MediaStore.Video.Media.EXTERNAL_CONTENT_URI, - PROJECTION_VIDEO, - MediaStore.Video.Media.MIME_TYPE + "=?", - new String[]{"video/mp4"}, - (Build.VERSION.SDK_INT > 28 - ? MediaStore.Video.Media.DATE_TAKEN - : MediaStore.Video.Media.DATE_MODIFIED) + " DESC"); - if (cursor != null) { - int imageIdColumn = cursor.getColumnIndex(MediaStore.Video.Media._ID); - int bucketIdColumn = cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_ID); - int bucketNameColumn = cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_DISPLAY_NAME); - int dataColumn = cursor.getColumnIndex(MediaStore.Video.Media.DATA); - int dateColumn = cursor.getColumnIndex(Build.VERSION.SDK_INT > 28 ? MediaStore.Video.Media.DATE_TAKEN - : MediaStore.Video.Media.DATE_MODIFIED); - int durationColumn = cursor.getColumnIndex(MediaStore.Video.Media.DURATION); - int widthColumn = cursor.getColumnIndex(MediaStore.Video.Media.WIDTH); - int heightColumn = cursor.getColumnIndex(MediaStore.Video.Media.HEIGHT); - int sizeColumn = cursor.getColumnIndex(MediaStore.Video.Media.SIZE); - - while (cursor.moveToNext()) { - String path = cursor.getString(dataColumn); - if (TextUtils.isEmpty(path)) { - continue; - } - - int imageId = cursor.getInt(imageIdColumn); - int bucketId = cursor.getInt(bucketIdColumn); - String bucketName = cursor.getString(bucketNameColumn); - long dateTaken = cursor.getLong(dateColumn); - long duration = cursor.getLong(durationColumn); - int width = cursor.getInt(widthColumn); - int height = cursor.getInt(heightColumn); - long size = cursor.getLong(sizeColumn); - - MediaEntry mediaEntry = new MediaEntry(bucketId, imageId, dateTaken, path, -1, duration, true, width, height, size); - - if (allVideosAlbum == null) { - allVideosAlbum = new AlbumEntry(0, context.getString(R.string.all_videos), mediaEntry); - allVideosAlbum.videoOnly = true; - int index = 0; - if (allMediaAlbum != null) { - index++; - } - if (allPhotosAlbum != null) { - index++; - } - mediaAlbumsSorted.add(index, allVideosAlbum); - } - if (allMediaAlbum == null) { - allMediaAlbum = new AlbumEntry(0, context.getString(R.string.all_media), mediaEntry); - mediaAlbumsSorted.add(0, allMediaAlbum); - } - allVideosAlbum.addPhoto(mediaEntry); - allMediaAlbum.addPhoto(mediaEntry); - - AlbumEntry albumEntry = mediaAlbums.get(bucketId); - if (albumEntry == null) { - albumEntry = new AlbumEntry(bucketId, bucketName, mediaEntry); - mediaAlbums.put(bucketId, albumEntry); - if (mediaCameraAlbumId == null && cameraFolder != null && path.startsWith(cameraFolder)) { - mediaAlbumsSorted.add(0, albumEntry); - mediaCameraAlbumId = bucketId; - } else { - mediaAlbumsSorted.add(albumEntry); - } - } - - albumEntry.addPhoto(mediaEntry); - } - } - } - } catch (Throwable e) { - Log.e(TAG, "loadGalleryAlbums: ", e); - } finally { - if (cursor != null) { - try { - cursor.close(); - } catch (Exception e) { - Log.e(TAG, "loadGalleryAlbums: ", e); - } - } - } - for (int a = 0; a < mediaAlbumsSorted.size(); a++) { - Collections.sort(mediaAlbumsSorted.get(a).photos, (o1, o2) -> { - if (o1.dateTaken < o2.dateTaken) { - return 1; - } else if (o1.dateTaken > o2.dateTaken) { - return -1; - } - return 0; - }); - } - broadcastNewPhotos(mediaAlbumsSorted, photoAlbumsSorted, mediaCameraAlbumId, allMediaAlbum, allPhotosAlbum, allVideosAlbum, 0); - }); - thread.setPriority(Thread.MIN_PRIORITY); - thread.start(); - } - - private void broadcastNewPhotos(final ArrayList mediaAlbumsSorted, - final ArrayList photoAlbumsSorted, - final Integer cameraAlbumIdFinal, - final AlbumEntry allMediaAlbumFinal, - final AlbumEntry allPhotosAlbumFinal, - final AlbumEntry allVideosAlbumFinal, - int delay) { - if (broadcastPhotosRunnable != null) { - appExecutors.getMainThread().cancel(broadcastPhotosRunnable); - } - appExecutors.getMainThread().execute(broadcastPhotosRunnable = () -> { - allMediaAlbums = mediaAlbumsSorted; - allPhotoAlbums = photoAlbumsSorted; - broadcastPhotosRunnable = null; - allPhotosAlbumEntry = allPhotosAlbumFinal; - allMediaAlbumEntry = allMediaAlbumFinal; - allVideosAlbumEntry = allVideosAlbumFinal; - if (onLoadListener != null) { - onLoadListener.onLoad(); - } - }, delay); - } - - public AlbumEntry getAllMediaAlbumEntry() { - return allMediaAlbumEntry; - } - - public AlbumEntry getAllPhotosAlbumEntry() { - return allPhotosAlbumEntry; - } - - public AlbumEntry getAllVideosAlbumEntry() { - return allVideosAlbumEntry; - } - - public ArrayList getAllMediaAlbums() { - return allMediaAlbums; - } - - public ArrayList getAllPhotoAlbums() { - return allPhotoAlbums; - } - - public static class AlbumEntry { - public int bucketId; - public boolean videoOnly; - public String bucketName; - public MediaEntry coverPhoto; - public ArrayList photos = new ArrayList<>(); - public SparseArray photosByIds = new SparseArray<>(); - - public AlbumEntry(int bucketId, String bucketName, MediaEntry coverPhoto) { - this.bucketId = bucketId; - this.bucketName = bucketName; - this.coverPhoto = coverPhoto; - } - - public void addPhoto(MediaEntry mediaEntry) { - photos.add(mediaEntry); - photosByIds.put(mediaEntry.imageId, mediaEntry); - } - } - - public static class MediaEntry { - public int bucketId; - public int imageId; - public long dateTaken; - public long duration; - public int width; - public int height; - public long size; - public String path; - public int orientation; - public boolean isVideo; - public boolean isMuted; - public boolean canDeleteAfter; - - public MediaEntry(int bucketId, - int imageId, - long dateTaken, - String path, - int orientation, - long duration, - boolean isVideo, - int width, - int height, - long size) { - this.bucketId = bucketId; - this.imageId = imageId; - this.dateTaken = dateTaken; - this.path = path; - this.width = width; - this.height = height; - this.size = size; - if (isVideo) { - this.duration = duration; - } else { - this.orientation = orientation; - } - this.isVideo = isVideo; - } - } - - public interface OnLoadListener { - void onLoad(); - } -} diff --git a/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.kt b/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.kt index 70407c06..c28f4463 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.kt +++ b/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.kt @@ -76,10 +76,6 @@ class DirectThreadViewModel( return threadManager.sendText(text, viewModelScope) } - fun sendUri(entry: MediaController.MediaEntry): LiveData> { - return threadManager.sendUri(entry, viewModelScope) - } - fun sendUri(uri: Uri): LiveData> { return threadManager.sendUri(uri, viewModelScope) } diff --git a/app/src/main/java/awais/instagrabber/viewmodels/MediaPickerViewModel.java b/app/src/main/java/awais/instagrabber/viewmodels/MediaPickerViewModel.java deleted file mode 100644 index 12858851..00000000 --- a/app/src/main/java/awais/instagrabber/viewmodels/MediaPickerViewModel.java +++ /dev/null @@ -1,41 +0,0 @@ -package awais.instagrabber.viewmodels; - -import android.content.Context; - -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.ViewModel; - -import java.util.Collections; -import java.util.List; - -import awais.instagrabber.utils.MediaController; -import awais.instagrabber.utils.MediaController.AlbumEntry; - -public class MediaPickerViewModel extends ViewModel implements MediaController.OnLoadListener { - private final MutableLiveData> allAlbums = new MutableLiveData<>(Collections.emptyList()); - - private MediaController mediaController; - - public MediaPickerViewModel() { - - } - - public void loadMedia(final Context context) { - mediaController = new MediaController(context, this); - mediaController.load(); - } - - @Override - public void onLoad() { - if (mediaController == null) { - return; - } - final List allPhotoAlbums = mediaController.getAllMediaAlbums(); - this.allAlbums.postValue(allPhotoAlbums); - } - - public LiveData> getAllAlbums() { - return allAlbums; - } -} diff --git a/app/src/main/res/layout/layout_media_picker.xml b/app/src/main/res/layout/layout_media_picker.xml deleted file mode 100644 index e8a314e6..00000000 --- a/app/src/main/res/layout/layout_media_picker.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file