diff --git a/app/build.gradle b/app/build.gradle
index 99fe8211..c64e49ff 100755
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,4 +1,5 @@
apply plugin: 'com.android.application'
+apply plugin: "androidx.navigation.safeargs"
android {
compileSdkVersion 29
@@ -37,10 +38,14 @@ android {
dependencies {
implementation('androidx.appcompat:appcompat:1.3.0-alpha01@aar') { transitive true }
- implementation('androidx.recyclerview:recyclerview:1.2.0-alpha03@aar') { transitive true }
+ implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation('com.google.android.material:material:1.3.0-alpha01@aar') { transitive true }
implementation('androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-rc01') { transitive true }
+ def nav_version = "2.3.0"
+ implementation "androidx.navigation:navigation-fragment:$nav_version"
+ implementation "androidx.navigation:navigation-ui:$nav_version"
+
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation('org.jsoup:jsoup:1.13.1') { transitive true }
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 43696544..1b29f327 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -215,7 +215,7 @@
-
-
-
-
-
{
- searchView.setQuery((cookieModel != null && userQuery != null && userQuery.equals("@"+cookieModel.getUsername())) ? "" : userQuery, false);
+ searchView.setQuery((cookieModel != null && userQuery != null && userQuery.equals("@" + cookieModel.getUsername())) ? "" : userQuery, false);
menu.findItem(R.id.action_about).setVisible(false);
menu.findItem(R.id.action_settings).setVisible(false);
menu.findItem(R.id.action_dms).setVisible(false);
@@ -400,7 +402,10 @@ public final class Main extends BaseLanguageActivity {
private void cancelSuggestionsAsync() {
if (prevSuggestionAsync != null)
- try { prevSuggestionAsync.cancel(true); } catch (final Exception ignored) { }
+ try {
+ prevSuggestionAsync.cancel(true);
+ } catch (final Exception ignored) {
+ }
}
@Override
@@ -411,7 +416,7 @@ public final class Main extends BaseLanguageActivity {
closeAnyOpenDrawer();
addToStack();
- userQuery = (query.contains("@") || query.contains("#")) ? query : ("@"+query);
+ userQuery = (query.contains("@") || query.contains("#")) ? query : ("@" + query);
searchAction.collapseActionView();
searchView.setIconified(true);
searchView.setIconified(true);
@@ -468,8 +473,7 @@ public final class Main extends BaseLanguageActivity {
mainHelper.onRefresh();
return;
}
- }
- else {
+ } else {
finish();
}
}
diff --git a/app/src/main/java/awais/instagrabber/activities/directmessages/DirectMessages.java b/app/src/main/java/awais/instagrabber/activities/directmessages/DirectMessages.java
deleted file mode 100644
index 8a6408e9..00000000
--- a/app/src/main/java/awais/instagrabber/activities/directmessages/DirectMessages.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package awais.instagrabber.activities.directmessages;
-
-import android.content.Intent;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.DividerItemDecoration;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-import android.view.View;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import awais.instagrabber.R;
-import awais.instagrabber.BuildConfig;
-import awais.instagrabber.activities.BaseLanguageActivity;
-import awais.instagrabber.adapters.DirectMessagesAdapter;
-import awais.instagrabber.asyncs.direct_messages.InboxFetcher;
-import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
-import awais.instagrabber.databinding.ActivityDmsBinding;
-import awais.instagrabber.interfaces.FetchListener;
-import awais.instagrabber.models.direct_messages.InboxModel;
-import awais.instagrabber.models.direct_messages.InboxThreadModel;
-import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
-
-public final class DirectMessages extends BaseLanguageActivity implements SwipeRefreshLayout.OnRefreshListener {
- private final ArrayList inboxThreadModelList = new ArrayList<>();
- private final DirectMessagesAdapter messagesAdapter = new DirectMessagesAdapter(inboxThreadModelList, v -> {
- final Object tag = v.getTag();
- if (tag instanceof InboxThreadModel) {
- startActivity(new Intent(this, DirectMessageThread.class)
- .putExtra(Constants.EXTRAS_THREAD_MODEL, (InboxThreadModel) tag)
- );
- }
- });
- private final FetchListener fetchListener = new FetchListener() {
- @Override
- public void doBefore() {
- dmsBinding.swipeRefreshLayout.setRefreshing(true);
- }
-
- @Override
- public void onResult(final InboxModel inboxModel) {
- if (inboxModel != null) {
- endCursor = inboxModel.getOldestCursor();
- if ("MINCURSOR".equals(endCursor) || "MAXCURSOR".equals(endCursor)) endCursor = null;
- // todo get request / unseen count from inboxModel
-
- final InboxThreadModel[] threads = inboxModel.getThreads();
- if (threads != null && threads.length > 0) {
- final int oldSize = inboxThreadModelList.size();
- inboxThreadModelList.addAll(Arrays.asList(threads));
-
- messagesAdapter.notifyItemRangeInserted(oldSize, threads.length);
- }
- }
-
- dmsBinding.swipeRefreshLayout.setRefreshing(false);
- stopCurrentExecutor();
- }
- };
- private String endCursor;
- private RecyclerLazyLoader lazyLoader;
- private AsyncTask currentlyRunning;
- private ActivityDmsBinding dmsBinding;
-
- @Override
- protected void onCreate(@Nullable final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- dmsBinding = ActivityDmsBinding.inflate(getLayoutInflater());
- setContentView(dmsBinding.getRoot());
-
- dmsBinding.swipeRefreshLayout.setOnRefreshListener(this);
- dmsBinding.toolbar.toolbar.setTitle(R.string.action_dms);
- dmsBinding.commentText.setVisibility(View.GONE);
- dmsBinding.commentSend.setVisibility(View.GONE);
-
- final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
- dmsBinding.rvDirectMessages.setLayoutManager(layoutManager);
- dmsBinding.rvDirectMessages.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
- dmsBinding.rvDirectMessages.setAdapter(messagesAdapter);
-
- lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
- if (!Utils.isEmpty(endCursor))
- currentlyRunning = new InboxFetcher(endCursor, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- endCursor = null;
- });
-
- dmsBinding.rvDirectMessages.addOnScrollListener(lazyLoader);
-
- stopCurrentExecutor();
- currentlyRunning = new InboxFetcher(null, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- @Override
- public void onRefresh() {
- endCursor = null;
- lazyLoader.resetState();
- inboxThreadModelList.clear();
- messagesAdapter.notifyDataSetChanged();
-
- stopCurrentExecutor();
- currentlyRunning = new InboxFetcher(null, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- private void stopCurrentExecutor() {
- if (currentlyRunning != null) {
- try {
- currentlyRunning.cancel(true);
- } catch (final Exception e) {
- if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/DirectMessageInboxAdapter.java b/app/src/main/java/awais/instagrabber/adapters/DirectMessageInboxAdapter.java
new file mode 100644
index 00000000..dfe6af2c
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/adapters/DirectMessageInboxAdapter.java
@@ -0,0 +1,54 @@
+package awais.instagrabber.adapters;
+
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.DiffUtil;
+import androidx.recyclerview.widget.ListAdapter;
+
+import awais.instagrabber.adapters.viewholder.DirectMessageInboxItemViewHolder;
+import awais.instagrabber.databinding.LayoutIncludeSimpleItemBinding;
+import awais.instagrabber.models.direct_messages.InboxThreadModel;
+
+public final class DirectMessageInboxAdapter extends ListAdapter {
+ private final OnItemClickListener onClickListener;
+
+ private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() {
+ @Override
+ public boolean areItemsTheSame(@NonNull final InboxThreadModel oldItem, @NonNull final InboxThreadModel newItem) {
+ return oldItem.getThreadId().equals(newItem.getThreadId());
+ }
+
+ @Override
+ public boolean areContentsTheSame(@NonNull final InboxThreadModel oldItem, @NonNull final InboxThreadModel newItem) {
+ return oldItem.equals(newItem);
+ }
+ };
+
+ public DirectMessageInboxAdapter(final OnItemClickListener onClickListener) {
+ super(diffCallback);
+ this.onClickListener = onClickListener;
+ }
+
+ @NonNull
+ @Override
+ public DirectMessageInboxItemViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int type) {
+ final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
+ final LayoutIncludeSimpleItemBinding binding = LayoutIncludeSimpleItemBinding.inflate(layoutInflater, parent, false);
+ return new DirectMessageInboxItemViewHolder(binding);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull final DirectMessageInboxItemViewHolder holder, final int position) {
+ final InboxThreadModel threadModel = getItem(position);
+ if (onClickListener != null) {
+ holder.itemView.setOnClickListener((v) -> onClickListener.onItemClick(threadModel));
+ }
+ holder.bind(threadModel);
+ }
+
+ public interface OnItemClickListener {
+ void onItemClick(final InboxThreadModel inboxThreadModel);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/DirectMessagesAdapter.java b/app/src/main/java/awais/instagrabber/adapters/DirectMessagesAdapter.java
deleted file mode 100755
index b38db004..00000000
--- a/app/src/main/java/awais/instagrabber/adapters/DirectMessagesAdapter.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package awais.instagrabber.adapters;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.core.text.HtmlCompat;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.RequestManager;
-
-import java.util.ArrayList;
-
-import awais.instagrabber.R;
-import awais.instagrabber.adapters.viewholder.DirectMessageViewHolder;
-import awais.instagrabber.models.ProfileModel;
-import awais.instagrabber.models.direct_messages.DirectItemModel;
-import awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemActionLogModel;
-import awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemReelShareModel;
-import awais.instagrabber.models.direct_messages.InboxThreadModel;
-import awais.instagrabber.models.enums.DirectItemType;
-
-public final class DirectMessagesAdapter extends RecyclerView.Adapter {
- private final ArrayList inboxThreadModels;
- private final View.OnClickListener onClickListener;
- private LayoutInflater layoutInflater;
-
- public DirectMessagesAdapter(final ArrayList inboxThreadModels, final View.OnClickListener onClickListener) {
- this.inboxThreadModels = inboxThreadModels;
- this.onClickListener = onClickListener;
- }
-
- @NonNull
- @Override
- public DirectMessageViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int type) {
- if (layoutInflater == null) layoutInflater = LayoutInflater.from(parent.getContext());
- return new DirectMessageViewHolder(layoutInflater.inflate(R.layout.layout_include_simple_item, parent, false),
- onClickListener);
- }
-
- @Override
- public void onBindViewHolder(@NonNull final DirectMessageViewHolder holder, final int position) {
- final InboxThreadModel threadModel = inboxThreadModels.get(position);
- final DirectItemModel[] itemModels;
-
- holder.itemView.setTag(threadModel);
-
- final RequestManager glideRequestManager = Glide.with(holder.itemView);
-
- if (threadModel != null && (itemModels = threadModel.getItems()) != null) {
- final ProfileModel[] users = threadModel.getUsers();
-
- if (users.length > 1) {
- holder.ivProfilePic.setVisibility(View.GONE);
- holder.multipleProfilePicsContainer.setVisibility(View.VISIBLE);
-
- for (int i = 0; i < Math.min(3, users.length); ++i)
- glideRequestManager.load(users[i].getSdProfilePic()).into(holder.multipleProfilePics[i]);
-
- } else {
- holder.ivProfilePic.setVisibility(View.VISIBLE);
- holder.multipleProfilePicsContainer.setVisibility(View.GONE);
-
- glideRequestManager.load(users.length == 1 ? users[0].getSdProfilePic() : null).into(holder.ivProfilePic);
- }
-
- holder.tvUsername.setText(threadModel.getThreadTitle());
-
- final DirectItemModel lastItemModel = itemModels[itemModels.length - 1];
- final DirectItemType itemType = lastItemModel.getItemType();
-
- holder.notTextType.setVisibility(itemType != DirectItemType.TEXT ? View.VISIBLE : View.GONE);
-
- final Context context = layoutInflater.getContext();
-
- final CharSequence messageText;
- switch (itemType) {
- case TEXT:
- case LIKE:
- messageText = lastItemModel.getText();
- break;
- case LINK:
- messageText = context.getString(R.string.direct_messages_sent_link);
- break;
- case MEDIA:
- case MEDIA_SHARE:
- messageText = context.getString(R.string.direct_messages_sent_media);
- break;
- case ACTION_LOG:
- final DirectItemActionLogModel logModel = lastItemModel.getActionLogModel();
- messageText = logModel != null ? logModel.getDescription() : "...";
- break;
- case REEL_SHARE:
- final DirectItemReelShareModel reelShare = lastItemModel.getReelShare();
- if (reelShare == null)
- messageText = context.getString(R.string.direct_messages_sent_media);
- else {
- final String reelType = reelShare.getType();
- final int textRes;
- if ("reply".equals(reelType))
- textRes = R.string.direct_messages_replied_story;
- else if ("mention".equals(reelType))
- textRes = R.string.direct_messages_mention_story;
- else if ("reaction".equals(reelType))
- textRes = R.string.direct_messages_reacted_story;
- else textRes = R.string.direct_messages_sent_media;
-
- messageText = context.getString(textRes) + " : " + reelShare.getText();
- }
- break;
- case RAVEN_MEDIA:
- messageText = context.getString(R.string.direct_messages_sent_media);
- break;
- default:
- messageText = "Unsupported message";
- }
-
- holder.tvMessage.setText(HtmlCompat.fromHtml(messageText.toString(), 63));
-
- holder.tvDate.setText(lastItemModel.getDateTime());
- }
- }
-
- @Override
- public int getItemCount() {
- return inboxThreadModels == null ? 0 : inboxThreadModels.size();
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/MessageItemsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/MessageItemsAdapter.java
index dbde8085..3fd3fe82 100755
--- a/app/src/main/java/awais/instagrabber/adapters/MessageItemsAdapter.java
+++ b/app/src/main/java/awais/instagrabber/adapters/MessageItemsAdapter.java
@@ -1,410 +1,66 @@
package awais.instagrabber.adapters;
-import android.content.Context;
-import android.content.res.Resources;
-import android.text.Spanned;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toast;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.text.HtmlCompat;
-import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.DiffUtil;
+import androidx.recyclerview.widget.ListAdapter;
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.RequestManager;
+import java.util.List;
-import java.util.ArrayList;
-
-import awais.instagrabber.R;
-import awais.instagrabber.activities.Main;
-import awais.instagrabber.adapters.viewholder.directmessages.TextMessageViewHolder;
+import awais.instagrabber.adapters.viewholder.directmessages.DirectMessageViewHolder;
+import awais.instagrabber.databinding.ItemMessageItemBinding;
import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.direct_messages.DirectItemModel;
-import awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemMediaModel;
-import awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemRavenMediaModel;
-import awais.instagrabber.models.enums.DirectItemType;
-import awais.instagrabber.models.enums.MediaItemType;
-import awais.instagrabber.models.enums.RavenExpiringMediaType;
-import awais.instagrabber.models.enums.RavenMediaViewType;
-import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
-import static awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemLinkContext;
-import static awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemLinkModel;
-import static awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemReelShareModel;
-import static awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemVoiceMediaModel;
-import static awais.instagrabber.models.direct_messages.DirectItemModel.RavenExpiringMediaActionSummaryModel;
-
-public final class MessageItemsAdapter extends RecyclerView.Adapter {
- private static final int MESSAGE_INCOMING = 69, MESSAGE_OUTGOING = 420;
- private final ProfileModel myProfileHolder =
- new ProfileModel(false, false, false,
- Utils.getUserIdFromCookie(Utils.settingsHelper.getString(Constants.COOKIE)),
- null, null, null, null, null, null, 0, 0, 0, false, false, false, false);
- private final ArrayList directItemModels;
- private final ArrayList users, leftusers;
+public final class MessageItemsAdapter extends ListAdapter {
+ private final List users;
+ private final List leftUsers;
private final View.OnClickListener onClickListener;
private final MentionClickListener mentionClickListener;
- private final View.OnClickListener openProfileClickListener = v -> {
- final Object tag = v.getTag();
- if (tag instanceof ProfileModel) {
- // todo do profile stuff
- final ProfileModel profileModel = (ProfileModel) tag;
- Log.d("AWAISKING_APP", "--> " + profileModel);
+
+ private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() {
+ @Override
+ public boolean areItemsTheSame(@NonNull final DirectItemModel oldItem, @NonNull final DirectItemModel newItem) {
+ return oldItem.getItemId().equals(newItem.getItemId());
+ }
+
+ @Override
+ public boolean areContentsTheSame(@NonNull final DirectItemModel oldItem, @NonNull final DirectItemModel newItem) {
+ return oldItem.getItemId().equals(newItem.getItemId());
}
};
- private final int itemMargin;
- private DirectItemVoiceMediaModel prevVoiceModel;
- private ImageView prevPlayIcon;
- private final View.OnClickListener voicePlayClickListener = v -> {
- final Object tag = v.getTag();
- if (v instanceof ViewGroup && tag instanceof DirectItemVoiceMediaModel) {
- final ImageView playIcon = (ImageView) ((ViewGroup) v).getChildAt(0);
- final DirectItemVoiceMediaModel voiceMediaModel = (DirectItemVoiceMediaModel) tag;
- final boolean voicePlaying = voiceMediaModel.isPlaying();
- voiceMediaModel.setPlaying(!voicePlaying);
- if (voiceMediaModel == prevVoiceModel) {
- // todo pause / resume
- } else {
- // todo release prev audio, start new voice
- if (prevVoiceModel != null) prevVoiceModel.setPlaying(false);
- if (prevPlayIcon != null) prevPlayIcon.setImageResource(android.R.drawable.ic_media_play);
- }
-
- if (voicePlaying) {
- playIcon.setImageResource(android.R.drawable.ic_media_play);
- } else {
- playIcon.setImageResource(android.R.drawable.ic_media_pause);
- }
-
- prevVoiceModel = voiceMediaModel;
- prevPlayIcon = playIcon;
- }
- };
- private Context context;
- private LayoutInflater layoutInflater;
- private String strDmYou;
-
- public MessageItemsAdapter(final ArrayList directItemModels, final ArrayList users,
- final ArrayList leftusers, final View.OnClickListener onClickListener,
+ public MessageItemsAdapter(final List users,
+ final List leftUsers,
+ final View.OnClickListener onClickListener,
final MentionClickListener mentionClickListener) {
+ super(diffCallback);
this.users = users;
- this.leftusers = leftusers;
- this.directItemModels = directItemModels;
+ this.leftUsers = leftUsers;
this.onClickListener = onClickListener;
this.mentionClickListener = mentionClickListener;
- this.itemMargin = Utils.displayMetrics.widthPixels / 5;
}
@NonNull
@Override
- public TextMessageViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int type) {
- if (context == null) context = parent.getContext();
- if (strDmYou == null) strDmYou = context.getString(R.string.direct_messages_you);
- if (layoutInflater == null) layoutInflater = LayoutInflater.from(context);
- return new TextMessageViewHolder(layoutInflater.inflate(R.layout.item_message_item, parent, false),
- onClickListener, mentionClickListener);
+ public DirectMessageViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int type) {
+ final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
+ final ItemMessageItemBinding binding = ItemMessageItemBinding.inflate(layoutInflater, parent, false);
+ return new DirectMessageViewHolder(binding, users, leftUsers);
}
@Override
- public void onBindViewHolder(@NonNull final TextMessageViewHolder holder, final int position) {
- final DirectItemModel directItemModel = directItemModels.get(position);
- holder.itemView.setTag(directItemModel);
-
- if (directItemModel != null) {
- final DirectItemType itemType = directItemModel.getItemType();
-
- final ProfileModel user = getUser(directItemModel.getUserId());
- final int type = user == myProfileHolder ? MESSAGE_OUTGOING : MESSAGE_INCOMING;
-
- final RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) holder.itemView.getLayoutParams();
- layoutParams.setMargins(type == MESSAGE_OUTGOING ? itemMargin : 0, 0,
- type == MESSAGE_INCOMING ? itemMargin : 0, 0);
-
- holder.tvMessage.setVisibility(View.GONE);
- holder.voiceMessageContainer.setVisibility(View.GONE);
- holder.ivAnimatedMessage.setVisibility(View.GONE);
- holder.linkMessageContainer.setVisibility(View.GONE);
-
- holder.mediaMessageContainer.setVisibility(View.GONE);
- holder.mediaTypeIcon.setVisibility(View.GONE);
- holder.mediaExpiredIcon.setVisibility(View.GONE);
-
- holder.profileMessageContainer.setVisibility(View.GONE);
- holder.isVerified.setVisibility(View.GONE);
-
- holder.btnOpenProfile.setVisibility(View.GONE);
- holder.btnOpenProfile.setOnClickListener(null);
- holder.btnOpenProfile.setTag(null);
-
- CharSequence text = "?";
- if (user != null && user != myProfileHolder) text = user.getUsername();
- else if (user == myProfileHolder) text = strDmYou;
- text = text + " - " + directItemModel.getDateTime();
-
- holder.tvUsername.setText(text);
-
- holder.ivProfilePic.setVisibility(type == MESSAGE_INCOMING ? View.VISIBLE : View.GONE);
-
- final RequestManager glideRequestManager = Glide.with(holder.itemView);
-
- if (type == MESSAGE_INCOMING && user != null)
- glideRequestManager.load(user.getSdProfilePic()).into(holder.ivProfilePic);
-
- DirectItemMediaModel mediaModel = directItemModel.getMediaModel();
- switch (itemType) {
- case PLACEHOLDER:
- holder.tvMessage.setText(HtmlCompat.fromHtml(directItemModel.getText().toString(), 63));
- holder.tvMessage.setVisibility(View.VISIBLE);
- break;
- case TEXT:
- case LIKE:
- text = directItemModel.getText();
- text = Utils.getSpannableUrl(text.toString()); // for urls
- if (Utils.hasMentions(text)) text = Utils.getMentionText(text); // for mentions
-
- if (text instanceof Spanned) holder.tvMessage.setText(text, TextView.BufferType.SPANNABLE);
- else if (text == "") holder.tvMessage.setText(context.getText(R.string.dms_inbox_raven_message_unknown));
- else holder.tvMessage.setText(text);
-
- holder.tvMessage.setVisibility(View.VISIBLE);
- break;
-
- case LINK: {
- final DirectItemLinkModel link = directItemModel.getLinkModel();
- final DirectItemLinkContext linkContext = link.getLinkContext();
-
- final String linkImageUrl = linkContext.getLinkImageUrl();
- if (!Utils.isEmpty(linkImageUrl)) {
- glideRequestManager.load(linkImageUrl).into(holder.ivLinkPreview);
- holder.tvLinkTitle.setText(linkContext.getLinkTitle());
- holder.tvLinkSummary.setText(linkContext.getLinkSummary());
- holder.ivLinkPreview.setVisibility(View.VISIBLE);
- holder.linkMessageContainer.setVisibility(View.VISIBLE);
- }
-
- holder.tvMessage.setText(Utils.getSpannableUrl(link.getText()));
- holder.tvMessage.setVisibility(View.VISIBLE);
- }
- break;
-
- case MEDIA_SHARE:
- {
- final ProfileModel modelUser = mediaModel.getUser();
- if (modelUser != null) {
- holder.tvMessage.setText(HtmlCompat.fromHtml(""+context.getString(R.string.dms_inbox_media_shared_from, modelUser.getUsername())+"", 63));
- holder.tvMessage.setVisibility(View.VISIBLE);
- }
- }
- case MEDIA: {
- glideRequestManager.load(mediaModel.getThumbUrl()).into(holder.ivMediaPreview);
-
- final MediaItemType modelMediaType = mediaModel.getMediaType();
- holder.mediaTypeIcon.setVisibility(modelMediaType == MediaItemType.MEDIA_TYPE_VIDEO ||
- modelMediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
-
- holder.mediaMessageContainer.setVisibility(View.VISIBLE);
- }
- break;
-
- case RAVEN_MEDIA: {
- final DirectItemRavenMediaModel ravenMediaModel = directItemModel.getRavenMediaModel();
-
- final boolean isExpired = ravenMediaModel == null || (mediaModel = ravenMediaModel.getMedia()) == null ||
- Utils.isEmpty(mediaModel.getThumbUrl()) && mediaModel.getPk() < 1;
-
- final RavenExpiringMediaActionSummaryModel mediaActionSummary = ravenMediaModel.getExpiringMediaActionSummary();
- holder.mediaExpiredIcon.setVisibility(isExpired ? View.VISIBLE : View.GONE);
-
- int textRes = R.string.dms_inbox_raven_media_unknown;
- if (isExpired) textRes = R.string.dms_inbox_raven_media_expired;
-
- if (!isExpired) {
- if (mediaActionSummary != null) {
- final RavenExpiringMediaType expiringMediaType = mediaActionSummary.getType();
-
- if (expiringMediaType == RavenExpiringMediaType.RAVEN_DELIVERED)
- textRes = R.string.dms_inbox_raven_media_delivered;
- else if (expiringMediaType == RavenExpiringMediaType.RAVEN_SENT)
- textRes = R.string.dms_inbox_raven_media_sent;
- else if (expiringMediaType == RavenExpiringMediaType.RAVEN_OPENED)
- textRes = R.string.dms_inbox_raven_media_opened;
- else if (expiringMediaType == RavenExpiringMediaType.RAVEN_REPLAYED)
- textRes = R.string.dms_inbox_raven_media_replayed;
- else if (expiringMediaType == RavenExpiringMediaType.RAVEN_SENDING)
- textRes = R.string.dms_inbox_raven_media_sending;
- else if (expiringMediaType == RavenExpiringMediaType.RAVEN_BLOCKED)
- textRes = R.string.dms_inbox_raven_media_blocked;
- else if (expiringMediaType == RavenExpiringMediaType.RAVEN_SUGGESTED)
- textRes = R.string.dms_inbox_raven_media_suggested;
- else if (expiringMediaType == RavenExpiringMediaType.RAVEN_SCREENSHOT)
- textRes = R.string.dms_inbox_raven_media_screenshot;
- else if (expiringMediaType == RavenExpiringMediaType.RAVEN_CANNOT_DELIVER)
- textRes = R.string.dms_inbox_raven_media_cant_deliver;
- }
-
- final RavenMediaViewType ravenMediaViewType = ravenMediaModel.getViewType();
- if (ravenMediaViewType == RavenMediaViewType.PERMANENT || ravenMediaViewType == RavenMediaViewType.REPLAYABLE) {
- final MediaItemType mediaType = mediaModel.getMediaType();
- textRes = -1;
- holder.mediaTypeIcon.setVisibility(mediaType == MediaItemType.MEDIA_TYPE_VIDEO ||
- mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
-
- glideRequestManager.load(mediaModel.getThumbUrl()).into(holder.ivMediaPreview);
- holder.mediaMessageContainer.setVisibility(View.VISIBLE);
- }
- }
- if (textRes != -1) {
- holder.tvMessage.setText(context.getText(textRes));
- holder.tvMessage.setVisibility(View.VISIBLE);
- }
- }
- break;
-
- case REEL_SHARE: {
- final DirectItemReelShareModel reelShare = directItemModel.getReelShare();
- if (!Utils.isEmpty(text = reelShare.getText())) {
- holder.tvMessage.setText(text);
- holder.tvMessage.setVisibility(View.VISIBLE);
- }
-
- final DirectItemMediaModel reelShareMedia = reelShare.getMedia();
- final MediaItemType mediaType = reelShareMedia.getMediaType();
-
- if (mediaType == null)
- holder.mediaExpiredIcon.setVisibility(View.VISIBLE);
- else {
- holder.mediaTypeIcon.setVisibility(mediaType == MediaItemType.MEDIA_TYPE_VIDEO ||
- mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
-
- glideRequestManager.load(reelShareMedia.getThumbUrl()).into(holder.ivMediaPreview);
- holder.mediaMessageContainer.setVisibility(View.VISIBLE);
- }
- }
- break;
-
- case STORY_SHARE: {
- final DirectItemReelShareModel reelShare = directItemModel.getReelShare();
- if (reelShare == null) {
- holder.tvMessage.setText(HtmlCompat.fromHtml(directItemModel.getText().toString(), 63));
- holder.tvMessage.setVisibility(View.VISIBLE);
- }
- else {
- if (!Utils.isEmpty(text = reelShare.getText())) {
- holder.tvMessage.setText(text);
- holder.tvMessage.setVisibility(View.VISIBLE);
- }
-
- final DirectItemMediaModel reelShareMedia = reelShare.getMedia();
- final MediaItemType mediaType = reelShareMedia.getMediaType();
-
- holder.mediaTypeIcon.setVisibility(mediaType == MediaItemType.MEDIA_TYPE_VIDEO ||
- mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
-
- glideRequestManager.load(reelShareMedia.getThumbUrl()).into(holder.ivMediaPreview);
- holder.mediaMessageContainer.setVisibility(View.VISIBLE);
- }
- }
- break;
-
- case VOICE_MEDIA: {
- final DirectItemVoiceMediaModel voiceMediaModel = directItemModel.getVoiceMediaModel();
-
- if (voiceMediaModel != null) {
- final int[] waveformData = voiceMediaModel.getWaveformData();
- if (waveformData != null) holder.waveformSeekBar.setSample(waveformData);
-
- final long durationMs = voiceMediaModel.getDurationMs();
- holder.tvVoiceDuration.setText(Utils.millisToString(durationMs));
- holder.waveformSeekBar.setProgress(voiceMediaModel.getProgress());
- holder.waveformSeekBar.setProgressChangeListener((waveformSeekBar, progress, fromUser) -> {
- // todo progress audio player
- voiceMediaModel.setProgress(progress);
- if (fromUser)
- holder.tvVoiceDuration.setText(Utils.millisToString(durationMs * progress / 100));
- });
- holder.btnPlayVoice.setTag(voiceMediaModel);
- holder.btnPlayVoice.setOnClickListener(voicePlayClickListener);
- } else {
- holder.waveformSeekBar.setProgress(0);
- }
-
- holder.voiceMessageContainer.setVisibility(View.VISIBLE);
- }
- break;
-
- case ANIMATED_MEDIA: {
- glideRequestManager.asGif().load(directItemModel.getAnimatedMediaModel().getGifUrl())
- .into(holder.ivAnimatedMessage);
- holder.ivAnimatedMessage.setVisibility(View.VISIBLE);
- }
- break;
-
- case PROFILE: {
- final ProfileModel profileModel = directItemModel.getProfileModel();
- Glide.with(holder.ivMessageProfilePic).load(profileModel.getSdProfilePic())
- .into(holder.ivMessageProfilePic);
- holder.btnOpenProfile.setTag(profileModel);
- holder.btnOpenProfile.setOnClickListener(openProfileClickListener);
-
- holder.tvProfileName.setText(profileModel.getName());
- holder.tvProfileUsername.setText(profileModel.getUsername());
- holder.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE);
-
- holder.btnOpenProfile.setVisibility(View.VISIBLE);
- holder.profileMessageContainer.setVisibility(View.VISIBLE);
- }
- break;
-
- case VIDEO_CALL_EVENT: {
- // todo add call event info
- holder.tvMessage.setVisibility(View.VISIBLE);
- holder.itemView.setBackgroundColor(0xFF_1F90E6);
- }
- break;
-
- case ACTION_LOG: {
- text = directItemModel.getActionLogModel().getDescription();
- holder.tvMessage.setText(HtmlCompat.fromHtml(""+text+"", 63));
- holder.tvMessage.setVisibility(View.VISIBLE);
- }
- break;
- }
- }
+ public void onBindViewHolder(@NonNull final DirectMessageViewHolder holder, final int position) {
+ final DirectItemModel directItemModel = getItem(position);
+ holder.bind(directItemModel);
}
@Override
public int getItemViewType(final int position) {
- return directItemModels.get(position).getItemType().ordinal();
- }
-
- @Override
- public int getItemCount() {
- return directItemModels == null ? 0 : directItemModels.size();
- }
-
- @Nullable
- private ProfileModel getUser(final long userId) {
- if (users != null) {
- ProfileModel result = myProfileHolder;
- for (final ProfileModel user : users) {
- if (Long.toString(userId).equals(user.getId())) result = user;
- }
- if (leftusers != null)
- for (final ProfileModel leftuser : leftusers) {
- if (Long.toString(userId).equals(leftuser.getId())) result = leftuser;
- }
- return result;
- }
- return null;
+ return getItem(position).getItemType().ordinal();
}
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/DirectMessageInboxItemViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/DirectMessageInboxItemViewHolder.java
new file mode 100644
index 00000000..4f2c8693
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/DirectMessageInboxItemViewHolder.java
@@ -0,0 +1,107 @@
+package awais.instagrabber.adapters.viewholder;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+import androidx.annotation.NonNull;
+import androidx.core.text.HtmlCompat;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.RequestManager;
+
+import awais.instagrabber.R;
+import awais.instagrabber.databinding.LayoutIncludeSimpleItemBinding;
+import awais.instagrabber.models.ProfileModel;
+import awais.instagrabber.models.direct_messages.DirectItemModel;
+import awais.instagrabber.models.direct_messages.InboxThreadModel;
+import awais.instagrabber.models.enums.DirectItemType;
+
+public final class DirectMessageInboxItemViewHolder extends RecyclerView.ViewHolder {
+ private final LinearLayout multipleProfilePicsContainer;
+ private final ImageView[] multipleProfilePics;
+ private final LayoutIncludeSimpleItemBinding binding;
+
+ public DirectMessageInboxItemViewHolder(@NonNull final LayoutIncludeSimpleItemBinding binding) {
+ super(binding.getRoot());
+ this.binding = binding;
+ binding.tvLikes.setVisibility(View.GONE);
+ multipleProfilePicsContainer = binding.container;
+ final LinearLayout containerChild = (LinearLayout) multipleProfilePicsContainer.getChildAt(1);
+ multipleProfilePics = new ImageView[]{
+ (ImageView) multipleProfilePicsContainer.getChildAt(0),
+ (ImageView) containerChild.getChildAt(0),
+ (ImageView) containerChild.getChildAt(1)
+ };
+ binding.tvDate.setSelected(true);
+ binding.tvUsername.setSelected(true);
+ }
+
+ public void bind(final InboxThreadModel model) {
+ final DirectItemModel[] itemModels;
+ if (model == null || (itemModels = model.getItems()) == null) {
+ return;
+ }
+ itemView.setTag(model);
+ final RequestManager glideRequestManager = Glide.with(itemView);
+ final ProfileModel[] users = model.getUsers();
+ if (users.length > 1) {
+ binding.ivProfilePic.setVisibility(View.GONE);
+ multipleProfilePicsContainer.setVisibility(View.VISIBLE);
+ for (int i = 0; i < Math.min(3, users.length); ++i)
+ glideRequestManager.load(users[i].getSdProfilePic()).into(multipleProfilePics[i]);
+ } else {
+ binding.ivProfilePic.setVisibility(View.VISIBLE);
+ multipleProfilePicsContainer.setVisibility(View.GONE);
+ glideRequestManager.load(users.length == 1 ? users[0].getSdProfilePic() : null).into(binding.ivProfilePic);
+ }
+ binding.tvUsername.setText(model.getThreadTitle());
+ final DirectItemModel lastItemModel = itemModels[itemModels.length - 1];
+ final DirectItemType itemType = lastItemModel.getItemType();
+ binding.notTextType.setVisibility(itemType != DirectItemType.TEXT ? View.VISIBLE : View.GONE);
+ final Context context = itemView.getContext();
+ final CharSequence messageText;
+ switch (itemType) {
+ case TEXT:
+ case LIKE:
+ messageText = lastItemModel.getText();
+ break;
+ case LINK:
+ messageText = context.getString(R.string.direct_messages_sent_link);
+ break;
+ case MEDIA:
+ case MEDIA_SHARE:
+ case RAVEN_MEDIA:
+ messageText = context.getString(R.string.direct_messages_sent_media);
+ break;
+ case ACTION_LOG:
+ final DirectItemModel.DirectItemActionLogModel logModel = lastItemModel.getActionLogModel();
+ messageText = logModel != null ? logModel.getDescription() : "...";
+ break;
+ case REEL_SHARE:
+ final DirectItemModel.DirectItemReelShareModel reelShare = lastItemModel.getReelShare();
+ if (reelShare == null)
+ messageText = context.getString(R.string.direct_messages_sent_media);
+ else {
+ final String reelType = reelShare.getType();
+ final int textRes;
+ if ("reply".equals(reelType))
+ textRes = R.string.direct_messages_replied_story;
+ else if ("mention".equals(reelType))
+ textRes = R.string.direct_messages_mention_story;
+ else if ("reaction".equals(reelType))
+ textRes = R.string.direct_messages_reacted_story;
+ else textRes = R.string.direct_messages_sent_media;
+
+ messageText = context.getString(textRes) + " : " + reelShare.getText();
+ }
+ break;
+ default:
+ messageText = "Unsupported message";
+ }
+ binding.tvComment.setText(HtmlCompat.fromHtml(messageText.toString(), HtmlCompat.FROM_HTML_MODE_COMPACT));
+ binding.tvDate.setText(lastItemModel.getDateTime());
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/DirectMessageViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/DirectMessageViewHolder.java
deleted file mode 100755
index c7cdddb4..00000000
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/DirectMessageViewHolder.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package awais.instagrabber.adapters.viewholder;
-
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import awais.instagrabber.R;
-
-public final class DirectMessageViewHolder extends RecyclerView.ViewHolder {
- public final LinearLayout multipleProfilePicsContainer;
- public final ImageView[] multipleProfilePics;
- public final ImageView ivProfilePic, notTextType;
- public final TextView tvUsername, tvDate, tvMessage;
-
- public DirectMessageViewHolder(@NonNull final View itemView, final View.OnClickListener clickListener) {
- super(itemView);
-
- if (clickListener != null) itemView.setOnClickListener(clickListener);
-
- itemView.findViewById(R.id.tvLikes).setVisibility(View.GONE);
-
- tvDate = itemView.findViewById(R.id.tvDate);
- tvMessage = itemView.findViewById(R.id.tvComment);
- tvUsername = itemView.findViewById(R.id.tvUsername);
- notTextType = itemView.findViewById(R.id.notTextType);
- ivProfilePic = itemView.findViewById(R.id.ivProfilePic);
-
- multipleProfilePicsContainer = itemView.findViewById(R.id.container);
- final LinearLayout containerChild = (LinearLayout) multipleProfilePicsContainer.getChildAt(1);
- multipleProfilePics = new ImageView[]{
- (ImageView) multipleProfilePicsContainer.getChildAt(0),
- (ImageView) containerChild.getChildAt(0),
- (ImageView) containerChild.getChildAt(1)
- };
-
- tvDate.setSelected(true);
- tvUsername.setSelected(true);
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageViewHolder.java
new file mode 100644
index 00000000..5a1fef4f
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageViewHolder.java
@@ -0,0 +1,383 @@
+package awais.instagrabber.adapters.viewholder.directmessages;
+
+import android.content.Context;
+import android.text.Spanned;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+import androidx.core.text.HtmlCompat;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.RequestManager;
+
+import java.util.List;
+
+import awais.instagrabber.R;
+import awais.instagrabber.databinding.ItemMessageItemBinding;
+import awais.instagrabber.models.ProfileModel;
+import awais.instagrabber.models.direct_messages.DirectItemModel;
+import awais.instagrabber.models.enums.DirectItemType;
+import awais.instagrabber.models.enums.MediaItemType;
+import awais.instagrabber.models.enums.RavenExpiringMediaType;
+import awais.instagrabber.models.enums.RavenMediaViewType;
+import awais.instagrabber.utils.Constants;
+import awais.instagrabber.utils.Utils;
+
+import static androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT;
+
+public final class DirectMessageViewHolder extends RecyclerView.ViewHolder {
+ private static final String TAG = "DirectMessageViewHolder";
+ private static final int MESSAGE_INCOMING = 69;
+ private static final int MESSAGE_OUTGOING = 420;
+
+ private final ProfileModel myProfileHolder = ProfileModel.getDefaultProfileModel(Utils.getUserIdFromCookie(Utils.settingsHelper.getString(Constants.COOKIE)));
+ private final ItemMessageItemBinding binding;
+ private final List users;
+ private final List leftUsers;
+ private final int itemMargin;
+ private final String strDmYou;
+ private DirectItemModel.DirectItemVoiceMediaModel prevVoiceModel;
+ private ImageView prevPlayIcon;
+
+ private final View.OnClickListener voicePlayClickListener = v -> {
+ final Object tag = v.getTag();
+ if (v instanceof ViewGroup && tag instanceof DirectItemModel.DirectItemVoiceMediaModel) {
+ final ImageView playIcon = (ImageView) ((ViewGroup) v).getChildAt(0);
+ final DirectItemModel.DirectItemVoiceMediaModel voiceMediaModel = (DirectItemModel.DirectItemVoiceMediaModel) tag;
+ final boolean voicePlaying = voiceMediaModel.isPlaying();
+ voiceMediaModel.setPlaying(!voicePlaying);
+
+ if (voiceMediaModel == prevVoiceModel) {
+ // todo pause / resume
+ } else {
+ // todo release prev audio, start new voice
+ if (prevVoiceModel != null) prevVoiceModel.setPlaying(false);
+ if (prevPlayIcon != null)
+ prevPlayIcon.setImageResource(android.R.drawable.ic_media_play);
+ }
+
+ if (voicePlaying) {
+ playIcon.setImageResource(android.R.drawable.ic_media_play);
+ } else {
+ playIcon.setImageResource(android.R.drawable.ic_media_pause);
+ }
+
+ prevVoiceModel = voiceMediaModel;
+ prevPlayIcon = playIcon;
+ }
+ };
+
+ private final View.OnClickListener openProfileClickListener = v -> {
+ final Object tag = v.getTag();
+ if (tag instanceof ProfileModel) {
+ // todo do profile stuff
+ final ProfileModel profileModel = (ProfileModel) tag;
+ Log.d(TAG, "--> " + profileModel);
+ }
+ };
+
+
+ public DirectMessageViewHolder(final ItemMessageItemBinding binding,
+ final List users,
+ final List leftUsers) {
+ super(binding.getRoot());
+ this.binding = binding;
+ this.users = users;
+ this.leftUsers = leftUsers;
+ this.itemMargin = Utils.displayMetrics.widthPixels / 5;
+ strDmYou = binding.getRoot().getContext().getString(R.string.direct_messages_you);
+ }
+
+ public void bind(final DirectItemModel directItemModel) {
+ if (directItemModel == null) {
+ return;
+ }
+ final Context context = itemView.getContext();
+ itemView.setTag(directItemModel);
+ final DirectItemType itemType = directItemModel.getItemType();
+ final ProfileModel user = getUser(directItemModel.getUserId());
+ final int type = user == myProfileHolder ? MESSAGE_OUTGOING : MESSAGE_INCOMING;
+
+ final RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) itemView.getLayoutParams();
+ layoutParams.setMargins(type == MESSAGE_OUTGOING ? itemMargin : 0, 0,
+ type == MESSAGE_INCOMING ? itemMargin : 0, 0);
+
+ binding.tvMessage.setVisibility(View.GONE);
+ final View voiceMessageContainer = (View) binding.waveformSeekBar.getParent();
+ final View linkMessageContainer = (View) binding.ivLinkPreview.getParent();
+ final View mediaMessageContainer = (View) binding.ivMediaPreview.getParent();
+ final View mediaTypeIcon = binding.typeIcon;
+ final View profileMessageContainer = (View) binding.profileInfo.getParent();
+
+ voiceMessageContainer.setVisibility(View.GONE);
+ binding.ivAnimatedMessage.setVisibility(View.GONE);
+ linkMessageContainer.setVisibility(View.GONE);
+ mediaMessageContainer.setVisibility(View.GONE);
+ mediaTypeIcon.setVisibility(View.GONE);
+ binding.mediaExpiredIcon.setVisibility(View.GONE);
+ profileMessageContainer.setVisibility(View.GONE);
+ binding.isVerified.setVisibility(View.GONE);
+
+ final FrameLayout btnOpenProfile = binding.btnInfo;
+ btnOpenProfile.setVisibility(View.GONE);
+ btnOpenProfile.setOnClickListener(null);
+ btnOpenProfile.setTag(null);
+
+ CharSequence text = "?";
+ if (user != null && user != myProfileHolder) text = user.getUsername();
+ else if (user == myProfileHolder) text = strDmYou;
+ text = text + " - " + directItemModel.getDateTime();
+
+ binding.tvUsername.setText(text);
+
+ binding.ivProfilePic.setVisibility(type == MESSAGE_INCOMING ? View.VISIBLE : View.GONE);
+
+ final RequestManager glideRequestManager = Glide.with(itemView);
+
+ if (type == MESSAGE_INCOMING && user != null)
+ glideRequestManager.load(user.getSdProfilePic()).into(binding.ivProfilePic);
+
+ DirectItemModel.DirectItemMediaModel mediaModel = directItemModel.getMediaModel();
+ switch (itemType) {
+ case PLACEHOLDER:
+ binding.tvMessage.setText(HtmlCompat.fromHtml(directItemModel.getText().toString(), FROM_HTML_MODE_COMPACT));
+ binding.tvMessage.setVisibility(View.VISIBLE);
+ break;
+ case TEXT:
+ case LIKE:
+ text = directItemModel.getText();
+ text = Utils.getSpannableUrl(text.toString()); // for urls
+ if (Utils.hasMentions(text)) text = Utils.getMentionText(text); // for mentions
+
+ if (text instanceof Spanned)
+ binding.tvMessage.setText(text, TextView.BufferType.SPANNABLE);
+ else if (text == "") {
+ binding.tvMessage.setText(context.getText(R.string.dms_inbox_raven_message_unknown));
+ } else binding.tvMessage.setText(text);
+
+ binding.tvMessage.setVisibility(View.VISIBLE);
+ break;
+
+ case LINK: {
+ final DirectItemModel.DirectItemLinkModel link = directItemModel.getLinkModel();
+ final DirectItemModel.DirectItemLinkContext linkContext = link.getLinkContext();
+
+ final String linkImageUrl = linkContext.getLinkImageUrl();
+ if (!Utils.isEmpty(linkImageUrl)) {
+ glideRequestManager.load(linkImageUrl).into(binding.ivLinkPreview);
+ binding.tvLinkTitle.setText(linkContext.getLinkTitle());
+ binding.tvLinkSummary.setText(linkContext.getLinkSummary());
+ binding.ivLinkPreview.setVisibility(View.VISIBLE);
+ linkMessageContainer.setVisibility(View.VISIBLE);
+ }
+
+ binding.tvMessage.setText(Utils.getSpannableUrl(link.getText()));
+ binding.tvMessage.setVisibility(View.VISIBLE);
+ }
+ break;
+
+ case MEDIA_SHARE: {
+ final ProfileModel modelUser = mediaModel.getUser();
+ if (modelUser != null) {
+ binding.tvMessage.setText(HtmlCompat.fromHtml("" + context.getString(R.string.dms_inbox_media_shared_from, modelUser.getUsername()) + "", FROM_HTML_MODE_COMPACT));
+ binding.tvMessage.setVisibility(View.VISIBLE);
+ }
+ }
+ case MEDIA: {
+ glideRequestManager.load(mediaModel.getThumbUrl()).into(binding.ivMediaPreview);
+
+ final MediaItemType modelMediaType = mediaModel.getMediaType();
+ mediaTypeIcon.setVisibility(modelMediaType == MediaItemType.MEDIA_TYPE_VIDEO ||
+ modelMediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
+ mediaMessageContainer.setVisibility(View.VISIBLE);
+ }
+ break;
+
+ case RAVEN_MEDIA: {
+ final DirectItemModel.DirectItemRavenMediaModel ravenMediaModel = directItemModel.getRavenMediaModel();
+
+ final boolean isExpired = ravenMediaModel == null || (mediaModel = ravenMediaModel.getMedia()) == null ||
+ Utils.isEmpty(mediaModel.getThumbUrl()) && mediaModel.getPk() < 1;
+
+ DirectItemModel.RavenExpiringMediaActionSummaryModel mediaActionSummary = null;
+ if (ravenMediaModel != null) {
+ mediaActionSummary = ravenMediaModel.getExpiringMediaActionSummary();
+ }
+ binding.mediaExpiredIcon.setVisibility(isExpired ? View.VISIBLE : View.GONE);
+
+ int textRes = R.string.dms_inbox_raven_media_unknown;
+ if (isExpired) textRes = R.string.dms_inbox_raven_media_expired;
+
+ if (!isExpired) {
+ if (mediaActionSummary != null) {
+ final RavenExpiringMediaType expiringMediaType = mediaActionSummary.getType();
+
+ if (expiringMediaType == RavenExpiringMediaType.RAVEN_DELIVERED)
+ textRes = R.string.dms_inbox_raven_media_delivered;
+ else if (expiringMediaType == RavenExpiringMediaType.RAVEN_SENT)
+ textRes = R.string.dms_inbox_raven_media_sent;
+ else if (expiringMediaType == RavenExpiringMediaType.RAVEN_OPENED)
+ textRes = R.string.dms_inbox_raven_media_opened;
+ else if (expiringMediaType == RavenExpiringMediaType.RAVEN_REPLAYED)
+ textRes = R.string.dms_inbox_raven_media_replayed;
+ else if (expiringMediaType == RavenExpiringMediaType.RAVEN_SENDING)
+ textRes = R.string.dms_inbox_raven_media_sending;
+ else if (expiringMediaType == RavenExpiringMediaType.RAVEN_BLOCKED)
+ textRes = R.string.dms_inbox_raven_media_blocked;
+ else if (expiringMediaType == RavenExpiringMediaType.RAVEN_SUGGESTED)
+ textRes = R.string.dms_inbox_raven_media_suggested;
+ else if (expiringMediaType == RavenExpiringMediaType.RAVEN_SCREENSHOT)
+ textRes = R.string.dms_inbox_raven_media_screenshot;
+ else if (expiringMediaType == RavenExpiringMediaType.RAVEN_CANNOT_DELIVER)
+ textRes = R.string.dms_inbox_raven_media_cant_deliver;
+ }
+
+ final RavenMediaViewType ravenMediaViewType = ravenMediaModel.getViewType();
+ if (ravenMediaViewType == RavenMediaViewType.PERMANENT || ravenMediaViewType == RavenMediaViewType.REPLAYABLE) {
+ final MediaItemType mediaType = mediaModel.getMediaType();
+ textRes = -1;
+ mediaTypeIcon.setVisibility(mediaType == MediaItemType.MEDIA_TYPE_VIDEO ||
+ mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
+
+ glideRequestManager.load(mediaModel.getThumbUrl()).into(binding.ivMediaPreview);
+ mediaMessageContainer.setVisibility(View.VISIBLE);
+ }
+ }
+ if (textRes != -1) {
+ binding.tvMessage.setText(context.getText(textRes));
+ binding.tvMessage.setVisibility(View.VISIBLE);
+ }
+ }
+ break;
+
+ case REEL_SHARE: {
+ final DirectItemModel.DirectItemReelShareModel reelShare = directItemModel.getReelShare();
+ if (!Utils.isEmpty(text = reelShare.getText())) {
+ binding.tvMessage.setText(text);
+ binding.tvMessage.setVisibility(View.VISIBLE);
+ }
+
+ final DirectItemModel.DirectItemMediaModel reelShareMedia = reelShare.getMedia();
+ final MediaItemType mediaType = reelShareMedia.getMediaType();
+
+ if (mediaType == null)
+ binding.mediaExpiredIcon.setVisibility(View.VISIBLE);
+ else {
+ mediaTypeIcon.setVisibility(mediaType == MediaItemType.MEDIA_TYPE_VIDEO ||
+ mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
+
+ glideRequestManager.load(reelShareMedia.getThumbUrl()).into(binding.ivMediaPreview);
+ mediaMessageContainer.setVisibility(View.VISIBLE);
+ }
+ }
+ break;
+
+ case STORY_SHARE: {
+ final DirectItemModel.DirectItemReelShareModel reelShare = directItemModel.getReelShare();
+ if (reelShare == null) {
+ binding.tvMessage.setText(HtmlCompat.fromHtml(directItemModel.getText().toString(), FROM_HTML_MODE_COMPACT));
+ binding.tvMessage.setVisibility(View.VISIBLE);
+ } else {
+ if (!Utils.isEmpty(text = reelShare.getText())) {
+ binding.tvMessage.setText(text);
+ binding.tvMessage.setVisibility(View.VISIBLE);
+ }
+
+ final DirectItemModel.DirectItemMediaModel reelShareMedia = reelShare.getMedia();
+ final MediaItemType mediaType = reelShareMedia.getMediaType();
+
+ mediaTypeIcon.setVisibility(mediaType == MediaItemType.MEDIA_TYPE_VIDEO ||
+ mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
+
+ glideRequestManager.load(reelShareMedia.getThumbUrl()).into(binding.ivMediaPreview);
+ mediaMessageContainer.setVisibility(View.VISIBLE);
+ }
+ }
+ break;
+
+ case VOICE_MEDIA: {
+ final DirectItemModel.DirectItemVoiceMediaModel voiceMediaModel = directItemModel.getVoiceMediaModel();
+
+ if (voiceMediaModel != null) {
+ final int[] waveformData = voiceMediaModel.getWaveformData();
+ if (waveformData != null) binding.waveformSeekBar.setSample(waveformData);
+
+ final long durationMs = voiceMediaModel.getDurationMs();
+ binding.tvVoiceDuration.setText(Utils.millisToString(durationMs));
+ binding.waveformSeekBar.setProgress(voiceMediaModel.getProgress());
+ binding.waveformSeekBar.setProgressChangeListener((waveformSeekBar, progress, fromUser) -> {
+ // todo progress audio player
+ voiceMediaModel.setProgress(progress);
+ if (fromUser)
+ binding.tvVoiceDuration.setText(Utils.millisToString(durationMs * progress / 100));
+ });
+ binding.btnPlayVoice.setTag(voiceMediaModel);
+ binding.btnPlayVoice.setOnClickListener(voicePlayClickListener);
+ } else {
+ binding.waveformSeekBar.setProgress(0);
+ }
+ voiceMessageContainer.setVisibility(View.VISIBLE);
+ }
+ break;
+
+ case ANIMATED_MEDIA: {
+ glideRequestManager.asGif().load(directItemModel.getAnimatedMediaModel().getGifUrl())
+ .into(binding.ivAnimatedMessage);
+ binding.ivAnimatedMessage.setVisibility(View.VISIBLE);
+ }
+ break;
+
+ case PROFILE: {
+ final ProfileModel profileModel = directItemModel.getProfileModel();
+ Glide.with(binding.profileInfo).load(profileModel.getSdProfilePic())
+ .into(binding.profileInfo);
+ btnOpenProfile.setTag(profileModel);
+ btnOpenProfile.setOnClickListener(openProfileClickListener);
+
+ binding.tvFullName.setText(profileModel.getName());
+ binding.profileInfoText.setText(profileModel.getUsername());
+ binding.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE);
+
+ btnOpenProfile.setVisibility(View.VISIBLE);
+ profileMessageContainer.setVisibility(View.VISIBLE);
+ }
+ break;
+
+ case VIDEO_CALL_EVENT: {
+ // todo add call event info
+ binding.tvMessage.setVisibility(View.VISIBLE);
+ binding.profileInfoText.setBackgroundColor(0xFF_1F90E6);
+ }
+ break;
+
+ case ACTION_LOG: {
+ text = directItemModel.getActionLogModel().getDescription();
+ binding.tvMessage.setText(HtmlCompat.fromHtml("" + text + "", FROM_HTML_MODE_COMPACT));
+ binding.tvMessage.setVisibility(View.VISIBLE);
+ }
+ break;
+ }
+ }
+
+ @Nullable
+ private ProfileModel getUser(final long userId) {
+ if (users != null) {
+ ProfileModel result = myProfileHolder;
+ for (final ProfileModel user : users) {
+ if (Long.toString(userId).equals(user.getId())) result = user;
+ }
+ if (leftUsers != null)
+ for (final ProfileModel leftUser : leftUsers) {
+ if (Long.toString(userId).equals(leftUser.getId())) result = leftUser;
+ }
+ return result;
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/TextMessageViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/TextMessageViewHolder.java
deleted file mode 100755
index 3e1bed67..00000000
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/TextMessageViewHolder.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package awais.instagrabber.adapters.viewholder.directmessages;
-
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.cardview.widget.CardView;
-import androidx.recyclerview.widget.RecyclerView;
-
-import awais.instagrabber.R;
-import awais.instagrabber.customviews.RamboTextView;
-import awais.instagrabber.customviews.masoudss_waveform.WaveformSeekBar;
-import awais.instagrabber.interfaces.MentionClickListener;
-
-public final class TextMessageViewHolder extends RecyclerView.ViewHolder {
- public final CardView rootCardView;
- public final TextView tvUsername;
- public final ImageView ivProfilePic;
- // text message
- public final RamboTextView tvMessage;
- // expired message icon
- public final View mediaExpiredIcon;
- // media message
- public final View mediaMessageContainer;
- public final ImageView ivMediaPreview, mediaTypeIcon;
- // profile messag
- public final View profileMessageContainer, isVerified, btnOpenProfile;
- public final TextView tvProfileUsername, tvProfileName;
- public final ImageView ivMessageProfilePic;
- // animated message
- public final ImageView ivAnimatedMessage;
- // link message
- public final View linkMessageContainer;
- public final ImageView ivLinkPreview;
- public final TextView tvLinkTitle, tvLinkSummary;
- // voice message
- public final View voiceMessageContainer, btnPlayVoice;
- public final WaveformSeekBar waveformSeekBar;
- public final TextView tvVoiceDuration;
-
- public TextMessageViewHolder(@NonNull final View itemView, final View.OnClickListener clickListener,
- final MentionClickListener mentionClickListener) {
- super(itemView);
-
- if (clickListener != null) itemView.setOnClickListener(clickListener);
-
- tvUsername = itemView.findViewById(R.id.tvUsername);
- ivProfilePic = itemView.findViewById(R.id.ivProfilePic);
-
- // text message
- tvMessage = itemView.findViewById(R.id.tvMessage);
- tvMessage.setCaptionIsExpandable(true);
- tvMessage.setCaptionIsExpanded(true);
- if (mentionClickListener != null) tvMessage.setMentionClickListener(mentionClickListener);
-
- // root view
- rootCardView = (CardView) tvMessage.getParent().getParent();
-
- // expired message icon
- mediaExpiredIcon = itemView.findViewById(R.id.mediaExpiredIcon);
-
- // media message
- ivMediaPreview = itemView.findViewById(R.id.ivMediaPreview);
- mediaMessageContainer = (View) ivMediaPreview.getParent();
- mediaTypeIcon = mediaMessageContainer.findViewById(R.id.typeIcon);
-
- // profile message
- btnOpenProfile = itemView.findViewById(R.id.btnInfo);
- ivMessageProfilePic = itemView.findViewById(R.id.profileInfo);
- profileMessageContainer = (View) ivMessageProfilePic.getParent();
- isVerified = profileMessageContainer.findViewById(R.id.isVerified);
- tvProfileName = profileMessageContainer.findViewById(R.id.tvFullName);
- tvProfileUsername = profileMessageContainer.findViewById(R.id.profileInfoText);
-
- // animated message
- ivAnimatedMessage = itemView.findViewById(R.id.ivAnimatedMessage);
-
- // link message
- ivLinkPreview = itemView.findViewById(R.id.ivLinkPreview);
- linkMessageContainer = (View) ivLinkPreview.getParent();
- tvLinkTitle = linkMessageContainer.findViewById(R.id.tvLinkTitle);
- tvLinkSummary = linkMessageContainer.findViewById(R.id.tvLinkSummary);
-
- // voice message
- waveformSeekBar = itemView.findViewById(R.id.waveformSeekBar);
- voiceMessageContainer = (View) waveformSeekBar.getParent();
- btnPlayVoice = voiceMessageContainer.findViewById(R.id.btnPlayVoice);
- tvVoiceDuration = voiceMessageContainer.findViewById(R.id.tvVoiceDuration);
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/asyncs/direct_messages/UserInboxFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/direct_messages/DirectMessageInboxThreadFetcher.java
old mode 100755
new mode 100644
similarity index 67%
rename from app/src/main/java/awais/instagrabber/asyncs/direct_messages/UserInboxFetcher.java
rename to app/src/main/java/awais/instagrabber/asyncs/direct_messages/DirectMessageInboxThreadFetcher.java
index d38a9301..b45d44bd
--- a/app/src/main/java/awais/instagrabber/asyncs/direct_messages/UserInboxFetcher.java
+++ b/app/src/main/java/awais/instagrabber/asyncs/direct_messages/DirectMessageInboxThreadFetcher.java
@@ -9,6 +9,8 @@ import org.json.JSONObject;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.interfaces.FetchListener;
@@ -21,17 +23,21 @@ import awais.instagrabber.utils.Utils;
import static awais.instagrabber.utils.Utils.logCollector;
import static awaisomereport.LogCollector.LogFile;
-public final class UserInboxFetcher extends AsyncTask {
+public final class DirectMessageInboxThreadFetcher extends AsyncTask {
+ private static final String TAG = "DMInboxThreadFetcher";
+
private final String id;
private final String endCursor;
private final FetchListener fetchListener;
- private final String direction;
+ private final UserInboxDirection direction;
- public UserInboxFetcher(final String id, final UserInboxDirection direction, final String endCursor,
- final FetchListener fetchListener) {
+ public DirectMessageInboxThreadFetcher(final String id,
+ final UserInboxDirection direction,
+ final String cursor,
+ final FetchListener fetchListener) {
this.id = id;
- this.direction = "&direction=" + (direction == UserInboxDirection.NEWER ? "newer" : "older");
- this.endCursor = !Utils.isEmpty(endCursor) ? "&cursor=" + endCursor : "";
+ this.direction = direction;
+ this.endCursor = cursor;
this.fetchListener = fetchListener;
}
@@ -39,11 +45,14 @@ public final class UserInboxFetcher extends AsyncTask queryParamsMap = new HashMap<>();
+ queryParamsMap.put("visual_message_return_type", "unseen");
+ queryParamsMap.put("direction", direction.getValue());
+ if (!Utils.isEmpty(endCursor)) {
+ queryParamsMap.put("cursor", endCursor);
+ }
+ final String queryString = Utils.getQueryString(queryParamsMap);
+ final String url = "https://i.instagram.com/api/v1/direct_v2/threads/" + id + "/?" + queryString;
try {
final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestProperty("User-Agent", Constants.I_USER_AGENT);
@@ -60,9 +69,8 @@ public final class UserInboxFetcher extends AsyncTask currentlyRunning;
+ private InboxThreadModelListViewModel listViewModel;
+
+ private final FetchListener fetchListener = new FetchListener() {
+ @Override
+ public void doBefore() {
+ root.setRefreshing(true);
+ }
+
+ @Override
+ public void onResult(final InboxModel inboxModel) {
+ if (inboxModel != null) {
+ endCursor = inboxModel.getOldestCursor();
+ if ("MINCURSOR".equals(endCursor) || "MAXCURSOR".equals(endCursor))
+ endCursor = null;
+ // todo get request / unseen count from inboxModel
+ final InboxThreadModel[] threads = inboxModel.getThreads();
+ if (threads != null && threads.length > 0) {
+ List list = listViewModel.getList().getValue();
+ list = list != null ? new LinkedList<>(list) : new LinkedList<>();
+ // final int oldSize = list != null ? list.size() : 0;
+ final List newList = Arrays.asList(threads);
+ list.addAll(newList);
+ listViewModel.getList().postValue(list);
+ }
+ }
+ root.setRefreshing(false);
+ stopCurrentExecutor();
+ }
+ };
+
+ @Override
+ public void onCreate(@Nullable final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ fragmentActivity = requireActivity();
+ }
+
+ @Override
+ public View onCreateView(@NonNull final LayoutInflater inflater,
+ final ViewGroup container,
+ final Bundle savedInstanceState) {
+ if (root != null) {
+ return root;
+ }
+ final FragmentDirectMessagesInboxBinding binding = FragmentDirectMessagesInboxBinding.inflate(inflater, container, false);
+ root = binding.getRoot();
+ root.setOnRefreshListener(this);
+ inboxList = binding.inboxList;
+ inboxList.setHasFixedSize(true);
+ layoutManager = new LinearLayoutManager(requireContext());
+ inboxList.setLayoutManager(layoutManager);
+ final DirectMessageInboxAdapter inboxAdapter = new DirectMessageInboxAdapter(inboxThreadModel -> {
+ final NavDirections action = DirectMessagesInboxFragmentDirections.actionDMInboxFragmentToDMThreadFragment(inboxThreadModel.getThreadId(), inboxThreadModel.getThreadTitle());
+ NavHostFragment.findNavController(this).navigate(action);
+ });
+ inboxList.setAdapter(inboxAdapter);
+ listViewModel = new ViewModelProvider(fragmentActivity).get(InboxThreadModelListViewModel.class);
+ listViewModel.getList().observe(fragmentActivity, inboxAdapter::submitList);
+ initData();
+ return root;
+ }
+
+ @Override
+ public void onRefresh() {
+ endCursor = null;
+ lazyLoader.resetState();
+ listViewModel.getList().postValue(Collections.emptyList());
+ stopCurrentExecutor();
+ currentlyRunning = new InboxFetcher(null, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
+ private void initData() {
+ lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
+ if (!Utils.isEmpty(endCursor))
+ currentlyRunning = new InboxFetcher(endCursor, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ endCursor = null;
+ });
+ inboxList.addOnScrollListener(lazyLoader);
+ stopCurrentExecutor();
+ currentlyRunning = new InboxFetcher(null, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
+ private void stopCurrentExecutor() {
+ if (currentlyRunning != null) {
+ try {
+ currentlyRunning.cancel(true);
+ } catch (final Exception e) {
+ if (BuildConfig.DEBUG) Log.e(TAG, "", e);
+ }
+ }
+ }
+
+ public static class InboxThreadModelListViewModel extends ViewModel {
+ private MutableLiveData> list;
+
+ public MutableLiveData> getList() {
+ if (list == null) {
+ list = new MutableLiveData<>();
+ }
+ return list;
+ }
+ }
+}
diff --git a/app/src/main/java/awais/instagrabber/activities/directmessages/DirectMessageThread.java b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java
similarity index 51%
rename from app/src/main/java/awais/instagrabber/activities/directmessages/DirectMessageThread.java
rename to app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java
index 7a374a2d..1e6b37f2 100644
--- a/app/src/main/java/awais/instagrabber/activities/directmessages/DirectMessageThread.java
+++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java
@@ -1,17 +1,26 @@
-package awais.instagrabber.activities.directmessages;
+package awais.instagrabber.fragments.directmessages;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.Handler;
import android.os.ParcelFileDescriptor;
-import android.text.TextUtils;
import android.util.Log;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
import android.widget.Toast;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -25,24 +34,21 @@ import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import awais.instagrabber.R;
-import awais.instagrabber.activities.BaseLanguageActivity;
import awais.instagrabber.activities.PostViewer;
import awais.instagrabber.activities.ProfileViewer;
import awais.instagrabber.activities.StoryViewer;
import awais.instagrabber.adapters.MessageItemsAdapter;
import awais.instagrabber.asyncs.ImageUploader;
+import awais.instagrabber.asyncs.direct_messages.DirectMessageInboxThreadFetcher;
import awais.instagrabber.asyncs.direct_messages.DirectThreadBroadcaster;
-import awais.instagrabber.asyncs.direct_messages.DirectThreadBroadcaster.BroadcastOptions;
-import awais.instagrabber.asyncs.direct_messages.DirectThreadBroadcaster.ImageBroadcastOptions;
-import awais.instagrabber.asyncs.direct_messages.DirectThreadBroadcaster.OnBroadcastCompleteListener;
-import awais.instagrabber.asyncs.direct_messages.DirectThreadBroadcaster.TextBroadcastOptions;
-import awais.instagrabber.asyncs.direct_messages.UserInboxFetcher;
import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
-import awais.instagrabber.databinding.ActivityDmsBinding;
+import awais.instagrabber.databinding.FragmentDirectMessagesThreadBinding;
import awais.instagrabber.interfaces.FetchListener;
+import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.ImageUploadOptions;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.ProfileModel;
@@ -55,72 +61,34 @@ import awais.instagrabber.models.enums.UserInboxDirection;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils;
-import static android.view.View.VISIBLE;
-
-public final class DirectMessageThread extends BaseLanguageActivity {
- private static final String TAG = "DirectMessageThread";
+public class DirectMessageThreadFragment extends Fragment {
+ private static final String TAG = "DirectMessagesThreadFmt";
private static final int PICK_IMAGE = 100;
- private DirectItemModel directItemModel;
+ private FragmentActivity fragmentActivity;
private String threadId;
- private String endCursor;
- private ActivityDmsBinding dmsBinding;
- private MessageItemsAdapter messageItemsAdapter;
+ private String cursor;
+ private FragmentDirectMessagesThreadBinding binding;
+ private DirectItemModelListViewModel listViewModel;
+ private RecyclerView messageList;
+ private boolean hasSentSomething;
+ private boolean hasOlder = true;
private final ProfileModel myProfileHolder = ProfileModel.getDefaultProfileModel();
- private final ArrayList users = new ArrayList<>();
- private final ArrayList leftUsers = new ArrayList<>();
- private final ArrayList directItemModels = new ArrayList<>();
- private final FetchListener fetchListener = new FetchListener() {
- @Override
- public void doBefore() {
- dmsBinding.swipeRefreshLayout.setRefreshing(true);
- }
+ private final List users = new ArrayList<>();
+ private final List leftUsers = new ArrayList<>();
- @Override
- public void onResult(final InboxThreadModel result) {
- if (result == null && ("MINCURSOR".equals(endCursor) || "MAXCURSOR".equals(endCursor) || Utils.isEmpty(endCursor)))
- Toast.makeText(DirectMessageThread.this, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
-
- if (result != null) {
- endCursor = result.getPrevCursor();
- if ("MINCURSOR".equals(endCursor) || "MAXCURSOR".equals(endCursor))
- endCursor = null;
-
- users.clear();
- users.addAll(Arrays.asList(result.getUsers()));
-
- leftUsers.clear();
- leftUsers.addAll(Arrays.asList(result.getLeftUsers()));
-
- threadId = result.getThreadId();
- dmsBinding.toolbar.toolbar.setTitle(result.getThreadTitle());
- String[] users = new String[result.getUsers().length];
- for (int i = 0; i < users.length; ++i) {
- users[i] = result.getUsers()[i].getUsername();
- }
- dmsBinding.toolbar.toolbar.setSubtitle(TextUtils.join(", ", users));
-
- final int oldSize = directItemModels.size();
- final List itemModels = Arrays.asList(result.getItems());
- directItemModels.addAll(itemModels);
- messageItemsAdapter.notifyItemRangeInserted(oldSize, itemModels.size());
- }
-
- dmsBinding.swipeRefreshLayout.setRefreshing(false);
- }
- };
private final View.OnClickListener clickListener = v -> {
- if (v == dmsBinding.commentSend) {
- final String text = dmsBinding.commentText.getText().toString();
+ if (v == binding.commentSend) {
+ final String text = binding.commentText.getText().toString();
if (Utils.isEmpty(text)) {
- Toast.makeText(getApplicationContext(), R.string.comment_send_empty_comment, Toast.LENGTH_SHORT).show();
+ Toast.makeText(requireContext(), R.string.comment_send_empty_comment, Toast.LENGTH_SHORT).show();
return;
}
sendText(text);
return;
}
- if (v == dmsBinding.image) {
+ if (v == binding.image) {
final Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
@@ -128,45 +96,95 @@ public final class DirectMessageThread extends BaseLanguageActivity {
}
};
- @Override
- protected void onCreate(@Nullable final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- dmsBinding = ActivityDmsBinding.inflate(getLayoutInflater());
- setContentView(dmsBinding.getRoot());
-
- final InboxThreadModel threadModel;
- final Intent intent = getIntent();
- if (intent == null || !intent.hasExtra(Constants.EXTRAS_THREAD_MODEL) ||
- (threadModel = (InboxThreadModel) intent.getSerializableExtra(Constants.EXTRAS_THREAD_MODEL)) == null) {
- Utils.errorFinish(this);
- return;
+ private final FetchListener fetchListener = new FetchListener() {
+ @Override
+ public void doBefore() {
+ binding.swipeRefreshLayout.setRefreshing(true);
}
- dmsBinding.swipeRefreshLayout.setEnabled(false);
- dmsBinding.commentText.setVisibility(VISIBLE);
- dmsBinding.commentSend.setVisibility(VISIBLE);
- dmsBinding.image.setVisibility(VISIBLE);
- dmsBinding.commentSend.setOnClickListener(clickListener);
- dmsBinding.image.setOnClickListener(clickListener);
+ @Override
+ public void onResult(final InboxThreadModel result) {
+ if (result == null && ("MINCURSOR".equals(cursor) || "MAXCURSOR".equals(cursor) || Utils.isEmpty(cursor)))
+ Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- final LinearLayoutManager layoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, true);
- dmsBinding.rvDirectMessages.setLayoutManager(layoutManager);
+ if (result != null) {
+ cursor = result.getOldestCursor();
+ hasOlder = result.hasOlder();
+ if ("MINCURSOR".equals(cursor) || "MAXCURSOR".equals(cursor)) {
+ cursor = null;
+ }
+ users.clear();
+ users.addAll(Arrays.asList(result.getUsers()));
+ leftUsers.clear();
+ leftUsers.addAll(Arrays.asList(result.getLeftUsers()));
- dmsBinding.rvDirectMessages.addOnScrollListener(new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
- if (!Utils.isEmpty(endCursor)) {
- new UserInboxFetcher(threadModel.getThreadId(), UserInboxDirection.OLDER,
- endCursor, fetchListener).execute(); // serial because we don't want messages to be randomly ordered
+ // thread title is already comma separated username, so no need to set by ourselves
+ // String[] users = new String[result.getUsers().length];
+ // for (int i = 0; i < users.length; ++i) {
+ // users[i] = result.getUsers()[i].getUsername();
+ // }
+
+ List list = listViewModel.getList().getValue();
+ final List newList = Arrays.asList(result.getItems());
+ list = list != null ? new LinkedList<>(list) : new LinkedList<>();
+ if (hasSentSomething) {
+ list = newList;
+ hasSentSomething = false;
+ final Handler handler = new Handler();
+ handler.postDelayed(() -> {
+ if (messageList != null) {
+ messageList.smoothScrollToPosition(0);
+ }
+ }, 200);
+ } else {
+ list.addAll(newList);
+ }
+ listViewModel.getList().postValue(list);
}
+ binding.swipeRefreshLayout.setRefreshing(false);
+ }
+ };
+
+ @Override
+ public void onCreate(@Nullable final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ fragmentActivity = requireActivity();
+ }
+
+ @Override
+ public View onCreateView(@NonNull final LayoutInflater inflater,
+ final ViewGroup container,
+ final Bundle savedInstanceState) {
+ binding = FragmentDirectMessagesThreadBinding.inflate(inflater, container, false);
+ final LinearLayout root = binding.getRoot();
+ if (getArguments() == null) {
+ return root;
+ }
+ threadId = DirectMessagesThreadFragmentArgs.fromBundle(getArguments()).getThreadId();
+ binding.swipeRefreshLayout.setEnabled(false);
+ messageList = binding.messageList;
+ messageList.setHasFixedSize(true);
+ binding.commentSend.setOnClickListener(clickListener);
+ binding.image.setOnClickListener(clickListener);
+ final LinearLayoutManager layoutManager = new LinearLayoutManager(requireContext());
+ layoutManager.setReverseLayout(true);
+ // layoutManager.setStackFromEnd(true);
+ messageList.setLayoutManager(layoutManager);
+ messageList.addOnScrollListener(new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
+ if (Utils.isEmpty(cursor) || !hasOlder) {
+ return;
+ }
+ new DirectMessageInboxThreadFetcher(threadId, UserInboxDirection.OLDER, cursor, fetchListener).execute(); // serial because we don't want messages to be randomly ordered
}));
- messageItemsAdapter = new MessageItemsAdapter(directItemModels, users, leftUsers, v -> {
+ final View.OnClickListener onClickListener = v -> {
Object tag = v.getTag();
if (tag instanceof DirectItemModel) {
- directItemModel = (DirectItemModel) tag;
+ final DirectItemModel directItemModel = (DirectItemModel) tag;
final DirectItemType itemType = directItemModel.getItemType();
switch (itemType) {
case MEDIA_SHARE:
- startActivity(new Intent(this, PostViewer.class)
+ startActivity(new Intent(requireContext(), PostViewer.class)
.putExtra(Constants.EXTRAS_POST, new PostModel(directItemModel.getMediaModel().getCode(), false)));
break;
case LINK:
@@ -182,9 +200,7 @@ public final class DirectMessageThread extends BaseLanguageActivity {
case RAVEN_MEDIA:
case MEDIA:
final ProfileModel user = getUser(directItemModel.getUserId());
- if (user != null) {
- Utils.dmDownload(this, user.getUsername(), DownloadMethod.DOWNLOAD_DIRECT, Collections.singletonList(itemType == DirectItemType.MEDIA ? directItemModel.getMediaModel() : directItemModel.getRavenMediaModel().getMedia()));
- }
+ Utils.dmDownload(requireContext(), user.getUsername(), DownloadMethod.DOWNLOAD_DIRECT, Collections.singletonList(itemType == DirectItemType.MEDIA ? directItemModel.getMediaModel() : directItemModel.getRavenMediaModel().getMedia()));
Toast.makeText(v.getContext(), R.string.downloader_downloading_media, Toast.LENGTH_SHORT).show();
break;
case STORY_SHARE:
@@ -200,7 +216,7 @@ public final class DirectMessageThread extends BaseLanguageActivity {
);
sm.setVideoUrl(directItemModel.getReelShare().getMedia().getVideoUrl());
StoryModel[] sms = {sm};
- startActivity(new Intent(this, StoryViewer.class)
+ startActivity(new Intent(requireContext(), StoryViewer.class)
.putExtra(Constants.EXTRAS_USERNAME, directItemModel.getReelShare().getReelOwnerName())
.putExtra(Constants.EXTRAS_STORIES, sms)
);
@@ -216,15 +232,18 @@ public final class DirectMessageThread extends BaseLanguageActivity {
Log.d("austin_debug", "unsupported type " + itemType);
}
}
- }, (view, text, isHashtag) -> searchUsername(text));
-
- dmsBinding.rvDirectMessages.setAdapter(messageItemsAdapter);
-
- new UserInboxFetcher(threadModel.getThreadId(), UserInboxDirection.OLDER, null, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ };
+ final MentionClickListener mentionClickListener = (view, text, isHashtag) -> searchUsername(text);
+ final MessageItemsAdapter adapter = new MessageItemsAdapter(users, leftUsers, onClickListener, mentionClickListener);
+ messageList.setAdapter(adapter);
+ listViewModel = new ViewModelProvider(fragmentActivity).get(DirectItemModelListViewModel.class);
+ listViewModel.getList().observe(fragmentActivity, adapter::submitList);
+ new DirectMessageInboxThreadFetcher(threadId, UserInboxDirection.OLDER, null, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ return root;
}
@Override
- protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+ public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE && resultCode == Activity.RESULT_OK) {
if (data == null || data.getData() == null) {
@@ -236,61 +255,46 @@ public final class DirectMessageThread extends BaseLanguageActivity {
}
}
- @Nullable
- private ProfileModel getUser(final long userId) {
- if (users != null) {
- ProfileModel result = myProfileHolder;
- for (final ProfileModel user : users) {
- if (Long.toString(userId).equals(user.getId())) result = user;
- }
- if (leftUsers != null)
- for (final ProfileModel leftUser : leftUsers) {
- if (Long.toString(userId).equals(leftUser.getId())) result = leftUser;
- }
- return result;
- }
- return null;
- }
-
- private void searchUsername(final String text) {
- startActivity(new Intent(getApplicationContext(), ProfileViewer.class).putExtra(Constants.EXTRAS_USERNAME, text));
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ listViewModel.getList().postValue(Collections.emptyList());
}
private void sendText(final String text) {
- final TextBroadcastOptions options;
+ final DirectThreadBroadcaster.TextBroadcastOptions options;
try {
- options = new TextBroadcastOptions(text);
+ options = new DirectThreadBroadcaster.TextBroadcastOptions(text);
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Error", e);
return;
}
broadcast(options, result -> {
if (result == null || result.getResponseCode() != HttpURLConnection.HTTP_OK) {
- Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
+ Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
return;
}
- dmsBinding.commentText.setText("");
- dmsBinding.commentText.clearFocus();
- directItemModels.clear();
- messageItemsAdapter.notifyDataSetChanged();
- new UserInboxFetcher(threadId, UserInboxDirection.OLDER, null, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ binding.commentText.setText("");
+ // binding.commentText.clearFocus();
+ hasSentSomething = true;
+ new DirectMessageInboxThreadFetcher(threadId, UserInboxDirection.OLDER, null, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
});
}
private void sendImage(final Uri imageUri) {
try {
- final ParcelFileDescriptor fileDescriptor = getContentResolver().openFileDescriptor(imageUri, "r");
+ final ParcelFileDescriptor fileDescriptor = requireContext().getContentResolver().openFileDescriptor(imageUri, "r");
if (fileDescriptor == null) {
Log.e(TAG, "fileDescriptor is null!");
return;
}
final long contentLength = fileDescriptor.getStatSize();
- final InputStream inputStream = getContentResolver().openInputStream(imageUri);
+ final InputStream inputStream = requireContext().getContentResolver().openInputStream(imageUri);
// Upload Image
final ImageUploader imageUploader = new ImageUploader();
imageUploader.setOnTaskCompleteListener(response -> {
if (response == null || response.getResponseCode() != HttpURLConnection.HTTP_OK) {
- Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
+ Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
if (response != null && response.getResponse() != null) {
Log.e(TAG, response.getResponse().toString());
}
@@ -300,12 +304,9 @@ public final class DirectMessageThread extends BaseLanguageActivity {
try {
final String uploadId = responseJson.getString("upload_id");
// Broadcast
- final ImageBroadcastOptions options = new ImageBroadcastOptions(true, uploadId);
- broadcast(options, onBroadcastCompleteListener -> {
- directItemModels.clear();
- messageItemsAdapter.notifyDataSetChanged();
- new UserInboxFetcher(threadId, UserInboxDirection.OLDER, null, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- });
+ final DirectThreadBroadcaster.ImageBroadcastOptions options = new DirectThreadBroadcaster.ImageBroadcastOptions(true, uploadId);
+ hasSentSomething = true;
+ broadcast(options, onBroadcastCompleteListener -> new DirectMessageInboxThreadFetcher(threadId, UserInboxDirection.OLDER, null, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR));
} catch (JSONException e) {
Log.e(TAG, "Error parsing json response", e);
}
@@ -317,9 +318,36 @@ public final class DirectMessageThread extends BaseLanguageActivity {
}
}
- private void broadcast(final BroadcastOptions broadcastOptions, final OnBroadcastCompleteListener listener) {
+ private void broadcast(final DirectThreadBroadcaster.BroadcastOptions broadcastOptions, final DirectThreadBroadcaster.OnBroadcastCompleteListener listener) {
final DirectThreadBroadcaster broadcaster = new DirectThreadBroadcaster(threadId);
broadcaster.setOnTaskCompleteListener(listener);
broadcaster.execute(broadcastOptions);
}
-}
\ No newline at end of file
+
+ @NonNull
+ private ProfileModel getUser(final long userId) {
+ ProfileModel result = myProfileHolder;
+ for (final ProfileModel user : users) {
+ if (Long.toString(userId).equals(user.getId())) result = user;
+ }
+ for (final ProfileModel leftUser : leftUsers) {
+ if (Long.toString(userId).equals(leftUser.getId())) result = leftUser;
+ }
+ return result;
+ }
+
+ private void searchUsername(final String text) {
+ startActivity(new Intent(requireContext(), ProfileViewer.class).putExtra(Constants.EXTRAS_USERNAME, text));
+ }
+
+ public static class DirectItemModelListViewModel extends ViewModel {
+ private MutableLiveData> list;
+
+ public MutableLiveData> getList() {
+ if (list == null) {
+ list = new MutableLiveData<>();
+ }
+ return list;
+ }
+ }
+}
diff --git a/app/src/main/java/awais/instagrabber/models/ProfileModel.java b/app/src/main/java/awais/instagrabber/models/ProfileModel.java
index 027cbf03..ac75527f 100755
--- a/app/src/main/java/awais/instagrabber/models/ProfileModel.java
+++ b/app/src/main/java/awais/instagrabber/models/ProfileModel.java
@@ -35,6 +35,10 @@ public final class ProfileModel implements Serializable {
return new ProfileModel(false, false, false, null, null, null, null, null, null, null, 0, 0, 0, false, false, false, false);
}
+ public static ProfileModel getDefaultProfileModel(final String userId) {
+ return new ProfileModel(false, false, false, userId, null, null, null, null, null, null, 0, 0, 0, false, false, false, false);
+ }
+
public boolean isPrivate() {
return isPrivate;
}
diff --git a/app/src/main/java/awais/instagrabber/models/direct_messages/InboxThreadModel.java b/app/src/main/java/awais/instagrabber/models/direct_messages/InboxThreadModel.java
index 9678023a..2eec3549 100755
--- a/app/src/main/java/awais/instagrabber/models/direct_messages/InboxThreadModel.java
+++ b/app/src/main/java/awais/instagrabber/models/direct_messages/InboxThreadModel.java
@@ -1,5 +1,7 @@
package awais.instagrabber.models.direct_messages;
+import androidx.core.util.ObjectsCompat;
+
import java.io.Serializable;
import awais.instagrabber.models.ProfileModel;
@@ -123,7 +125,7 @@ public final class InboxThreadModel implements Serializable {
return canonical;
}
- public boolean isHasOlder() {
+ public boolean hasOlder() {
return hasOlder;
}
@@ -142,4 +144,18 @@ public final class InboxThreadModel implements Serializable {
public long getLastActivityAt() {
return lastActivityAt;
}
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ final InboxThreadModel that = (InboxThreadModel) o;
+ return ObjectsCompat.equals(threadId, that.threadId) &&
+ ObjectsCompat.equals(threadV2Id, that.threadV2Id);
+ }
+
+ @Override
+ public int hashCode() {
+ return ObjectsCompat.hash(threadId, threadV2Id);
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/models/enums/UserInboxDirection.java b/app/src/main/java/awais/instagrabber/models/enums/UserInboxDirection.java
index 620c50f0..dc6cf83a 100755
--- a/app/src/main/java/awais/instagrabber/models/enums/UserInboxDirection.java
+++ b/app/src/main/java/awais/instagrabber/models/enums/UserInboxDirection.java
@@ -1,6 +1,16 @@
package awais.instagrabber.models.enums;
public enum UserInboxDirection {
- OLDER,
- NEWER,
+ OLDER("older"),
+ NEWER("newer");
+
+ private final String value;
+
+ UserInboxDirection(final String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/utils/Utils.java b/app/src/main/java/awais/instagrabber/utils/Utils.java
index 033b3f26..9d25ecd3 100755
--- a/app/src/main/java/awais/instagrabber/utils/Utils.java
+++ b/app/src/main/java/awais/instagrabber/utils/Utils.java
@@ -42,6 +42,7 @@ import androidx.fragment.app.FragmentManager;
import org.json.JSONArray;
import org.json.JSONObject;
+import org.jsoup.internal.StringUtil;
import java.io.BufferedReader;
import java.io.File;
@@ -58,6 +59,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Set;
import java.util.regex.Pattern;
import javax.crypto.Mac;
@@ -1371,4 +1373,24 @@ public final class Utils {
connection.setRequestProperty(header.getKey(), header.getValue());
}
}
+
+ public static String getQueryString(final Map queryParamsMap) {
+ if (queryParamsMap == null || queryParamsMap.isEmpty()) {
+ return "";
+ }
+ final Set> params = queryParamsMap.entrySet();
+ final StringBuilder builder = new StringBuilder();
+ for (final Map.Entry param : params) {
+ if (isEmpty(param.getKey())) {
+ continue;
+ }
+ if (builder.length() != 0) {
+ builder.append("&");
+ }
+ builder.append(param.getKey());
+ builder.append("=");
+ builder.append(param.getValue() != null ? param.getValue() : "");
+ }
+ return builder.toString();
+ }
}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_direct_messages.xml b/app/src/main/res/layout/activity_direct_messages.xml
new file mode 100644
index 00000000..cda5e611
--- /dev/null
+++ b/app/src/main/res/layout/activity_direct_messages.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_direct_messages_inbox.xml b/app/src/main/res/layout/fragment_direct_messages_inbox.xml
new file mode 100644
index 00000000..724b313f
--- /dev/null
+++ b/app/src/main/res/layout/fragment_direct_messages_inbox.xml
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/app/src/main/res/layout/activity_dms.xml b/app/src/main/res/layout/fragment_direct_messages_thread.xml
old mode 100755
new mode 100644
similarity index 81%
rename from app/src/main/res/layout/activity_dms.xml
rename to app/src/main/res/layout/fragment_direct_messages_thread.xml
index 2d7c0f83..5ff80e79
--- a/app/src/main/res/layout/activity_dms.xml
+++ b/app/src/main/res/layout/fragment_direct_messages_thread.xml
@@ -1,24 +1,18 @@
-
-
+ android:orientation="vertical">
+ android:layout_weight="1">
@@ -31,7 +25,7 @@
android:id="@+id/commentText"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_weight="2"
+ android:layout_weight="1"
android:gravity="bottom"
android:hint="@string/dm_hint"
android:importantForAutofill="no"
@@ -42,8 +36,7 @@
android:paddingLeft="8dp"
android:paddingEnd="4dp"
android:paddingRight="4dp"
- android:scrollHorizontally="false"
- android:visibility="visible" />
+ android:scrollHorizontally="false" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_message_item.xml b/app/src/main/res/layout/item_message_item.xml
index 46235156..ca78d237 100755
--- a/app/src/main/res/layout/item_message_item.xml
+++ b/app/src/main/res/layout/item_message_item.xml
@@ -4,8 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal"
- tools:viewBindingIgnore="true">
+ android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a7682f9d..276a9348 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -181,7 +181,7 @@
Like comment
Unlike comment
Delete comment
- No empty comments, dawg!
+ No empty comments!
Do you want to search the username?
Do you want to search the hashtag?
Do you want to search the location?
diff --git a/build.gradle b/build.gradle
index 156a6372..1c9b89c0 100755
--- a/build.gradle
+++ b/build.gradle
@@ -6,6 +6,9 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
+ def nav_version = "2.3.0"
+ classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
+
}
}