mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-24 23:57:30 +00:00
close #1447
This commit is contained in:
parent
9c811a6291
commit
5e016e3210
@ -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<MediaEntry, MediaItemsAdapter.MediaItemViewHolder> {
|
|
||||||
|
|
||||||
private static final DiffUtil.ItemCallback<MediaEntry> diffCallback = new DiffUtil.ItemCallback<MediaEntry>() {
|
|
||||||
@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<ImageInfo> controllerListener = new BaseControllerListener<ImageInfo>() {
|
|
||||||
@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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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<View> 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<View> 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<String> 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<MediaController.AlbumEntry> 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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,11 +8,11 @@ import android.annotation.SuppressLint;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.graphics.drawable.Animatable;
|
import android.graphics.drawable.Animatable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.provider.DocumentsContract;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
@ -32,7 +32,6 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.ActionBar;
|
import androidx.appcompat.app.ActionBar;
|
||||||
import androidx.appcompat.view.menu.ActionMenuItemView;
|
import androidx.appcompat.view.menu.ActionMenuItemView;
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import androidx.core.view.WindowInsetsAnimationCompat;
|
import androidx.core.view.WindowInsetsAnimationCompat;
|
||||||
import androidx.core.view.WindowInsetsAnimationControlListenerCompat;
|
import androidx.core.view.WindowInsetsAnimationControlListenerCompat;
|
||||||
@ -97,7 +96,6 @@ import awais.instagrabber.customviews.helpers.TranslateDeferringInsetsAnimationC
|
|||||||
import awais.instagrabber.databinding.FragmentDirectMessagesThreadBinding;
|
import awais.instagrabber.databinding.FragmentDirectMessagesThreadBinding;
|
||||||
import awais.instagrabber.dialogs.DirectItemReactionDialogFragment;
|
import awais.instagrabber.dialogs.DirectItemReactionDialogFragment;
|
||||||
import awais.instagrabber.dialogs.GifPickerBottomDialogFragment;
|
import awais.instagrabber.dialogs.GifPickerBottomDialogFragment;
|
||||||
import awais.instagrabber.dialogs.MediaPickerBottomDialogFragment;
|
|
||||||
import awais.instagrabber.fragments.PostViewV2Fragment;
|
import awais.instagrabber.fragments.PostViewV2Fragment;
|
||||||
import awais.instagrabber.fragments.UserSearchFragment;
|
import awais.instagrabber.fragments.UserSearchFragment;
|
||||||
import awais.instagrabber.fragments.UserSearchFragmentDirections;
|
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 String TAG = DirectMessageThreadFragment.class.getSimpleName();
|
||||||
private static final int AUDIO_RECORD_PERM_REQUEST_CODE = 1000;
|
private static final int AUDIO_RECORD_PERM_REQUEST_CODE = 1000;
|
||||||
private static final int CAMERA_REQUEST_CODE = 200;
|
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 static final String TRANSLATION_Y = "translationY";
|
||||||
|
|
||||||
private DirectItemsAdapter itemsAdapter;
|
private DirectItemsAdapter itemsAdapter;
|
||||||
@ -474,6 +473,24 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
|
|||||||
@Override
|
@Override
|
||||||
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, 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 (requestCode == CAMERA_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
|
||||||
if (data == null || data.getData() == null) {
|
if (data == null || data.getData() == null) {
|
||||||
Log.w(TAG, "data is null!");
|
Log.w(TAG, "data is null!");
|
||||||
@ -1109,17 +1126,15 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
|
|||||||
setupInsetsCallback();
|
setupInsetsCallback();
|
||||||
setupEmojiPicker();
|
setupEmojiPicker();
|
||||||
binding.gallery.setOnClickListener(v -> {
|
binding.gallery.setOnClickListener(v -> {
|
||||||
final MediaPickerBottomDialogFragment mediaPicker = MediaPickerBottomDialogFragment.newInstance();
|
final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||||
mediaPicker.setOnSelectListener(entry -> {
|
intent.setType("*/*");
|
||||||
mediaPicker.dismiss();
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
if (!isAdded()) return;
|
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
if (!entry.isVideo) {
|
intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[]{
|
||||||
navigateToImageEditFragment(entry.path);
|
"image/*",
|
||||||
return;
|
"video/mp4"
|
||||||
}
|
|
||||||
handleSentMessage(viewModel.sendUri(entry));
|
|
||||||
});
|
});
|
||||||
mediaPicker.show(getChildFragmentManager(), "MediaPicker");
|
startActivityForResult(intent, FILE_PICKER_REQUEST_CODE);
|
||||||
});
|
});
|
||||||
binding.gif.setOnClickListener(v -> {
|
binding.gif.setOnClickListener(v -> {
|
||||||
final GifPickerBottomDialogFragment gifPicker = GifPickerBottomDialogFragment.newInstance();
|
final GifPickerBottomDialogFragment gifPicker = GifPickerBottomDialogFragment.newInstance();
|
||||||
|
@ -367,17 +367,6 @@ class ThreadManager(
|
|||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendUri(entry: MediaController.MediaEntry, scope: CoroutineScope): LiveData<Resource<Any?>> {
|
|
||||||
val data = MutableLiveData<Resource<Any?>>()
|
|
||||||
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<Resource<Any?>> {
|
fun sendUri(uri: Uri, scope: CoroutineScope): LiveData<Resource<Any?>> {
|
||||||
val data = MutableLiveData<Resource<Any?>>()
|
val data = MutableLiveData<Resource<Any?>>()
|
||||||
val mimeType = Utils.getMimeType(uri, contentResolver)
|
val mimeType = Utils.getMimeType(uri, contentResolver)
|
||||||
|
@ -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<AlbumEntry> allMediaAlbums;
|
|
||||||
private ArrayList<AlbumEntry> 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<AlbumEntry> mediaAlbumsSorted = new ArrayList<>();
|
|
||||||
final ArrayList<AlbumEntry> photoAlbumsSorted = new ArrayList<>();
|
|
||||||
SparseArray<AlbumEntry> mediaAlbums = new SparseArray<>();
|
|
||||||
SparseArray<AlbumEntry> 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<AlbumEntry> mediaAlbumsSorted,
|
|
||||||
final ArrayList<AlbumEntry> 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<AlbumEntry> getAllMediaAlbums() {
|
|
||||||
return allMediaAlbums;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<AlbumEntry> getAllPhotoAlbums() {
|
|
||||||
return allPhotoAlbums;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class AlbumEntry {
|
|
||||||
public int bucketId;
|
|
||||||
public boolean videoOnly;
|
|
||||||
public String bucketName;
|
|
||||||
public MediaEntry coverPhoto;
|
|
||||||
public ArrayList<MediaEntry> photos = new ArrayList<>();
|
|
||||||
public SparseArray<MediaEntry> 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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -76,10 +76,6 @@ class DirectThreadViewModel(
|
|||||||
return threadManager.sendText(text, viewModelScope)
|
return threadManager.sendText(text, viewModelScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendUri(entry: MediaController.MediaEntry): LiveData<Resource<Any?>> {
|
|
||||||
return threadManager.sendUri(entry, viewModelScope)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun sendUri(uri: Uri): LiveData<Resource<Any?>> {
|
fun sendUri(uri: Uri): LiveData<Resource<Any?>> {
|
||||||
return threadManager.sendUri(uri, viewModelScope)
|
return threadManager.sendUri(uri, viewModelScope)
|
||||||
}
|
}
|
||||||
|
@ -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<List<AlbumEntry>> 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<AlbumEntry> allPhotoAlbums = mediaController.getAllMediaAlbums();
|
|
||||||
this.allAlbums.postValue(allPhotoAlbums);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiveData<List<AlbumEntry>> getAllAlbums() {
|
|
||||||
return allAlbums;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?actionBarSize"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/media_list"
|
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
|
||||||
|
|
||||||
<Spinner
|
|
||||||
android:id="@+id/album_picker"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
</androidx.appcompat.widget.Toolbar>
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/media_list"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/toolbar" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
Loading…
Reference in New Issue
Block a user