mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-22 22:57:29 +00:00
Send stickers and gifs in DM
This commit is contained in:
parent
4bb77abb33
commit
6d73528387
@ -0,0 +1,107 @@
|
|||||||
|
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.drawee.drawable.ScalingUtils;
|
||||||
|
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
|
||||||
|
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.util.Objects;
|
||||||
|
|
||||||
|
import awais.instagrabber.databinding.ItemMediaBinding;
|
||||||
|
import awais.instagrabber.repositories.responses.giphy.GiphyGif;
|
||||||
|
import awais.instagrabber.utils.Utils;
|
||||||
|
|
||||||
|
public class GifItemsAdapter extends ListAdapter<GiphyGif, GifItemsAdapter.GifViewHolder> {
|
||||||
|
|
||||||
|
private static final DiffUtil.ItemCallback<GiphyGif> diffCallback = new DiffUtil.ItemCallback<GiphyGif>() {
|
||||||
|
@Override
|
||||||
|
public boolean areItemsTheSame(@NonNull final GiphyGif oldItem, @NonNull final GiphyGif newItem) {
|
||||||
|
return Objects.equals(oldItem.getId(), newItem.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areContentsTheSame(@NonNull final GiphyGif oldItem, @NonNull final GiphyGif newItem) {
|
||||||
|
return Objects.equals(oldItem.getId(), newItem.getId());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final OnItemClickListener onItemClickListener;
|
||||||
|
|
||||||
|
public GifItemsAdapter(final OnItemClickListener onItemClickListener) {
|
||||||
|
super(diffCallback);
|
||||||
|
this.onItemClickListener = onItemClickListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public GifViewHolder 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 GifViewHolder(binding, onItemClickListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull final GifViewHolder holder, final int position) {
|
||||||
|
holder.bind(getItem(position));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class GifViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
private static final String TAG = GifViewHolder.class.getSimpleName();
|
||||||
|
private static final int size = Utils.displayMetrics.widthPixels / 3;
|
||||||
|
|
||||||
|
private final ItemMediaBinding binding;
|
||||||
|
private final OnItemClickListener onItemClickListener;
|
||||||
|
|
||||||
|
public GifViewHolder(@NonNull final ItemMediaBinding binding,
|
||||||
|
final OnItemClickListener onItemClickListener) {
|
||||||
|
super(binding.getRoot());
|
||||||
|
this.binding = binding;
|
||||||
|
this.onItemClickListener = onItemClickListener;
|
||||||
|
binding.duration.setVisibility(View.GONE);
|
||||||
|
final GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(itemView.getResources());
|
||||||
|
builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_CENTER);
|
||||||
|
binding.item.setHierarchy(builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bind(final GiphyGif item) {
|
||||||
|
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.parse(item.getImages().getFixedHeight().getWebp()))
|
||||||
|
.setResizeOptions(ResizeOptions.forDimensions(size, size))
|
||||||
|
.build();
|
||||||
|
final PipelineDraweeControllerBuilder builder = Fresco.newDraweeControllerBuilder()
|
||||||
|
.setImageRequest(request)
|
||||||
|
.setAutoPlayAnimations(true)
|
||||||
|
.setControllerListener(controllerListener);
|
||||||
|
binding.item.setController(builder.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnItemClickListener {
|
||||||
|
void onItemClick(GiphyGif giphyGif);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,150 @@
|
|||||||
|
package awais.instagrabber.dialogs;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
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 com.google.android.material.snackbar.Snackbar;
|
||||||
|
|
||||||
|
import awais.instagrabber.R;
|
||||||
|
import awais.instagrabber.adapters.GifItemsAdapter;
|
||||||
|
import awais.instagrabber.customviews.helpers.TextWatcherAdapter;
|
||||||
|
import awais.instagrabber.databinding.LayoutGifPickerBinding;
|
||||||
|
import awais.instagrabber.repositories.responses.giphy.GiphyGif;
|
||||||
|
import awais.instagrabber.utils.Debouncer;
|
||||||
|
import awais.instagrabber.utils.TextUtils;
|
||||||
|
import awais.instagrabber.viewmodels.GifPickerViewModel;
|
||||||
|
|
||||||
|
public class GifPickerBottomDialogFragment extends BottomSheetDialogFragment {
|
||||||
|
private static final String TAG = GifPickerBottomDialogFragment.class.getSimpleName();
|
||||||
|
private static final int INPUT_DEBOUNCE_INTERVAL = 500;
|
||||||
|
private static final String INPUT_KEY = "gif_search_input";
|
||||||
|
|
||||||
|
private LayoutGifPickerBinding binding;
|
||||||
|
private GifPickerViewModel viewModel;
|
||||||
|
private GifItemsAdapter gifItemsAdapter;
|
||||||
|
private OnSelectListener onSelectListener;
|
||||||
|
private Debouncer<String> inputDebouncer;
|
||||||
|
|
||||||
|
public static GifPickerBottomDialogFragment newInstance() {
|
||||||
|
final Bundle args = new Bundle();
|
||||||
|
final GifPickerBottomDialogFragment fragment = new GifPickerBottomDialogFragment();
|
||||||
|
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);
|
||||||
|
final Debouncer.Callback<String> callback = new Debouncer.Callback<String>() {
|
||||||
|
@Override
|
||||||
|
public void call(final String key) {
|
||||||
|
final Editable text = binding.input.getText();
|
||||||
|
if (TextUtils.isEmpty(text)) {
|
||||||
|
viewModel.search(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
viewModel.search(text.toString().trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(final Throwable t) {
|
||||||
|
Log.e(TAG, "onError: ", t);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
inputDebouncer = new Debouncer<>(callback, INPUT_DEBOUNCE_INTERVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
|
||||||
|
binding = LayoutGifPickerBinding.inflate(inflater, container, false);
|
||||||
|
viewModel = new ViewModelProvider(this).get(GifPickerViewModel.class);
|
||||||
|
return binding.getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
setupList();
|
||||||
|
setupInput();
|
||||||
|
setupObservers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupList() {
|
||||||
|
final Context context = getContext();
|
||||||
|
if (context == null) return;
|
||||||
|
binding.gifList.setLayoutManager(new GridLayoutManager(context, 3));
|
||||||
|
binding.gifList.setHasFixedSize(true);
|
||||||
|
gifItemsAdapter = new GifItemsAdapter(entry -> {
|
||||||
|
if (onSelectListener == null) return;
|
||||||
|
onSelectListener.onSelect(entry);
|
||||||
|
});
|
||||||
|
binding.gifList.setAdapter(gifItemsAdapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupInput() {
|
||||||
|
binding.input.addTextChangedListener(new TextWatcherAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
|
||||||
|
inputDebouncer.call(INPUT_KEY);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupObservers() {
|
||||||
|
viewModel.getImages().observe(getViewLifecycleOwner(), imagesResource -> {
|
||||||
|
if (imagesResource == null) return;
|
||||||
|
switch (imagesResource.status) {
|
||||||
|
case SUCCESS:
|
||||||
|
gifItemsAdapter.submitList(imagesResource.data);
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
final Context context = getContext();
|
||||||
|
if (context != null && imagesResource.message != null) {
|
||||||
|
Snackbar.make(context, binding.getRoot(), imagesResource.message, Snackbar.LENGTH_LONG);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LOADING:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnSelectListener(final OnSelectListener onSelectListener) {
|
||||||
|
this.onSelectListener = onSelectListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnSelectListener {
|
||||||
|
void onSelect(GiphyGif giphyGif);
|
||||||
|
}
|
||||||
|
}
|
@ -81,6 +81,7 @@ import awais.instagrabber.customviews.helpers.SwipeAndRestoreItemTouchHelperCall
|
|||||||
import awais.instagrabber.customviews.helpers.TextWatcherAdapter;
|
import awais.instagrabber.customviews.helpers.TextWatcherAdapter;
|
||||||
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.MediaPickerBottomDialogFragment;
|
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;
|
||||||
@ -737,6 +738,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
|
|||||||
|
|
||||||
private void hideInput() {
|
private void hideInput() {
|
||||||
binding.emojiToggle.setVisibility(View.GONE);
|
binding.emojiToggle.setVisibility(View.GONE);
|
||||||
|
binding.gif.setVisibility(View.GONE);
|
||||||
binding.camera.setVisibility(View.GONE);
|
binding.camera.setVisibility(View.GONE);
|
||||||
binding.gallery.setVisibility(View.GONE);
|
binding.gallery.setVisibility(View.GONE);
|
||||||
binding.input.setVisibility(View.GONE);
|
binding.input.setVisibility(View.GONE);
|
||||||
@ -750,6 +752,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
|
|||||||
|
|
||||||
private void showInput() {
|
private void showInput() {
|
||||||
binding.emojiToggle.setVisibility(View.VISIBLE);
|
binding.emojiToggle.setVisibility(View.VISIBLE);
|
||||||
|
binding.gif.setVisibility(View.VISIBLE);
|
||||||
binding.camera.setVisibility(View.VISIBLE);
|
binding.camera.setVisibility(View.VISIBLE);
|
||||||
binding.gallery.setVisibility(View.VISIBLE);
|
binding.gallery.setVisibility(View.VISIBLE);
|
||||||
binding.input.setVisibility(View.VISIBLE);
|
binding.input.setVisibility(View.VISIBLE);
|
||||||
@ -788,16 +791,18 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
|
|||||||
binding.send.setListenForRecord(true);
|
binding.send.setListenForRecord(true);
|
||||||
startIconAnimation();
|
startIconAnimation();
|
||||||
}
|
}
|
||||||
binding.gallery.setVisibility(View.VISIBLE);
|
binding.gif.setVisibility(View.VISIBLE);
|
||||||
binding.camera.setVisibility(View.VISIBLE);
|
binding.camera.setVisibility(View.VISIBLE);
|
||||||
|
binding.gallery.setVisibility(View.VISIBLE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (binding.send.isListenForRecord()) {
|
if (binding.send.isListenForRecord()) {
|
||||||
binding.send.setListenForRecord(false);
|
binding.send.setListenForRecord(false);
|
||||||
startIconAnimation();
|
startIconAnimation();
|
||||||
}
|
}
|
||||||
binding.gallery.setVisibility(View.GONE);
|
binding.gif.setVisibility(View.GONE);
|
||||||
binding.camera.setVisibility(View.GONE);
|
binding.camera.setVisibility(View.GONE);
|
||||||
|
binding.gallery.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDirectItemPreviewText(final DirectItem item) {
|
private String getDirectItemPreviewText(final DirectItem item) {
|
||||||
@ -937,8 +942,9 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
|
|||||||
public void onStart() {
|
public void onStart() {
|
||||||
isRecording = true;
|
isRecording = true;
|
||||||
binding.input.setHint(null);
|
binding.input.setHint(null);
|
||||||
binding.gallery.setVisibility(View.GONE);
|
binding.gif.setVisibility(View.GONE);
|
||||||
binding.camera.setVisibility(View.GONE);
|
binding.camera.setVisibility(View.GONE);
|
||||||
|
binding.gallery.setVisibility(View.GONE);
|
||||||
if (PermissionUtils.hasAudioRecordPerms(context)) {
|
if (PermissionUtils.hasAudioRecordPerms(context)) {
|
||||||
viewModel.startRecording();
|
viewModel.startRecording();
|
||||||
return;
|
return;
|
||||||
@ -958,8 +964,9 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
|
|||||||
public void onFinish(final long recordTime) {
|
public void onFinish(final long recordTime) {
|
||||||
Log.d(TAG, "onFinish");
|
Log.d(TAG, "onFinish");
|
||||||
binding.input.setHint("Message");
|
binding.input.setHint("Message");
|
||||||
binding.gallery.setVisibility(View.VISIBLE);
|
binding.gif.setVisibility(View.VISIBLE);
|
||||||
binding.camera.setVisibility(View.VISIBLE);
|
binding.camera.setVisibility(View.VISIBLE);
|
||||||
|
binding.gallery.setVisibility(View.VISIBLE);
|
||||||
viewModel.stopRecording(false);
|
viewModel.stopRecording(false);
|
||||||
isRecording = false;
|
isRecording = false;
|
||||||
}
|
}
|
||||||
@ -971,16 +978,18 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
|
|||||||
if (PermissionUtils.hasAudioRecordPerms(context)) {
|
if (PermissionUtils.hasAudioRecordPerms(context)) {
|
||||||
tooltip.show(binding.send);
|
tooltip.show(binding.send);
|
||||||
}
|
}
|
||||||
binding.gallery.setVisibility(View.VISIBLE);
|
binding.gif.setVisibility(View.VISIBLE);
|
||||||
binding.camera.setVisibility(View.VISIBLE);
|
binding.camera.setVisibility(View.VISIBLE);
|
||||||
|
binding.gallery.setVisibility(View.VISIBLE);
|
||||||
viewModel.stopRecording(true);
|
viewModel.stopRecording(true);
|
||||||
isRecording = false;
|
isRecording = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
binding.recordView.setOnBasketAnimationEndListener(() -> {
|
binding.recordView.setOnBasketAnimationEndListener(() -> {
|
||||||
binding.input.setHint(R.string.dms_thread_message_hint);
|
binding.input.setHint(R.string.dms_thread_message_hint);
|
||||||
binding.gallery.setVisibility(View.VISIBLE);
|
binding.gif.setVisibility(View.VISIBLE);
|
||||||
binding.camera.setVisibility(View.VISIBLE);
|
binding.camera.setVisibility(View.VISIBLE);
|
||||||
|
binding.gallery.setVisibility(View.VISIBLE);
|
||||||
});
|
});
|
||||||
binding.input.addTextChangedListener(new TextWatcherAdapter() {
|
binding.input.addTextChangedListener(new TextWatcherAdapter() {
|
||||||
// int prevLength = 0;
|
// int prevLength = 0;
|
||||||
@ -1057,6 +1066,16 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
|
|||||||
mediaPicker.show(getChildFragmentManager(), "MediaPicker");
|
mediaPicker.show(getChildFragmentManager(), "MediaPicker");
|
||||||
hideKeyboard(true);
|
hideKeyboard(true);
|
||||||
});
|
});
|
||||||
|
binding.gif.setOnClickListener(v -> {
|
||||||
|
final GifPickerBottomDialogFragment gifPicker = GifPickerBottomDialogFragment.newInstance();
|
||||||
|
gifPicker.setOnSelectListener(giphyGif -> {
|
||||||
|
gifPicker.dismiss();
|
||||||
|
if (giphyGif == null) return;
|
||||||
|
handleSentMessage(viewModel.sendAnimatedMedia(giphyGif));
|
||||||
|
});
|
||||||
|
gifPicker.show(getChildFragmentManager(), "GifPicker");
|
||||||
|
hideKeyboard(true);
|
||||||
|
});
|
||||||
binding.camera.setOnClickListener(v -> {
|
binding.camera.setOnClickListener(v -> {
|
||||||
final Intent intent = new Intent(context, CameraActivity.class);
|
final Intent intent = new Intent(context, CameraActivity.class);
|
||||||
startActivityForResult(intent, CAMERA_REQUEST_CODE);
|
startActivityForResult(intent, CAMERA_REQUEST_CODE);
|
||||||
|
@ -53,6 +53,7 @@ import awais.instagrabber.repositories.responses.directmessages.DirectThreadDeta
|
|||||||
import awais.instagrabber.repositories.responses.directmessages.DirectThreadFeedResponse;
|
import awais.instagrabber.repositories.responses.directmessages.DirectThreadFeedResponse;
|
||||||
import awais.instagrabber.repositories.responses.directmessages.DirectThreadParticipantRequestsResponse;
|
import awais.instagrabber.repositories.responses.directmessages.DirectThreadParticipantRequestsResponse;
|
||||||
import awais.instagrabber.repositories.responses.directmessages.RankedRecipient;
|
import awais.instagrabber.repositories.responses.directmessages.RankedRecipient;
|
||||||
|
import awais.instagrabber.repositories.responses.giphy.GiphyGif;
|
||||||
import awais.instagrabber.utils.BitmapUtils;
|
import awais.instagrabber.utils.BitmapUtils;
|
||||||
import awais.instagrabber.utils.Constants;
|
import awais.instagrabber.utils.Constants;
|
||||||
import awais.instagrabber.utils.CookieUtils;
|
import awais.instagrabber.utils.CookieUtils;
|
||||||
@ -641,6 +642,24 @@ public final class ThreadManager {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LiveData<Resource<Object>> sendAnimatedMedia(@NonNull final GiphyGif giphyGif) {
|
||||||
|
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
|
||||||
|
final Long userId = getCurrentUserId(data);
|
||||||
|
if (userId == null) return data;
|
||||||
|
final String clientContext = UUID.randomUUID().toString();
|
||||||
|
final DirectItem directItem = DirectItemFactory.createAnimatedMedia(userId, clientContext, giphyGif);
|
||||||
|
directItem.setPending(true);
|
||||||
|
addItems(0, Collections.singletonList(directItem));
|
||||||
|
data.postValue(Resource.loading(directItem));
|
||||||
|
final Call<DirectThreadBroadcastResponse> request = service.broadcastAnimatedMedia(
|
||||||
|
clientContext,
|
||||||
|
threadIdOrUserIds,
|
||||||
|
giphyGif
|
||||||
|
);
|
||||||
|
enqueueRequest(request, data, directItem);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
public void sendVoice(@NonNull final MutableLiveData<Resource<Object>> data,
|
public void sendVoice(@NonNull final MutableLiveData<Resource<Object>> data,
|
||||||
@NonNull final Uri uri,
|
@NonNull final Uri uri,
|
||||||
@NonNull final List<Float> waveform,
|
@NonNull final List<Float> waveform,
|
||||||
|
@ -7,7 +7,8 @@ public enum BroadcastItemType {
|
|||||||
IMAGE("configure_photo"),
|
IMAGE("configure_photo"),
|
||||||
LINK("link"),
|
LINK("link"),
|
||||||
VIDEO("configure_video"),
|
VIDEO("configure_video"),
|
||||||
VOICE("share_voice");
|
VOICE("share_voice"),
|
||||||
|
ANIMATED_MEDIA("animated_media");
|
||||||
|
|
||||||
private final String value;
|
private final String value;
|
||||||
|
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
package awais.instagrabber.repositories;
|
||||||
|
|
||||||
|
import awais.instagrabber.repositories.responses.giphy.GiphyGifResponse;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.http.GET;
|
||||||
|
import retrofit2.http.Query;
|
||||||
|
|
||||||
|
public interface GifRepository {
|
||||||
|
|
||||||
|
@GET("/api/v1/creatives/story_media_search_keyed_format/")
|
||||||
|
Call<GiphyGifResponse> searchGiphyGifs(@Query("request_surface") final String requestSurface,
|
||||||
|
@Query("q") final String query,
|
||||||
|
@Query("media_types") final String mediaTypes);
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package awais.instagrabber.repositories.requests.directmessages;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import awais.instagrabber.models.enums.BroadcastItemType;
|
||||||
|
import awais.instagrabber.repositories.responses.giphy.GiphyGif;
|
||||||
|
|
||||||
|
public class AnimatedMediaBroadcastOptions extends BroadcastOptions {
|
||||||
|
|
||||||
|
private final GiphyGif giphyGif;
|
||||||
|
|
||||||
|
public AnimatedMediaBroadcastOptions(final String clientContext,
|
||||||
|
final ThreadIdOrUserIds threadIdOrUserIds,
|
||||||
|
final GiphyGif giphyGif) {
|
||||||
|
super(clientContext, threadIdOrUserIds, BroadcastItemType.ANIMATED_MEDIA);
|
||||||
|
this.giphyGif = giphyGif;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getFormMap() {
|
||||||
|
final Map<String, String> form = new HashMap<>();
|
||||||
|
form.put("is_sticker", String.valueOf(giphyGif.isSticker()));
|
||||||
|
form.put("id", giphyGif.getId());
|
||||||
|
return form;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
package awais.instagrabber.repositories.responses.giphy;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class GiphyGif {
|
||||||
|
private final String type;
|
||||||
|
private final String id;
|
||||||
|
private final String title;
|
||||||
|
private final int isSticker;
|
||||||
|
private final GiphyGifImages images;
|
||||||
|
|
||||||
|
public GiphyGif(final String type, final String id, final String title, final int isSticker, final GiphyGifImages images) {
|
||||||
|
this.type = type;
|
||||||
|
this.id = id;
|
||||||
|
this.title = title;
|
||||||
|
this.isSticker = isSticker;
|
||||||
|
this.images = images;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSticker() {
|
||||||
|
return isSticker == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GiphyGifImages getImages() {
|
||||||
|
return images;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
final GiphyGif giphyGif = (GiphyGif) o;
|
||||||
|
return isSticker == giphyGif.isSticker &&
|
||||||
|
Objects.equals(type, giphyGif.type) &&
|
||||||
|
Objects.equals(id, giphyGif.id) &&
|
||||||
|
Objects.equals(title, giphyGif.title) &&
|
||||||
|
Objects.equals(images, giphyGif.images);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(type, id, title, isSticker, images);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "GiphyGif{" +
|
||||||
|
"type='" + type + '\'' +
|
||||||
|
", id='" + id + '\'' +
|
||||||
|
", title='" + title + '\'' +
|
||||||
|
", isSticker=" + isSticker() +
|
||||||
|
", images=" + images +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package awais.instagrabber.repositories.responses.giphy;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class GiphyGifImage {
|
||||||
|
private final int height;
|
||||||
|
private final int width;
|
||||||
|
private final long webpSize;
|
||||||
|
private final String webp;
|
||||||
|
|
||||||
|
public GiphyGifImage(final int height, final int width, final long webpSize, final String webp) {
|
||||||
|
this.height = height;
|
||||||
|
this.width = width;
|
||||||
|
this.webpSize = webpSize;
|
||||||
|
this.webp = webp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getWebpSize() {
|
||||||
|
return webpSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWebp() {
|
||||||
|
return webp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
final GiphyGifImage that = (GiphyGifImage) o;
|
||||||
|
return height == that.height &&
|
||||||
|
width == that.width &&
|
||||||
|
webpSize == that.webpSize &&
|
||||||
|
Objects.equals(webp, that.webp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(height, width, webpSize, webp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "GiphyGifImage{" +
|
||||||
|
"height=" + height +
|
||||||
|
", width=" + width +
|
||||||
|
", webpSize=" + webpSize +
|
||||||
|
", webp='" + webp + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package awais.instagrabber.repositories.responses.giphy;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import awais.instagrabber.repositories.responses.AnimatedMediaFixedHeight;
|
||||||
|
|
||||||
|
public class GiphyGifImages {
|
||||||
|
private final AnimatedMediaFixedHeight fixedHeight;
|
||||||
|
|
||||||
|
public GiphyGifImages(final AnimatedMediaFixedHeight fixedHeight) {
|
||||||
|
this.fixedHeight = fixedHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimatedMediaFixedHeight getFixedHeight() {
|
||||||
|
return fixedHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
final GiphyGifImages that = (GiphyGifImages) o;
|
||||||
|
return Objects.equals(fixedHeight, that.fixedHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(fixedHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "GiphyGifImages{" +
|
||||||
|
"fixedHeight=" + fixedHeight +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package awais.instagrabber.repositories.responses.giphy;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class GiphyGifResponse {
|
||||||
|
private final GiphyGifResults results;
|
||||||
|
private final String status;
|
||||||
|
|
||||||
|
public GiphyGifResponse(final GiphyGifResults results, final String status) {
|
||||||
|
this.results = results;
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GiphyGifResults getResults() {
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
final GiphyGifResponse that = (GiphyGifResponse) o;
|
||||||
|
return Objects.equals(results, that.results) &&
|
||||||
|
Objects.equals(status, that.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(results, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "GiphyGifResponse{" +
|
||||||
|
"results=" + results +
|
||||||
|
", status='" + status + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package awais.instagrabber.repositories.responses.giphy;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class GiphyGifResults {
|
||||||
|
private final List<GiphyGif> giphyGifs;
|
||||||
|
private final List<GiphyGif> giphy;
|
||||||
|
|
||||||
|
public GiphyGifResults(final List<GiphyGif> giphyGifs, final List<GiphyGif> giphy) {
|
||||||
|
this.giphyGifs = giphyGifs;
|
||||||
|
this.giphy = giphy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GiphyGif> getGiphyGifs() {
|
||||||
|
return giphyGifs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GiphyGif> getGiphy() {
|
||||||
|
return giphy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
final GiphyGifResults that = (GiphyGifResults) o;
|
||||||
|
return Objects.equals(giphyGifs, that.giphyGifs) &&
|
||||||
|
Objects.equals(giphy, that.giphy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(giphyGifs, giphy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "GiphyGifResults{" +
|
||||||
|
"giphyGifs=" + giphyGifs +
|
||||||
|
", giphy=" + giphy +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@ import awais.instagrabber.models.enums.DirectItemType;
|
|||||||
import awais.instagrabber.models.enums.MediaItemType;
|
import awais.instagrabber.models.enums.MediaItemType;
|
||||||
import awais.instagrabber.repositories.responses.User;
|
import awais.instagrabber.repositories.responses.User;
|
||||||
import awais.instagrabber.repositories.responses.directmessages.DirectItem;
|
import awais.instagrabber.repositories.responses.directmessages.DirectItem;
|
||||||
|
import awais.instagrabber.repositories.responses.directmessages.DirectItemAnimatedMedia;
|
||||||
import awais.instagrabber.repositories.responses.directmessages.DirectItemReelShare;
|
import awais.instagrabber.repositories.responses.directmessages.DirectItemReelShare;
|
||||||
import awais.instagrabber.repositories.responses.directmessages.DirectItemVisualMedia;
|
import awais.instagrabber.repositories.responses.directmessages.DirectItemVisualMedia;
|
||||||
import awais.instagrabber.repositories.responses.directmessages.DirectThread;
|
import awais.instagrabber.repositories.responses.directmessages.DirectThread;
|
||||||
@ -84,11 +85,16 @@ public final class DMUtils {
|
|||||||
message = item.getPlaceholder().getMessage();
|
message = item.getPlaceholder().getMessage();
|
||||||
break;
|
break;
|
||||||
case MEDIA_SHARE:
|
case MEDIA_SHARE:
|
||||||
subtitle = resources.getString(R.string.dms_inbox_shared_post, username != null ? username : "",
|
final User mediaShareUser = item.getMediaShare().getUser();
|
||||||
item.getMediaShare().getUser().getUsername());
|
subtitle = resources.getString(R.string.dms_inbox_shared_post,
|
||||||
|
username != null ? username : "",
|
||||||
|
mediaShareUser == null ? "" : mediaShareUser.getUsername());
|
||||||
break;
|
break;
|
||||||
case ANIMATED_MEDIA:
|
case ANIMATED_MEDIA:
|
||||||
subtitle = resources.getString(R.string.dms_inbox_shared_gif, username != null ? username : "");
|
final DirectItemAnimatedMedia animatedMedia = item.getAnimatedMedia();
|
||||||
|
subtitle = resources.getString(animatedMedia.isSticker() ? R.string.dms_inbox_shared_sticker
|
||||||
|
: R.string.dms_inbox_shared_gif,
|
||||||
|
username != null ? username : "");
|
||||||
break;
|
break;
|
||||||
case PROFILE:
|
case PROFILE:
|
||||||
subtitle = resources
|
subtitle = resources
|
||||||
@ -111,8 +117,10 @@ public final class DMUtils {
|
|||||||
final int format = reelType.equals("highlight_reel")
|
final int format = reelType.equals("highlight_reel")
|
||||||
? R.string.dms_inbox_shared_highlight
|
? R.string.dms_inbox_shared_highlight
|
||||||
: R.string.dms_inbox_shared_story;
|
: R.string.dms_inbox_shared_story;
|
||||||
subtitle = resources.getString(format, username != null ? username : "",
|
final User storyShareMediaUser = item.getStoryShare().getMedia().getUser();
|
||||||
item.getStoryShare().getMedia().getUser().getUsername());
|
subtitle = resources.getString(format,
|
||||||
|
username != null ? username : "",
|
||||||
|
storyShareMediaUser == null ? "" : storyShareMediaUser.getUsername());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -126,12 +134,16 @@ public final class DMUtils {
|
|||||||
subtitle = item.getVideoCallEvent().getDescription();
|
subtitle = item.getVideoCallEvent().getDescription();
|
||||||
break;
|
break;
|
||||||
case CLIP:
|
case CLIP:
|
||||||
subtitle = resources.getString(R.string.dms_inbox_shared_clip, username != null ? username : "",
|
final User clipUser = item.getClip().getClip().getUser();
|
||||||
item.getClip().getClip().getUser().getUsername());
|
subtitle = resources.getString(R.string.dms_inbox_shared_clip,
|
||||||
|
username != null ? username : "",
|
||||||
|
clipUser == null ? "" : clipUser.getUsername());
|
||||||
break;
|
break;
|
||||||
case FELIX_SHARE:
|
case FELIX_SHARE:
|
||||||
subtitle = resources.getString(R.string.dms_inbox_shared_igtv, username != null ? username : "",
|
final User felixShareVideoUser = item.getFelixShare().getVideo().getUser();
|
||||||
item.getFelixShare().getVideo().getUser().getUsername());
|
subtitle = resources.getString(R.string.dms_inbox_shared_igtv,
|
||||||
|
username != null ? username : "",
|
||||||
|
felixShareVideoUser == null ? "" : felixShareVideoUser.getUsername());
|
||||||
break;
|
break;
|
||||||
case RAVEN_MEDIA:
|
case RAVEN_MEDIA:
|
||||||
subtitle = getRavenMediaSubtitle(item, resources, username);
|
subtitle = getRavenMediaSubtitle(item, resources, username);
|
||||||
|
@ -8,13 +8,16 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import awais.instagrabber.models.enums.DirectItemType;
|
import awais.instagrabber.models.enums.DirectItemType;
|
||||||
import awais.instagrabber.models.enums.MediaItemType;
|
import awais.instagrabber.models.enums.MediaItemType;
|
||||||
|
import awais.instagrabber.repositories.responses.AnimatedMediaImages;
|
||||||
import awais.instagrabber.repositories.responses.Audio;
|
import awais.instagrabber.repositories.responses.Audio;
|
||||||
import awais.instagrabber.repositories.responses.ImageVersions2;
|
import awais.instagrabber.repositories.responses.ImageVersions2;
|
||||||
import awais.instagrabber.repositories.responses.Media;
|
import awais.instagrabber.repositories.responses.Media;
|
||||||
import awais.instagrabber.repositories.responses.MediaCandidate;
|
import awais.instagrabber.repositories.responses.MediaCandidate;
|
||||||
import awais.instagrabber.repositories.responses.VideoVersion;
|
import awais.instagrabber.repositories.responses.VideoVersion;
|
||||||
import awais.instagrabber.repositories.responses.directmessages.DirectItem;
|
import awais.instagrabber.repositories.responses.directmessages.DirectItem;
|
||||||
|
import awais.instagrabber.repositories.responses.directmessages.DirectItemAnimatedMedia;
|
||||||
import awais.instagrabber.repositories.responses.directmessages.DirectItemVoiceMedia;
|
import awais.instagrabber.repositories.responses.directmessages.DirectItemVoiceMedia;
|
||||||
|
import awais.instagrabber.repositories.responses.giphy.GiphyGif;
|
||||||
|
|
||||||
public final class DirectItemFactory {
|
public final class DirectItemFactory {
|
||||||
|
|
||||||
@ -213,4 +216,45 @@ public final class DirectItemFactory {
|
|||||||
0,
|
0,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DirectItem createAnimatedMedia(final long userId,
|
||||||
|
final String clientContext,
|
||||||
|
final GiphyGif giphyGif) {
|
||||||
|
final AnimatedMediaImages animatedImages = new AnimatedMediaImages(giphyGif.getImages().getFixedHeight());
|
||||||
|
final DirectItemAnimatedMedia animateMedia = new DirectItemAnimatedMedia(
|
||||||
|
giphyGif.getId(),
|
||||||
|
animatedImages,
|
||||||
|
false,
|
||||||
|
giphyGif.isSticker()
|
||||||
|
);
|
||||||
|
return new DirectItem(
|
||||||
|
UUID.randomUUID().toString(),
|
||||||
|
userId,
|
||||||
|
System.currentTimeMillis() * 1000,
|
||||||
|
DirectItemType.ANIMATED_MEDIA,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
clientContext,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
animateMedia,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
0,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import awais.instagrabber.repositories.responses.User;
|
|||||||
import awais.instagrabber.repositories.responses.directmessages.DirectItem;
|
import awais.instagrabber.repositories.responses.directmessages.DirectItem;
|
||||||
import awais.instagrabber.repositories.responses.directmessages.DirectThread;
|
import awais.instagrabber.repositories.responses.directmessages.DirectThread;
|
||||||
import awais.instagrabber.repositories.responses.directmessages.RankedRecipient;
|
import awais.instagrabber.repositories.responses.directmessages.RankedRecipient;
|
||||||
|
import awais.instagrabber.repositories.responses.giphy.GiphyGif;
|
||||||
import awais.instagrabber.utils.Constants;
|
import awais.instagrabber.utils.Constants;
|
||||||
import awais.instagrabber.utils.CookieUtils;
|
import awais.instagrabber.utils.CookieUtils;
|
||||||
import awais.instagrabber.utils.DirectoryUtils;
|
import awais.instagrabber.utils.DirectoryUtils;
|
||||||
@ -219,6 +220,10 @@ public class DirectThreadViewModel extends AndroidViewModel {
|
|||||||
return threadManager.unsend(item);
|
return threadManager.unsend(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LiveData<Resource<Object>> sendAnimatedMedia(@NonNull final GiphyGif giphyGif) {
|
||||||
|
return threadManager.sendAnimatedMedia(giphyGif);
|
||||||
|
}
|
||||||
|
|
||||||
public User getCurrentUser() {
|
public User getCurrentUser() {
|
||||||
return currentUser;
|
return currentUser;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,121 @@
|
|||||||
|
package awais.instagrabber.viewmodels;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import awais.instagrabber.models.Resource;
|
||||||
|
import awais.instagrabber.repositories.responses.giphy.GiphyGif;
|
||||||
|
import awais.instagrabber.repositories.responses.giphy.GiphyGifResponse;
|
||||||
|
import awais.instagrabber.repositories.responses.giphy.GiphyGifResults;
|
||||||
|
import awais.instagrabber.webservices.GifService;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
public class GifPickerViewModel extends ViewModel {
|
||||||
|
private static final String TAG = GifPickerViewModel.class.getSimpleName();
|
||||||
|
|
||||||
|
private final MutableLiveData<Resource<List<GiphyGif>>> images = new MutableLiveData<>(Resource.success(Collections.emptyList()));
|
||||||
|
private final GifService gifService;
|
||||||
|
|
||||||
|
private Call<GiphyGifResponse> searchRequest;
|
||||||
|
|
||||||
|
public GifPickerViewModel() {
|
||||||
|
gifService = GifService.getInstance();
|
||||||
|
search(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Resource<List<GiphyGif>>> getImages() {
|
||||||
|
return images;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void search(final String query) {
|
||||||
|
final Resource<List<GiphyGif>> currentValue = images.getValue();
|
||||||
|
if (currentValue != null && currentValue.status == Resource.Status.LOADING) {
|
||||||
|
cancelSearchRequest();
|
||||||
|
}
|
||||||
|
images.postValue(Resource.loading(getCurrentImages()));
|
||||||
|
searchRequest = gifService.searchGiphyGifs(query, query != null);
|
||||||
|
searchRequest.enqueue(new Callback<GiphyGifResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull final Call<GiphyGifResponse> call,
|
||||||
|
@NonNull final Response<GiphyGifResponse> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
parseResponse(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (response.errorBody() != null) {
|
||||||
|
try {
|
||||||
|
final String string = response.errorBody().string();
|
||||||
|
final String msg = String.format(Locale.US,
|
||||||
|
"onResponse: url: %s, responseCode: %d, errorBody: %s",
|
||||||
|
call.request().url().toString(),
|
||||||
|
response.code(),
|
||||||
|
string);
|
||||||
|
images.postValue(Resource.error(msg, getCurrentImages()));
|
||||||
|
Log.e(TAG, msg);
|
||||||
|
} catch (IOException e) {
|
||||||
|
images.postValue(Resource.error(e.getMessage(), getCurrentImages()));
|
||||||
|
Log.e(TAG, "onResponse: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
images.postValue(Resource.error("request was not successful and response error body was null", getCurrentImages()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NonNull final Call<GiphyGifResponse> call,
|
||||||
|
@NonNull final Throwable t) {
|
||||||
|
images.postValue(Resource.error(t.getMessage(), getCurrentImages()));
|
||||||
|
Log.e(TAG, "enqueueRequest: onFailure: ", t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseResponse(final Response<GiphyGifResponse> response) {
|
||||||
|
final GiphyGifResponse giphyGifResponse = response.body();
|
||||||
|
if (giphyGifResponse == null) {
|
||||||
|
images.postValue(Resource.error("Response body was null", getCurrentImages()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final GiphyGifResults results = giphyGifResponse.getResults();
|
||||||
|
images.postValue(Resource.success(
|
||||||
|
ImmutableList.<GiphyGif>builder()
|
||||||
|
.addAll(results.getGiphy() == null ? Collections.emptyList() : results.getGiphy())
|
||||||
|
.addAll(results.getGiphyGifs() == null ? Collections.emptyList() : results.getGiphyGifs())
|
||||||
|
.build()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// @NonNull
|
||||||
|
// private List<GiphyGifImage> getGiphyGifImages(@NonNull final List<GiphyGif> giphy) {
|
||||||
|
// return giphy.stream()
|
||||||
|
// .map(giphyGif -> {
|
||||||
|
// final GiphyGifImages images = giphyGif.getImages();
|
||||||
|
// if (images == null) return null;
|
||||||
|
// return images.getOriginal();
|
||||||
|
// })
|
||||||
|
// .filter(Objects::nonNull)
|
||||||
|
// .collect(Collectors.toList());
|
||||||
|
// }
|
||||||
|
|
||||||
|
private List<GiphyGif> getCurrentImages() {
|
||||||
|
final Resource<List<GiphyGif>> value = images.getValue();
|
||||||
|
return value == null ? Collections.emptyList() : value.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancelSearchRequest() {
|
||||||
|
if (searchRequest == null) return;
|
||||||
|
searchRequest.cancel();
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,7 @@ import java.util.UUID;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import awais.instagrabber.repositories.DirectMessagesRepository;
|
import awais.instagrabber.repositories.DirectMessagesRepository;
|
||||||
|
import awais.instagrabber.repositories.requests.directmessages.AnimatedMediaBroadcastOptions;
|
||||||
import awais.instagrabber.repositories.requests.directmessages.BroadcastOptions;
|
import awais.instagrabber.repositories.requests.directmessages.BroadcastOptions;
|
||||||
import awais.instagrabber.repositories.requests.directmessages.BroadcastOptions.ThreadIdOrUserIds;
|
import awais.instagrabber.repositories.requests.directmessages.BroadcastOptions.ThreadIdOrUserIds;
|
||||||
import awais.instagrabber.repositories.requests.directmessages.LinkBroadcastOptions;
|
import awais.instagrabber.repositories.requests.directmessages.LinkBroadcastOptions;
|
||||||
@ -34,6 +35,7 @@ import awais.instagrabber.repositories.responses.directmessages.DirectThreadDeta
|
|||||||
import awais.instagrabber.repositories.responses.directmessages.DirectThreadFeedResponse;
|
import awais.instagrabber.repositories.responses.directmessages.DirectThreadFeedResponse;
|
||||||
import awais.instagrabber.repositories.responses.directmessages.DirectThreadParticipantRequestsResponse;
|
import awais.instagrabber.repositories.responses.directmessages.DirectThreadParticipantRequestsResponse;
|
||||||
import awais.instagrabber.repositories.responses.directmessages.RankedRecipientsResponse;
|
import awais.instagrabber.repositories.responses.directmessages.RankedRecipientsResponse;
|
||||||
|
import awais.instagrabber.repositories.responses.giphy.GiphyGif;
|
||||||
import awais.instagrabber.utils.TextUtils;
|
import awais.instagrabber.utils.TextUtils;
|
||||||
import awais.instagrabber.utils.Utils;
|
import awais.instagrabber.utils.Utils;
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
@ -182,6 +184,11 @@ public class DirectMessagesService extends BaseService {
|
|||||||
return broadcast(new ReactionBroadcastOptions(clientContext, threadIdOrUserIds, itemId, emoji, delete));
|
return broadcast(new ReactionBroadcastOptions(clientContext, threadIdOrUserIds, itemId, emoji, delete));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Call<DirectThreadBroadcastResponse> broadcastAnimatedMedia(final String clientContext,
|
||||||
|
final ThreadIdOrUserIds threadIdOrUserIds,
|
||||||
|
final GiphyGif giphyGif) {
|
||||||
|
return broadcast(new AnimatedMediaBroadcastOptions(clientContext, threadIdOrUserIds, giphyGif));
|
||||||
|
}
|
||||||
|
|
||||||
private Call<DirectThreadBroadcastResponse> broadcast(@NonNull final BroadcastOptions broadcastOptions) {
|
private Call<DirectThreadBroadcastResponse> broadcast(@NonNull final BroadcastOptions broadcastOptions) {
|
||||||
if (TextUtils.isEmpty(broadcastOptions.getClientContext())) {
|
if (TextUtils.isEmpty(broadcastOptions.getClientContext())) {
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
package awais.instagrabber.webservices;
|
||||||
|
|
||||||
|
import awais.instagrabber.repositories.GifRepository;
|
||||||
|
import awais.instagrabber.repositories.responses.giphy.GiphyGifResponse;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Retrofit;
|
||||||
|
|
||||||
|
public class GifService extends BaseService {
|
||||||
|
|
||||||
|
private final GifRepository repository;
|
||||||
|
|
||||||
|
private static GifService instance;
|
||||||
|
|
||||||
|
private GifService() {
|
||||||
|
final Retrofit retrofit = getRetrofitBuilder()
|
||||||
|
.baseUrl("https://i.instagram.com")
|
||||||
|
.build();
|
||||||
|
repository = retrofit.create(GifRepository.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GifService getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new GifService();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Call<GiphyGifResponse> searchGiphyGifs(final String query,
|
||||||
|
final boolean includeGifs) {
|
||||||
|
final String mediaTypes = includeGifs ? "[\"giphy_gifs\",\"giphy\"]" : "[\"giphy\"]";
|
||||||
|
return repository.searchGiphyGifs("direct", query, mediaTypes);
|
||||||
|
}
|
||||||
|
}
|
10
app/src/main/res/drawable/ic_round_gif_24.xml
Normal file
10
app/src/main/res/drawable/ic_round_gif_24.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12.25,9c0.41,0 0.75,0.34 0.75,0.75v4.5c0,0.41 -0.34,0.75 -0.75,0.75s-0.75,-0.34 -0.75,-0.75v-4.5c0,-0.41 0.34,-0.75 0.75,-0.75zM10,9.75c0,-0.41 -0.34,-0.75 -0.75,-0.75L6,9c-0.6,0 -1,0.5 -1,1v4c0,0.5 0.4,1 1,1h3c0.6,0 1,-0.5 1,-1v-1.25c0,-0.41 -0.34,-0.75 -0.75,-0.75s-0.75,0.34 -0.75,0.75v0.75h-2v-3h2.75c0.41,0 0.75,-0.34 0.75,-0.75zM19,9.75c0,-0.41 -0.34,-0.75 -0.75,-0.75L15.5,9c-0.55,0 -1,0.45 -1,1v4.25c0,0.41 0.34,0.75 0.75,0.75s0.75,-0.34 0.75,-0.75L16,13h1.25c0.41,0 0.75,-0.34 0.75,-0.75s-0.34,-0.75 -0.75,-0.75L16,11.5v-1h2.25c0.41,0 0.75,-0.34 0.75,-0.75z"/>
|
||||||
|
</vector>
|
@ -120,7 +120,8 @@
|
|||||||
app:layout_constraintBottom_toBottomOf="@id/input"
|
app:layout_constraintBottom_toBottomOf="@id/input"
|
||||||
app:layout_constraintEnd_toStartOf="@id/send"
|
app:layout_constraintEnd_toStartOf="@id/send"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@id/input" />
|
app:layout_constraintTop_toTopOf="@id/input"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/emoji_toggle"
|
android:id="@+id/emoji_toggle"
|
||||||
@ -143,7 +144,8 @@
|
|||||||
app:rippleColor="@color/grey_500"
|
app:rippleColor="@color/grey_500"
|
||||||
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.App.Button.Circle"
|
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.App.Button.Circle"
|
||||||
app:strokeColor="@color/black"
|
app:strokeColor="@color/black"
|
||||||
app:strokeWidth="1dp" />
|
app:strokeWidth="1dp"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<awais.instagrabber.customviews.KeyNotifyingEmojiEditText
|
<awais.instagrabber.customviews.KeyNotifyingEmojiEditText
|
||||||
android:id="@+id/input"
|
android:id="@+id/input"
|
||||||
@ -158,16 +160,32 @@
|
|||||||
android:textColorHint="@color/grey_500"
|
android:textColorHint="@color/grey_500"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toStartOf="@id/camera"
|
app:layout_constraintEnd_toStartOf="@id/gif"
|
||||||
app:layout_constraintStart_toEndOf="@id/emoji_toggle"
|
app:layout_constraintStart_toEndOf="@id/emoji_toggle"
|
||||||
app:layout_constraintTop_toBottomOf="@id/reply_preview_text"
|
app:layout_constraintTop_toBottomOf="@id/reply_preview_text"
|
||||||
app:layout_goneMarginBottom="4dp"
|
app:layout_goneMarginBottom="4dp"
|
||||||
app:layout_goneMarginEnd="24dp" />
|
app:layout_goneMarginEnd="24dp"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
android:id="@+id/gif"
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/input_bg"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/camera"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/input"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/input"
|
||||||
|
app:srcCompat="@drawable/ic_round_gif_24"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageButton
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
android:id="@+id/camera"
|
android:id="@+id/camera"
|
||||||
android:layout_width="32dp"
|
android:layout_width="32dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:paddingStart="4dp"
|
android:paddingStart="4dp"
|
||||||
android:paddingEnd="4dp"
|
android:paddingEnd="4dp"
|
||||||
@ -175,10 +193,10 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/input_bg"
|
app:layout_constraintBottom_toBottomOf="@id/input_bg"
|
||||||
app:layout_constraintEnd_toStartOf="@id/gallery"
|
app:layout_constraintEnd_toStartOf="@id/gallery"
|
||||||
app:layout_constraintStart_toEndOf="@id/input"
|
app:layout_constraintStart_toEndOf="@id/gif"
|
||||||
app:layout_constraintTop_toTopOf="@id/input"
|
app:layout_constraintTop_toTopOf="@id/input"
|
||||||
app:srcCompat="@drawable/ic_camera_24"
|
app:srcCompat="@drawable/ic_camera_24"
|
||||||
tools:visibility="gone" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageButton
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
android:id="@+id/gallery"
|
android:id="@+id/gallery"
|
||||||
@ -196,7 +214,7 @@
|
|||||||
app:layout_constraintEnd_toStartOf="@id/send"
|
app:layout_constraintEnd_toStartOf="@id/send"
|
||||||
app:layout_constraintStart_toEndOf="@id/camera"
|
app:layout_constraintStart_toEndOf="@id/camera"
|
||||||
app:layout_constraintTop_toTopOf="@id/input"
|
app:layout_constraintTop_toTopOf="@id/input"
|
||||||
tools:visibility="gone" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<awais.instagrabber.customviews.RecordView
|
<awais.instagrabber.customviews.RecordView
|
||||||
android:id="@+id/record_view"
|
android:id="@+id/record_view"
|
||||||
@ -214,7 +232,7 @@
|
|||||||
app:slide_to_cancel_margin_right="16dp"
|
app:slide_to_cancel_margin_right="16dp"
|
||||||
app:slide_to_cancel_text="Slide To Cancel"
|
app:slide_to_cancel_text="Slide To Cancel"
|
||||||
app:slide_to_cancel_text_color="@color/white"
|
app:slide_to_cancel_text_color="@color/white"
|
||||||
tools:visibility="gone" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<awais.instagrabber.customviews.RecordButton
|
<awais.instagrabber.customviews.RecordButton
|
||||||
android:id="@+id/send"
|
android:id="@+id/send"
|
||||||
@ -231,7 +249,8 @@
|
|||||||
app:layout_constraintBottom_toBottomOf="@id/input_bg"
|
app:layout_constraintBottom_toBottomOf="@id/input_bg"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/input_bg"
|
app:layout_constraintStart_toEndOf="@id/input_bg"
|
||||||
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.App.Button.Circle" />
|
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.App.Button.Circle"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<awais.instagrabber.customviews.emoji.EmojiPicker
|
<awais.instagrabber.customviews.emoji.EmojiPicker
|
||||||
android:id="@+id/emoji_picker"
|
android:id="@+id/emoji_picker"
|
||||||
@ -241,7 +260,8 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
android:id="@+id/accept_pending_request_question"
|
android:id="@+id/accept_pending_request_question"
|
||||||
@ -255,7 +275,7 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toTopOf="@id/decline"
|
app:layout_constraintBottom_toTopOf="@id/decline"
|
||||||
app:layout_constraintTop_toBottomOf="@id/chats_barrier"
|
app:layout_constraintTop_toBottomOf="@id/chats_barrier"
|
||||||
tools:visibility="visible" />
|
tools:visibility="gone" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
android:id="@+id/decline"
|
android:id="@+id/decline"
|
||||||
@ -272,7 +292,7 @@
|
|||||||
app:layout_constraintEnd_toStartOf="@id/accept"
|
app:layout_constraintEnd_toStartOf="@id/accept"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/accept_pending_request_question"
|
app:layout_constraintTop_toBottomOf="@id/accept_pending_request_question"
|
||||||
tools:visibility="visible" />
|
tools:visibility="gone" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
android:id="@+id/accept"
|
android:id="@+id/accept"
|
||||||
@ -288,5 +308,5 @@
|
|||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/decline"
|
app:layout_constraintStart_toEndOf="@id/decline"
|
||||||
app:layout_constraintTop_toBottomOf="@id/accept_pending_request_question"
|
app:layout_constraintTop_toBottomOf="@id/accept_pending_request_question"
|
||||||
tools:visibility="visible" />
|
tools:visibility="gone" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
70
app/src/main/res/layout/layout_gif_picker.xml
Normal file
70
app/src/main/res/layout/layout_gif_picker.xml
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<?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">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/input_bg"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
android:background="@drawable/bg_input"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/input"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/input" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/search_icon"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.Icon.NoInsets"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginEnd="2dp"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:clickable="false"
|
||||||
|
android:scrollbars="none"
|
||||||
|
app:icon="@drawable/ic_search_24"
|
||||||
|
app:iconGravity="textStart"
|
||||||
|
app:iconSize="24dp"
|
||||||
|
app:iconTint="@color/grey_700"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/input_bg"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/input"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/input_bg"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/input"
|
||||||
|
app:rippleColor="@color/grey_500"
|
||||||
|
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.App.Button.Circle"
|
||||||
|
app:strokeColor="@color/black"
|
||||||
|
app:strokeWidth="1dp" />
|
||||||
|
|
||||||
|
<androidx.emoji.widget.EmojiAppCompatEditText
|
||||||
|
android:id="@+id/input"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:hint="@string/search_giphy"
|
||||||
|
android:paddingTop="12dp"
|
||||||
|
android:paddingBottom="12dp"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textColorHint="@color/grey_500"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/gif_list"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/search_icon"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/gif_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/input" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -185,6 +185,7 @@
|
|||||||
<string name="dms_inbox_shared_video">%s shared a video</string>
|
<string name="dms_inbox_shared_video">%s shared a video</string>
|
||||||
<string name="dms_inbox_shared_message">%s sent a message</string>
|
<string name="dms_inbox_shared_message">%s sent a message</string>
|
||||||
<string name="dms_inbox_shared_gif">%s shared a gif</string>
|
<string name="dms_inbox_shared_gif">%s shared a gif</string>
|
||||||
|
<string name="dms_inbox_shared_sticker">%s shared a sticker</string>
|
||||||
<string name="dms_inbox_shared_profile">%s shared a profile: @%s</string>
|
<string name="dms_inbox_shared_profile">%s shared a profile: @%s</string>
|
||||||
<string name="dms_inbox_shared_location">%s shared a location: %s</string>
|
<string name="dms_inbox_shared_location">%s shared a location: %s</string>
|
||||||
<string name="dms_inbox_shared_highlight">%s shared a story highlight by @%s</string>
|
<string name="dms_inbox_shared_highlight">%s shared a story highlight by @%s</string>
|
||||||
@ -490,4 +491,5 @@
|
|||||||
<string name="auto_refresh_every">Auto refresh every</string>
|
<string name="auto_refresh_every">Auto refresh every</string>
|
||||||
<string name="secs">secs</string>
|
<string name="secs">secs</string>
|
||||||
<string name="mins">mins</string>
|
<string name="mins">mins</string>
|
||||||
|
<string name="search_giphy">Search GIPHY</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user