diff --git a/.gitignore b/.gitignore index 013266e7..57870dac 100755 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ .externalNativeBuild .cxx app/release + +.idea/git_toolbox_prj.xml diff --git a/app/src/main/java/awais/instagrabber/activities/Main.java b/app/src/main/java/awais/instagrabber/activities/Main.java index 377568d7..283a3f1c 100755 --- a/app/src/main/java/awais/instagrabber/activities/Main.java +++ b/app/src/main/java/awais/instagrabber/activities/Main.java @@ -12,7 +12,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.PersistableBundle; import android.provider.BaseColumns; -import android.util.Log; +import android.text.TextUtils; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -28,11 +28,8 @@ import androidx.core.app.NotificationCompat; import androidx.fragment.app.FragmentManager; import androidx.recyclerview.widget.GridLayoutManager; -import org.json.JSONObject; - -import java.net.HttpURLConnection; -import java.net.URL; import java.util.ArrayList; +import java.util.List; import java.util.Stack; import awais.instagrabber.BuildConfig; @@ -40,6 +37,7 @@ import awais.instagrabber.MainHelper; import awais.instagrabber.R; import awais.instagrabber.adapters.HighlightsAdapter; import awais.instagrabber.adapters.SuggestionsAdapter; +import awais.instagrabber.asyncs.GetActivityAsyncTask; import awais.instagrabber.asyncs.SuggestionsFetcher; import awais.instagrabber.asyncs.UsernameFetcher; import awais.instagrabber.asyncs.i.iStoryStatusFetcher; @@ -118,6 +116,7 @@ public final class Main extends BaseLanguageActivity { private DialogInterface.OnClickListener profileDialogListener; private Stack queriesStack; private DataBox.CookieModel cookieModel; + private Runnable runnable; @Override protected void onCreate(@Nullable final Bundle bundle) { @@ -259,12 +258,54 @@ public final class Main extends BaseLanguageActivity { mainHelper.onIntent(getIntent()); final Handler handler = new Handler(); - handler.postDelayed(new Runnable() { - public void run() { - new GetActivity().execute(); - handler.postDelayed(this, 60000); - } - }, 200); + runnable = () -> { + final GetActivityAsyncTask activityAsyncTask = new GetActivityAsyncTask(uid, cookie, result -> { + if (result == null) { + if (!Utils.isEmpty(cookie)) { + Toast.makeText(Main.this, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); + } + return; + } + if (notificationManager == null) { + return; + } + final List list = new ArrayList<>(); + if (result.getRelationshipsCount() != 0) { + list.add(getString(R.string.activity_count_relationship, result.getRelationshipsCount())); + } + if (result.getUserTagsCount() != 0) { + list.add(getString(R.string.activity_count_usertags, result.getUserTagsCount())); + } + if (result.getCommentsCount() != 0) { + list.add(getString(R.string.activity_count_comments, result.getCommentsCount())); + } + if (result.getCommentLikesCount() != 0) { + list.add(getString(R.string.activity_count_commentlikes, result.getCommentLikesCount())); + } + if (result.getLikesCount() != 0) { + list.add(getString(R.string.activity_count_likes, result.getLikesCount())); + } + if (list.isEmpty()) { + return; + } + final String join = TextUtils.join(", ", list); + final String notificationString = getString(R.string.activity_count_prefix) + " " + join + "."; + final Intent intent = new Intent(getApplicationContext(), NotificationsViewer.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + final Notification notification = new NotificationCompat.Builder(Main.this, CHANNEL_ID) + .setCategory(NotificationCompat.CATEGORY_STATUS) + .setSmallIcon(R.drawable.ic_notif) + .setAutoCancel(true) + .setPriority(NotificationCompat.PRIORITY_MIN) + .setContentText(notificationString) + .setContentIntent(PendingIntent.getActivity(getApplicationContext(), 1738, intent, PendingIntent.FLAG_UPDATE_CURRENT)) + .build(); + notificationManager.cancel(1800000000); + notificationManager.notify(1800000000, notification); + }); + activityAsyncTask.execute(); + handler.postDelayed(runnable, 60000); + }; + handler.postDelayed(runnable, 200); } private void downloadSelectedItems() { @@ -555,57 +596,4 @@ public final class Main extends BaseLanguageActivity { } return false; } - - class GetActivity extends AsyncTask { - String ok = null; - - protected Void doInBackground(Void... lmao) { - final String url = "https://www.instagram.com/graphql/query/?query_hash=0f318e8cfff9cc9ef09f88479ff571fb" - + "&variables={\"id\":\""+uid+"\"}"; - if (!Utils.isEmpty(cookie)) try { - final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); - urlConnection.setUseCaches(false); - urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT); - urlConnection.setRequestProperty("x-csrftoken", cookie.split("csrftoken=")[1].split(";")[0]); - urlConnection.connect(); - if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { - final JSONObject data = new JSONObject(Utils.readFromConnection(urlConnection)).getJSONObject("data") - .getJSONObject("user").getJSONObject("edge_activity_count").getJSONArray("edges").getJSONObject(0) - .getJSONObject("node"); - ok = (getString(R.string.activity_count_prefix) + " " + String.join(", ", - data.getInt("relationships") == 0 ? null : getString(R.string.activity_count_relationship, data.getInt("relationships")), - data.getInt("usertags") == 0 ? null : getString(R.string.activity_count_usertags, data.getInt("usertags")), - data.getInt("comments") == 0 ? null : getString(R.string.activity_count_comments, data.getInt("comments")), - data.getInt("comment_likes") == 0 ? null : getString(R.string.activity_count_commentlikes, data.getInt("comment_likes")), - data.getInt("likes") == 0 ? null : getString(R.string.activity_count_likes, data.getInt("likes"))) + ".") - .replaceAll("null, ", "").replaceAll(",,+", ",").replaceAll("(,+|null).", "."); - } - urlConnection.disconnect(); - } catch (Throwable ex) { - Log.e("austin_debug", "getactivity: " + ex); - } - return null; - } - - @Override - protected void onPostExecute(Void result) { - if (ok == null) { - if (!Utils.isEmpty(cookie)) Toast.makeText(Main.this, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); - } - else if (!ok.equals(getString(R.string.activity_count_prefix) + " .")) { - final Notification notif = new NotificationCompat.Builder(Main.this, CHANNEL_ID) - .setCategory(NotificationCompat.CATEGORY_STATUS).setSmallIcon(R.drawable.ic_notif) - .setAutoCancel(true).setPriority(NotificationCompat.PRIORITY_MIN).setContentText(ok) - .setContentIntent( - PendingIntent.getActivity(getApplicationContext(), 1738, - new Intent(getApplicationContext(), NotificationsViewer.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - , PendingIntent.FLAG_UPDATE_CURRENT)) - .build(); - if (notificationManager != null) { - notificationManager.cancel(1800000000); - notificationManager.notify(1800000000, notif); - } - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/adapters/DirectMessageItemsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/DirectMessageItemsAdapter.java new file mode 100644 index 00000000..8070aaf9 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/DirectMessageItemsAdapter.java @@ -0,0 +1,150 @@ +package awais.instagrabber.adapters; + +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 java.util.List; + +import awais.instagrabber.adapters.viewholder.directmessages.DirectMessageActionLogViewHolder; +import awais.instagrabber.adapters.viewholder.directmessages.DirectMessageAnimatedMediaViewHolder; +import awais.instagrabber.adapters.viewholder.directmessages.DirectMessageDefaultViewHolder; +import awais.instagrabber.adapters.viewholder.directmessages.DirectMessageItemViewHolder; +import awais.instagrabber.adapters.viewholder.directmessages.DirectMessageLinkViewHolder; +import awais.instagrabber.adapters.viewholder.directmessages.DirectMessageMediaShareViewHolder; +import awais.instagrabber.adapters.viewholder.directmessages.DirectMessageMediaViewHolder; +import awais.instagrabber.adapters.viewholder.directmessages.DirectMessagePlaceholderViewHolder; +import awais.instagrabber.adapters.viewholder.directmessages.DirectMessageProfileViewHolder; +import awais.instagrabber.adapters.viewholder.directmessages.DirectMessageRavenMediaViewHolder; +import awais.instagrabber.adapters.viewholder.directmessages.DirectMessageReelShareViewHolder; +import awais.instagrabber.adapters.viewholder.directmessages.DirectMessageStoryShareViewHolder; +import awais.instagrabber.adapters.viewholder.directmessages.DirectMessageTextViewHolder; +import awais.instagrabber.adapters.viewholder.directmessages.DirectMessageVideoCallEventViewHolder; +import awais.instagrabber.adapters.viewholder.directmessages.DirectMessageVoiceMediaViewHolder; +import awais.instagrabber.databinding.LayoutDmAnimatedMediaBinding; +import awais.instagrabber.databinding.LayoutDmBaseBinding; +import awais.instagrabber.databinding.LayoutDmLinkBinding; +import awais.instagrabber.databinding.LayoutDmMediaBinding; +import awais.instagrabber.databinding.LayoutDmMediaShareBinding; +import awais.instagrabber.databinding.LayoutDmProfileBinding; +import awais.instagrabber.databinding.LayoutDmRavenMediaBinding; +import awais.instagrabber.databinding.LayoutDmStoryShareBinding; +import awais.instagrabber.databinding.LayoutDmTextBinding; +import awais.instagrabber.databinding.LayoutDmVoiceMediaBinding; +import awais.instagrabber.interfaces.MentionClickListener; +import awais.instagrabber.models.ProfileModel; +import awais.instagrabber.models.direct_messages.DirectItemModel; +import awais.instagrabber.models.enums.DirectItemType; + +public final class DirectMessageItemsAdapter extends ListAdapter { + private final List users; + private final List leftUsers; + private final View.OnClickListener onClickListener; + private final MentionClickListener mentionClickListener; + + 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()); + } + }; + + public DirectMessageItemsAdapter(final List users, + final List leftUsers, + final View.OnClickListener onClickListener, + final MentionClickListener mentionClickListener) { + super(diffCallback); + this.users = users; + this.leftUsers = leftUsers; + this.onClickListener = onClickListener; + this.mentionClickListener = mentionClickListener; + } + + @NonNull + @Override + public DirectMessageItemViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int type) { + final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); + final DirectItemType directItemType = DirectItemType.valueOf(type); + final LayoutDmBaseBinding baseBinding = LayoutDmBaseBinding.inflate(layoutInflater, parent, false); + final ViewGroup itemViewParent = baseBinding.messageCard; + switch (directItemType) { + case LIKE: + case TEXT: { + final LayoutDmTextBinding binding = LayoutDmTextBinding.inflate(layoutInflater, itemViewParent, false); + return new DirectMessageTextViewHolder(baseBinding, binding, onClickListener, mentionClickListener); + } + case PLACEHOLDER: { + final LayoutDmTextBinding binding = LayoutDmTextBinding.inflate(layoutInflater, itemViewParent, false); + return new DirectMessagePlaceholderViewHolder(baseBinding, binding, onClickListener); + } + case ACTION_LOG: { + final LayoutDmTextBinding binding = LayoutDmTextBinding.inflate(layoutInflater, itemViewParent, false); + return new DirectMessageActionLogViewHolder(baseBinding, binding, onClickListener); + } + case LINK: { + final LayoutDmLinkBinding binding = LayoutDmLinkBinding.inflate(layoutInflater, itemViewParent, false); + return new DirectMessageLinkViewHolder(baseBinding, binding, onClickListener); + } + case MEDIA: { + final LayoutDmMediaBinding binding = LayoutDmMediaBinding.inflate(layoutInflater, itemViewParent, false); + return new DirectMessageMediaViewHolder(baseBinding, binding, onClickListener); + } + case PROFILE: { + final LayoutDmProfileBinding binding = LayoutDmProfileBinding.inflate(layoutInflater, itemViewParent, false); + return new DirectMessageProfileViewHolder(baseBinding, binding, onClickListener); + } + case REEL_SHARE: { + final LayoutDmRavenMediaBinding binding = LayoutDmRavenMediaBinding.inflate(layoutInflater, itemViewParent, false); + return new DirectMessageReelShareViewHolder(baseBinding, binding, onClickListener, mentionClickListener); + } + case MEDIA_SHARE: { + final LayoutDmMediaShareBinding binding = LayoutDmMediaShareBinding.inflate(layoutInflater, itemViewParent, false); + return new DirectMessageMediaShareViewHolder(baseBinding, binding, onClickListener); + } + case RAVEN_MEDIA: { + final LayoutDmRavenMediaBinding binding = LayoutDmRavenMediaBinding.inflate(layoutInflater, itemViewParent, false); + return new DirectMessageRavenMediaViewHolder(baseBinding, binding, onClickListener); + } + case STORY_SHARE: { + final LayoutDmStoryShareBinding binding = LayoutDmStoryShareBinding.inflate(layoutInflater, itemViewParent, false); + return new DirectMessageStoryShareViewHolder(baseBinding, binding, onClickListener); + } + case VOICE_MEDIA: { + final LayoutDmVoiceMediaBinding binding = LayoutDmVoiceMediaBinding.inflate(layoutInflater, itemViewParent, false); + return new DirectMessageVoiceMediaViewHolder(baseBinding, binding, onClickListener); + } + case ANIMATED_MEDIA: { + final LayoutDmAnimatedMediaBinding binding = LayoutDmAnimatedMediaBinding.inflate(layoutInflater, itemViewParent, false); + return new DirectMessageAnimatedMediaViewHolder(baseBinding, binding, onClickListener); + } + case VIDEO_CALL_EVENT: { + final LayoutDmTextBinding binding = LayoutDmTextBinding.inflate(layoutInflater, itemViewParent, false); + return new DirectMessageVideoCallEventViewHolder(baseBinding, binding, onClickListener); + } + default: { + final LayoutDmTextBinding binding = LayoutDmTextBinding.inflate(layoutInflater, itemViewParent, false); + return new DirectMessageDefaultViewHolder(baseBinding, binding, onClickListener); + } + } + } + + @Override + public void onBindViewHolder(@NonNull final DirectMessageItemViewHolder holder, final int position) { + final DirectItemModel directItemModel = getItem(position); + holder.bind(directItemModel, users, leftUsers); + } + + @Override + public int getItemViewType(final int position) { + return getItem(position).getItemType().getId(); + } +} \ 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 deleted file mode 100755 index bd6d8e7d..00000000 --- a/app/src/main/java/awais/instagrabber/adapters/MessageItemsAdapter.java +++ /dev/null @@ -1,66 +0,0 @@ -package awais.instagrabber.adapters; - -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 java.util.List; - -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; - -public final class MessageItemsAdapter extends ListAdapter { - private final List users; - private final List leftUsers; - private final View.OnClickListener onClickListener; - private final MentionClickListener mentionClickListener; - - 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()); - } - }; - - public MessageItemsAdapter(final List users, - final List leftUsers, - final View.OnClickListener onClickListener, - final MentionClickListener mentionClickListener) { - super(diffCallback); - this.users = users; - this.leftUsers = leftUsers; - this.onClickListener = onClickListener; - this.mentionClickListener = mentionClickListener; - } - - @NonNull - @Override - 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, onClickListener, mentionClickListener); - } - - @Override - 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 getItem(position).getItemType().ordinal(); - } -} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageActionLogViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageActionLogViewHolder.java new file mode 100644 index 00000000..4c5bfc85 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageActionLogViewHolder.java @@ -0,0 +1,33 @@ +package awais.instagrabber.adapters.viewholder.directmessages; + +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.text.HtmlCompat; + +import awais.instagrabber.databinding.LayoutDmBaseBinding; +import awais.instagrabber.databinding.LayoutDmTextBinding; +import awais.instagrabber.models.ProfileModel; +import awais.instagrabber.models.direct_messages.DirectItemModel; + +import static androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT; + +public class DirectMessageActionLogViewHolder extends DirectMessageItemViewHolder { + + private final LayoutDmTextBinding binding; + + public DirectMessageActionLogViewHolder(@NonNull final LayoutDmBaseBinding baseBinding, + @NonNull final LayoutDmTextBinding binding, + final View.OnClickListener onClickListener) { + super(baseBinding, onClickListener); + this.binding = binding; + setItemView(binding.getRoot()); + } + + @Override + public void bindItem(final DirectItemModel directItemModel) { + final String text = directItemModel.getActionLogModel().getDescription(); + binding.tvMessage.setText(HtmlCompat.fromHtml("" + text + "", FROM_HTML_MODE_COMPACT)); + binding.tvMessage.setVisibility(View.VISIBLE); + } +} diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageAnimatedMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageAnimatedMediaViewHolder.java new file mode 100644 index 00000000..ed96398c --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageAnimatedMediaViewHolder.java @@ -0,0 +1,29 @@ +package awais.instagrabber.adapters.viewholder.directmessages; + +import android.view.View; + +import androidx.annotation.NonNull; + +import awais.instagrabber.databinding.LayoutDmAnimatedMediaBinding; +import awais.instagrabber.databinding.LayoutDmBaseBinding; +import awais.instagrabber.models.direct_messages.DirectItemModel; + +public class DirectMessageAnimatedMediaViewHolder extends DirectMessageItemViewHolder { + + private final LayoutDmAnimatedMediaBinding binding; + + public DirectMessageAnimatedMediaViewHolder(@NonNull final LayoutDmBaseBinding baseBinding, + @NonNull final LayoutDmAnimatedMediaBinding binding, + final View.OnClickListener onClickListener) { + super(baseBinding, onClickListener); + this.binding = binding; + setItemView(binding.getRoot()); + } + + @Override + public void bindItem(final DirectItemModel directItemModel) { + getGlideRequestManager().asGif().load(directItemModel.getAnimatedMediaModel().getGifUrl()) + .into(binding.ivAnimatedMessage); + binding.ivAnimatedMessage.setVisibility(View.VISIBLE); + } +} diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageDefaultViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageDefaultViewHolder.java new file mode 100644 index 00000000..5a8ff31a --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageDefaultViewHolder.java @@ -0,0 +1,30 @@ +package awais.instagrabber.adapters.viewholder.directmessages; + +import android.content.Context; +import android.view.View; + +import androidx.annotation.NonNull; + +import awais.instagrabber.R; +import awais.instagrabber.databinding.LayoutDmBaseBinding; +import awais.instagrabber.databinding.LayoutDmTextBinding; +import awais.instagrabber.models.direct_messages.DirectItemModel; + +public class DirectMessageDefaultViewHolder extends DirectMessageItemViewHolder { + + private final LayoutDmTextBinding binding; + + public DirectMessageDefaultViewHolder(@NonNull final LayoutDmBaseBinding baseBinding, + @NonNull final LayoutDmTextBinding binding, + final View.OnClickListener onClickListener) { + super(baseBinding, onClickListener); + this.binding = binding; + setItemView(binding.getRoot()); + } + + @Override + public void bindItem(final DirectItemModel directItemModel) { + final Context context = itemView.getContext(); + binding.tvMessage.setText(context.getText(R.string.dms_inbox_raven_message_unknown)); + } +} diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageItemViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageItemViewHolder.java new file mode 100644 index 00000000..4564144f --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageItemViewHolder.java @@ -0,0 +1,100 @@ +package awais.instagrabber.adapters.viewholder.directmessages; + +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +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.LayoutDmBaseBinding; +import awais.instagrabber.models.ProfileModel; +import awais.instagrabber.models.direct_messages.DirectItemModel; +import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.Utils; + +public abstract class DirectMessageItemViewHolder extends RecyclerView.ViewHolder { + 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 LayoutDmBaseBinding binding; + private final String strDmYou; + private final int itemMargin; + + private final RequestManager glideRequestManager; + + public DirectMessageItemViewHolder(@NonNull final LayoutDmBaseBinding binding, @NonNull final View.OnClickListener onClickListener) { + super(binding.getRoot()); + this.binding = binding; + binding.ivProfilePic.setOnClickListener(onClickListener); + binding.messageCard.setOnClickListener(onClickListener); + strDmYou = binding.getRoot().getContext().getString(R.string.direct_messages_you); + itemMargin = Utils.displayMetrics.widthPixels / 5; + glideRequestManager = Glide.with(itemView); + } + + public void bind(final DirectItemModel directItemModel, final List users, final List leftUsers) { + final ProfileModel user = getUser(directItemModel.getUserId(), users, leftUsers); + final int type = user == myProfileHolder ? MESSAGE_OUTGOING : MESSAGE_INCOMING; + + final RecyclerView.LayoutParams itemViewLayoutParams = (RecyclerView.LayoutParams) itemView.getLayoutParams(); + itemViewLayoutParams.setMargins(type == MESSAGE_OUTGOING ? itemMargin : 0, 0, + type == MESSAGE_INCOMING ? itemMargin : 0, 0); + + final ViewGroup messageCardParent = (ViewGroup) binding.messageCard.getParent(); + binding.contentContainer.setGravity(type == MESSAGE_INCOMING ? Gravity.START : Gravity.END); + + CharSequence text = "?"; + if (user != null && user != myProfileHolder) { + text = user.getUsername(); + } else if (user == myProfileHolder) text = ""; + text = (Utils.isEmpty(text) ? "" : text + " - ") + directItemModel.getDateTime(); + binding.tvUsername.setText(text); + binding.tvUsername.setGravity(type == MESSAGE_INCOMING ? Gravity.START : Gravity.END); + binding.ivProfilePic.setVisibility(type == MESSAGE_INCOMING ? View.VISIBLE : View.GONE); + binding.ivProfilePic.setTag(user); + binding.likedContainer.setVisibility(directItemModel.isLiked() ? View.VISIBLE : View.GONE); + messageCardParent.setTag(directItemModel); + binding.messageCard.setTag(directItemModel); + + if (type == MESSAGE_INCOMING && user != null) { + glideRequestManager.load(user.getSdProfilePic()).into(binding.ivProfilePic); + } + + bindItem(directItemModel); + } + + public void setItemView(final View view) { + this.binding.messageCard.addView(view); + } + + public RequestManager getGlideRequestManager() { + return glideRequestManager; + } + + public abstract void bindItem(final DirectItemModel directItemModel); + + @Nullable + private ProfileModel getUser(final long userId, final List users, final List leftUsers) { + 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; + } +} diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageLinkViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageLinkViewHolder.java new file mode 100644 index 00000000..2c277d75 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageLinkViewHolder.java @@ -0,0 +1,46 @@ +package awais.instagrabber.adapters.viewholder.directmessages; + +import android.view.View; + +import androidx.annotation.NonNull; + +import awais.instagrabber.databinding.LayoutDmBaseBinding; +import awais.instagrabber.databinding.LayoutDmLinkBinding; +import awais.instagrabber.models.direct_messages.DirectItemModel; +import awais.instagrabber.utils.Utils; + +public class DirectMessageLinkViewHolder extends DirectMessageItemViewHolder { + + private final LayoutDmLinkBinding binding; + + public DirectMessageLinkViewHolder(@NonNull final LayoutDmBaseBinding baseBinding, + @NonNull final LayoutDmLinkBinding binding, + final View.OnClickListener onClickListener) { + super(baseBinding, onClickListener); + this.binding = binding; + setItemView(binding.getRoot()); + } + + @Override + public void bindItem(final DirectItemModel directItemModel) { + final DirectItemModel.DirectItemLinkModel link = directItemModel.getLinkModel(); + final DirectItemModel.DirectItemLinkContext linkContext = link.getLinkContext(); + final String linkImageUrl = linkContext.getLinkImageUrl(); + if (Utils.isEmpty(linkImageUrl)) { + binding.ivLinkPreview.setVisibility(View.GONE); + } else { + getGlideRequestManager().load(linkImageUrl).into(binding.ivLinkPreview); + } + if (Utils.isEmpty(linkContext.getLinkTitle())) { + binding.tvLinkTitle.setVisibility(View.GONE); + } else { + binding.tvLinkTitle.setText(linkContext.getLinkTitle()); + } + if (Utils.isEmpty(linkContext.getLinkSummary())) { + binding.tvLinkSummary.setVisibility(View.GONE); + } else { + binding.tvLinkSummary.setText(linkContext.getLinkSummary()); + } + binding.tvMessage.setText(Utils.getSpannableUrl(link.getText())); + } +} diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageMediaShareViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageMediaShareViewHolder.java new file mode 100644 index 00000000..e8840096 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageMediaShareViewHolder.java @@ -0,0 +1,44 @@ +package awais.instagrabber.adapters.viewholder.directmessages; + +import android.content.Context; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.text.HtmlCompat; + +import awais.instagrabber.R; +import awais.instagrabber.databinding.LayoutDmBaseBinding; +import awais.instagrabber.databinding.LayoutDmMediaShareBinding; +import awais.instagrabber.models.ProfileModel; +import awais.instagrabber.models.direct_messages.DirectItemModel; +import awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemMediaModel; +import awais.instagrabber.models.enums.MediaItemType; + +import static androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT; + +public class DirectMessageMediaShareViewHolder extends DirectMessageItemViewHolder { + + private final LayoutDmMediaShareBinding binding; + + public DirectMessageMediaShareViewHolder(@NonNull final LayoutDmBaseBinding baseBinding, + @NonNull final LayoutDmMediaShareBinding binding, + final View.OnClickListener onClickListener) { + super(baseBinding, onClickListener); + this.binding = binding; + setItemView(binding.getRoot()); + } + + @Override + public void bindItem(final DirectItemModel directItemModel) { + final Context context = itemView.getContext(); + final DirectItemMediaModel mediaModel = directItemModel.getMediaModel(); + 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)); + } + getGlideRequestManager().load(mediaModel.getThumbUrl()).into(binding.ivMediaPreview); + final MediaItemType modelMediaType = mediaModel.getMediaType(); + binding.typeIcon.setVisibility(modelMediaType == MediaItemType.MEDIA_TYPE_VIDEO + || modelMediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE); + } +} diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageMediaViewHolder.java new file mode 100644 index 00000000..3bbe8a87 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageMediaViewHolder.java @@ -0,0 +1,32 @@ +package awais.instagrabber.adapters.viewholder.directmessages; + +import android.view.View; + +import androidx.annotation.NonNull; + +import awais.instagrabber.databinding.LayoutDmBaseBinding; +import awais.instagrabber.databinding.LayoutDmMediaBinding; +import awais.instagrabber.models.direct_messages.DirectItemModel; +import awais.instagrabber.models.enums.MediaItemType; + +public class DirectMessageMediaViewHolder extends DirectMessageItemViewHolder { + + private final LayoutDmMediaBinding binding; + + public DirectMessageMediaViewHolder(@NonNull final LayoutDmBaseBinding baseBinding, + @NonNull final LayoutDmMediaBinding binding, + final View.OnClickListener onClickListener) { + super(baseBinding, onClickListener); + this.binding = binding; + setItemView(binding.getRoot()); + } + + @Override + public void bindItem(final DirectItemModel directItemModel) { + final DirectItemModel.DirectItemMediaModel mediaModel = directItemModel.getMediaModel(); + getGlideRequestManager().load(mediaModel.getThumbUrl()).into(binding.ivMediaPreview); + final MediaItemType modelMediaType = mediaModel.getMediaType(); + binding.typeIcon.setVisibility(modelMediaType == MediaItemType.MEDIA_TYPE_VIDEO + || modelMediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE); + } +} diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessagePlaceholderViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessagePlaceholderViewHolder.java new file mode 100644 index 00000000..00691588 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessagePlaceholderViewHolder.java @@ -0,0 +1,31 @@ +package awais.instagrabber.adapters.viewholder.directmessages; + +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.text.HtmlCompat; + +import awais.instagrabber.databinding.LayoutDmBaseBinding; +import awais.instagrabber.databinding.LayoutDmTextBinding; +import awais.instagrabber.models.ProfileModel; +import awais.instagrabber.models.direct_messages.DirectItemModel; + +import static androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT; + +public class DirectMessagePlaceholderViewHolder extends DirectMessageItemViewHolder { + + private final LayoutDmTextBinding binding; + + public DirectMessagePlaceholderViewHolder(@NonNull final LayoutDmBaseBinding baseBinding, + @NonNull final LayoutDmTextBinding binding, + final View.OnClickListener onClickListener) { + super(baseBinding, onClickListener); + this.binding = binding; + setItemView(binding.getRoot()); + } + + @Override + public void bindItem(final DirectItemModel directItemModel) { + binding.tvMessage.setText(HtmlCompat.fromHtml(directItemModel.getText().toString(), FROM_HTML_MODE_COMPACT)); + } +} diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageProfileViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageProfileViewHolder.java new file mode 100644 index 00000000..1ebfae22 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageProfileViewHolder.java @@ -0,0 +1,38 @@ +package awais.instagrabber.adapters.viewholder.directmessages; + +import android.view.View; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.Glide; + +import awais.instagrabber.databinding.LayoutDmBaseBinding; +import awais.instagrabber.databinding.LayoutDmProfileBinding; +import awais.instagrabber.models.ProfileModel; +import awais.instagrabber.models.direct_messages.DirectItemModel; + +public class DirectMessageProfileViewHolder extends DirectMessageItemViewHolder { + + private final LayoutDmProfileBinding binding; + + public DirectMessageProfileViewHolder(@NonNull final LayoutDmBaseBinding baseBinding, + @NonNull final LayoutDmProfileBinding binding, + final View.OnClickListener onClickListener) { + super(baseBinding, onClickListener); + this.binding = binding; + binding.btnOpenProfile.setOnClickListener(onClickListener); + setItemView(binding.getRoot()); + } + + @Override + public void bindItem(final DirectItemModel directItemModel) { + final ProfileModel profileModel = directItemModel.getProfileModel(); + Glide.with(binding.profileInfo) + .load(profileModel.getSdProfilePic()) + .into(binding.profileInfo); + binding.btnOpenProfile.setTag(profileModel); + binding.tvFullName.setText(profileModel.getName()); + binding.profileInfoText.setText(profileModel.getUsername()); + binding.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE); + } +} diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageRavenMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageRavenMediaViewHolder.java new file mode 100644 index 00000000..473778ac --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageRavenMediaViewHolder.java @@ -0,0 +1,85 @@ +package awais.instagrabber.adapters.viewholder.directmessages; + +import android.content.Context; +import android.view.View; + +import androidx.annotation.NonNull; + +import awais.instagrabber.R; +import awais.instagrabber.databinding.LayoutDmBaseBinding; +import awais.instagrabber.databinding.LayoutDmRavenMediaBinding; +import awais.instagrabber.models.direct_messages.DirectItemModel; +import awais.instagrabber.models.enums.MediaItemType; +import awais.instagrabber.models.enums.RavenExpiringMediaType; +import awais.instagrabber.models.enums.RavenMediaViewType; +import awais.instagrabber.utils.Utils; + +public class DirectMessageRavenMediaViewHolder extends DirectMessageItemViewHolder { + + private final LayoutDmRavenMediaBinding binding; + + public DirectMessageRavenMediaViewHolder(@NonNull final LayoutDmBaseBinding baseBinding, + @NonNull final LayoutDmRavenMediaBinding binding, + final View.OnClickListener onClickListener) { + super(baseBinding, onClickListener); + this.binding = binding; + binding.tvMessage.setVisibility(View.GONE); + setItemView(binding.getRoot()); + } + + @Override + public void bindItem(final DirectItemModel directItemModel) { + final Context context = itemView.getContext(); + final DirectItemModel.DirectItemRavenMediaModel ravenMediaModel = directItemModel.getRavenMediaModel(); + DirectItemModel.DirectItemMediaModel mediaModel = directItemModel.getMediaModel(); + 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; + binding.typeIcon.setVisibility(mediaType == MediaItemType.MEDIA_TYPE_VIDEO || + mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE); + getGlideRequestManager().load(mediaModel.getThumbUrl()).into(binding.ivMediaPreview); + } + } + if (textRes != -1) { + binding.tvMessage.setText(context.getText(textRes)); + binding.tvMessage.setVisibility(View.VISIBLE); + } + } +} diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageReelShareViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageReelShareViewHolder.java new file mode 100644 index 00000000..31b50ea4 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageReelShareViewHolder.java @@ -0,0 +1,48 @@ +package awais.instagrabber.adapters.viewholder.directmessages; + +import android.view.View; + +import androidx.annotation.NonNull; + +import awais.instagrabber.databinding.LayoutDmBaseBinding; +import awais.instagrabber.databinding.LayoutDmRavenMediaBinding; +import awais.instagrabber.interfaces.MentionClickListener; +import awais.instagrabber.models.direct_messages.DirectItemModel; +import awais.instagrabber.models.enums.MediaItemType; +import awais.instagrabber.utils.Utils; + +public class DirectMessageReelShareViewHolder extends DirectMessageItemViewHolder { + + private final LayoutDmRavenMediaBinding binding; + + public DirectMessageReelShareViewHolder(@NonNull final LayoutDmBaseBinding baseBinding, + @NonNull final LayoutDmRavenMediaBinding binding, + final View.OnClickListener onClickListener, + final MentionClickListener mentionClickListener) { + super(baseBinding, onClickListener); + this.binding = binding; + binding.tvMessage.setMentionClickListener(mentionClickListener); + setItemView(binding.getRoot()); + } + + @Override + public void bindItem(final DirectItemModel directItemModel) { + final DirectItemModel.DirectItemReelShareModel reelShare = directItemModel.getReelShare(); + CharSequence text = reelShare.getText(); + if (Utils.isEmpty(text)) { + binding.tvMessage.setVisibility(View.GONE); + } else { + if (Utils.hasMentions(text)) text = Utils.getMentionText(text); // for mentions + binding.tvMessage.setText(text); + } + final DirectItemModel.DirectItemMediaModel reelShareMedia = reelShare.getMedia(); + final MediaItemType mediaType = reelShareMedia.getMediaType(); + if (mediaType == null) { + binding.mediaExpiredIcon.setVisibility(View.VISIBLE); + } else { + binding.typeIcon.setVisibility(mediaType == MediaItemType.MEDIA_TYPE_VIDEO || + mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE); + getGlideRequestManager().load(reelShareMedia.getThumbUrl()).into(binding.ivMediaPreview); + } + } +} diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageStoryShareViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageStoryShareViewHolder.java new file mode 100644 index 00000000..3ab53253 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageStoryShareViewHolder.java @@ -0,0 +1,48 @@ +package awais.instagrabber.adapters.viewholder.directmessages; + +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.text.HtmlCompat; + +import awais.instagrabber.databinding.LayoutDmBaseBinding; +import awais.instagrabber.databinding.LayoutDmStoryShareBinding; +import awais.instagrabber.models.direct_messages.DirectItemModel; +import awais.instagrabber.models.enums.MediaItemType; +import awais.instagrabber.utils.Utils; + +import static androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT; + +public class DirectMessageStoryShareViewHolder extends DirectMessageItemViewHolder { + + private final LayoutDmStoryShareBinding binding; + + public DirectMessageStoryShareViewHolder(@NonNull final LayoutDmBaseBinding baseBinding, + @NonNull final LayoutDmStoryShareBinding binding, + final View.OnClickListener onClickListener) { + super(baseBinding, onClickListener); + this.binding = binding; + binding.tvMessage.setVisibility(View.GONE); + setItemView(binding.getRoot()); + } + + @Override + public void bindItem(final DirectItemModel directItemModel) { + 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 { + final String text = reelShare.getText(); + if (!Utils.isEmpty(text)) { + binding.tvMessage.setText(text); + binding.tvMessage.setVisibility(View.VISIBLE); + } + final DirectItemModel.DirectItemMediaModel reelShareMedia = reelShare.getMedia(); + final MediaItemType mediaType = reelShareMedia.getMediaType(); + binding.typeIcon.setVisibility(mediaType == MediaItemType.MEDIA_TYPE_VIDEO || + mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE); + getGlideRequestManager().load(reelShareMedia.getThumbUrl()).into(binding.ivMediaPreview); + } + } +} diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageTextViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageTextViewHolder.java new file mode 100644 index 00000000..12fe1b38 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageTextViewHolder.java @@ -0,0 +1,43 @@ +package awais.instagrabber.adapters.viewholder.directmessages; + +import android.content.Context; +import android.text.Spanned; +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import awais.instagrabber.R; +import awais.instagrabber.databinding.LayoutDmBaseBinding; +import awais.instagrabber.databinding.LayoutDmTextBinding; +import awais.instagrabber.interfaces.MentionClickListener; +import awais.instagrabber.models.direct_messages.DirectItemModel; +import awais.instagrabber.utils.Utils; + +public class DirectMessageTextViewHolder extends DirectMessageItemViewHolder { + + private final LayoutDmTextBinding binding; + + public DirectMessageTextViewHolder(@NonNull final LayoutDmBaseBinding baseBinding, + @NonNull final LayoutDmTextBinding binding, + final View.OnClickListener onClickListener, + final MentionClickListener mentionClickListener) { + super(baseBinding, onClickListener); + this.binding = binding; + this.binding.tvMessage.setMentionClickListener(mentionClickListener); + setItemView(binding.getRoot()); + } + + @Override + public void bindItem(final DirectItemModel directItemModel) { + final Context context = itemView.getContext(); + CharSequence 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); + } +} diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageVideoCallEventViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageVideoCallEventViewHolder.java new file mode 100644 index 00000000..e8f9fa68 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageVideoCallEventViewHolder.java @@ -0,0 +1,29 @@ +package awais.instagrabber.adapters.viewholder.directmessages; + +import android.view.View; + +import androidx.annotation.NonNull; + +import awais.instagrabber.databinding.LayoutDmBaseBinding; +import awais.instagrabber.databinding.LayoutDmTextBinding; +import awais.instagrabber.models.direct_messages.DirectItemModel; + +public class DirectMessageVideoCallEventViewHolder extends DirectMessageItemViewHolder { + + private final LayoutDmTextBinding binding; + + public DirectMessageVideoCallEventViewHolder(@NonNull final LayoutDmBaseBinding baseBinding, + @NonNull final LayoutDmTextBinding binding, + final View.OnClickListener onClickListener) { + super(baseBinding, onClickListener); + this.binding = binding; + setItemView(binding.getRoot()); + } + + @Override + public void bindItem(final DirectItemModel directItemModel) { + // todo add call event info + binding.tvMessage.setVisibility(View.VISIBLE); + binding.tvMessage.setBackgroundColor(0xFF_1F90E6); + } +} 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 deleted file mode 100644 index ed79a61b..00000000 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageViewHolder.java +++ /dev/null @@ -1,390 +0,0 @@ -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.LinearLayout; -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.interfaces.MentionClickListener; -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 View.OnClickListener onClickListener; - private MentionClickListener mentionClickListener; - - 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; - } - }; - - public DirectMessageViewHolder(final ItemMessageItemBinding binding, - final List users, - final List leftUsers, - final View.OnClickListener onClickListener, - final MentionClickListener mentionClickListener) { - super(binding.getRoot()); - this.binding = binding; - this.users = users; - this.leftUsers = leftUsers; - this.itemMargin = Utils.displayMetrics.widthPixels / 5; - this.onClickListener = onClickListener; - this.mentionClickListener = mentionClickListener; - 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); - binding.ivProfilePic.setTag(user); - binding.ivProfilePic.setOnClickListener(onClickListener); - - binding.tvMessage.setMentionClickListener(mentionClickListener); - binding.messageCard.setTag(directItemModel); - LinearLayout parent = (LinearLayout) binding.messageCard.getParent(); - parent.setTag(directItemModel); - binding.messageCard.setOnClickListener(onClickListener); - binding.liked.setVisibility(directItemModel.isLiked() ? 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(onClickListener); - - 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/DirectMessageVoiceMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageVoiceMediaViewHolder.java new file mode 100644 index 00000000..f6790e54 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageVoiceMediaViewHolder.java @@ -0,0 +1,77 @@ +package awais.instagrabber.adapters.viewholder.directmessages; + +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import androidx.annotation.NonNull; + +import awais.instagrabber.databinding.LayoutDmBaseBinding; +import awais.instagrabber.databinding.LayoutDmVoiceMediaBinding; +import awais.instagrabber.models.direct_messages.DirectItemModel; +import awais.instagrabber.utils.Utils; + +public class DirectMessageVoiceMediaViewHolder extends DirectMessageItemViewHolder { + + private final LayoutDmVoiceMediaBinding binding; + + private DirectItemModel.DirectItemVoiceMediaModel prevVoiceModel; + private ImageView prevPlayIcon; + + public DirectMessageVoiceMediaViewHolder(@NonNull final LayoutDmBaseBinding baseBinding, + @NonNull final LayoutDmVoiceMediaBinding binding, + final View.OnClickListener onClickListener) { + super(baseBinding, onClickListener); + this.binding = binding; + + // todo pause / resume + // todo release prev audio, start new voice + binding.btnPlayVoice.setOnClickListener(v -> { + final Object tag = v.getTag(); + 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; + }); + setItemView(binding.getRoot()); + } + + @Override + public void bindItem(final DirectItemModel directItemModel) { + 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); + } else { + binding.waveformSeekBar.setProgress(0); + } + } +} diff --git a/app/src/main/java/awais/instagrabber/asyncs/GetActivityAsyncTask.java b/app/src/main/java/awais/instagrabber/asyncs/GetActivityAsyncTask.java new file mode 100644 index 00000000..860015fd --- /dev/null +++ b/app/src/main/java/awais/instagrabber/asyncs/GetActivityAsyncTask.java @@ -0,0 +1,113 @@ +package awais.instagrabber.asyncs; + +import android.os.AsyncTask; +import android.util.Log; + +import org.json.JSONObject; + +import java.net.HttpURLConnection; +import java.net.URL; + +import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.Utils; + +public class GetActivityAsyncTask extends AsyncTask { + private static final String TAG = "GetActivityAsyncTask"; + private String uid; + private String cookie; + private OnTaskCompleteListener onTaskCompleteListener; + + public GetActivityAsyncTask(final String uid, final String cookie, final OnTaskCompleteListener onTaskCompleteListener) { + this.uid = uid; + this.cookie = cookie; + this.onTaskCompleteListener = onTaskCompleteListener; + } + + protected NotificationCounts doInBackground(Void... voids) { + if (Utils.isEmpty(cookie)) { + return null; + } + final String url = "https://www.instagram.com/graphql/query/?query_hash=0f318e8cfff9cc9ef09f88479ff571fb" + + "&variables={\"id\":\"" + uid + "\"}"; + HttpURLConnection urlConnection = null; + try { + urlConnection = (HttpURLConnection) new URL(url).openConnection(); + urlConnection.setUseCaches(false); + urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT); + urlConnection.setRequestProperty("x-csrftoken", cookie.split("csrftoken=")[1].split(";")[0]); + urlConnection.connect(); + if (urlConnection.getResponseCode() != HttpURLConnection.HTTP_OK) { + return null; + } + final JSONObject data = new JSONObject(Utils.readFromConnection(urlConnection)).getJSONObject("data") + .getJSONObject("user").getJSONObject("edge_activity_count").getJSONArray("edges").getJSONObject(0) + .getJSONObject("node"); + return new NotificationCounts( + data.getInt("relationships"), + data.getInt("usertags"), + data.getInt("comments"), + data.getInt("comment_likes"), + data.getInt("likes") + ); + } catch (Throwable ex) { + Log.e(TAG, "Error", ex); + } finally { + if (urlConnection != null) { + urlConnection.disconnect(); + } + } + return null; + } + + @Override + protected void onPostExecute(final NotificationCounts result) { + if (onTaskCompleteListener == null) { + return; + } + onTaskCompleteListener.onTaskComplete(result); + } + + public static class NotificationCounts { + private int relationshipsCount; + private int userTagsCount; + private int commentsCount; + private int commentLikesCount; + private int likesCount; + + public NotificationCounts(final int relationshipsCount, + final int userTagsCount, + final int commentsCount, + final int commentLikesCount, + final int likesCount) { + this.relationshipsCount = relationshipsCount; + this.userTagsCount = userTagsCount; + this.commentsCount = commentsCount; + this.commentLikesCount = commentLikesCount; + this.likesCount = likesCount; + } + + public int getRelationshipsCount() { + return relationshipsCount; + } + + public int getUserTagsCount() { + return userTagsCount; + } + + public int getCommentsCount() { + return commentsCount; + } + + public int getCommentLikesCount() { + return commentLikesCount; + } + + public int getLikesCount() { + return likesCount; + } + } + + public interface OnTaskCompleteListener { + void onTaskComplete(final NotificationCounts result); + } +} diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java index 26138521..936ca7f2 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java @@ -50,7 +50,7 @@ import awais.instagrabber.R; import awais.instagrabber.activities.PostViewer; import awais.instagrabber.activities.ProfileViewer; import awais.instagrabber.activities.StoryViewer; -import awais.instagrabber.adapters.MessageItemsAdapter; +import awais.instagrabber.adapters.DirectMessageItemsAdapter; import awais.instagrabber.asyncs.ImageUploader; import awais.instagrabber.asyncs.direct_messages.DirectMessageInboxThreadFetcher; import awais.instagrabber.asyncs.direct_messages.DirectThreadBroadcaster; @@ -191,8 +191,8 @@ public class DirectMessageThreadFragment extends Fragment { new DirectMessageInboxThreadFetcher(threadId, UserInboxDirection.OLDER, cursor, fetchListener).execute(); // serial because we don't want messages to be randomly ordered })); - final DialogInterface.OnClickListener onDialogListener = (d,w) -> { - if (w == 0) { + final DialogInterface.OnClickListener onDialogListener = (dialogInterface, which) -> { + if (which == 0) { final DirectItemType itemType = directItemModel.getItemType(); switch (itemType) { case MEDIA_SHARE: @@ -244,10 +244,10 @@ public class DirectMessageThreadFragment extends Fragment { Log.d("austin_debug", "unsupported type " + itemType); } } - else if (w == 1) { + else if (which == 1) { sendText(null, directItemModel.getItemId(), directItemModel.isLiked()); } - else if (w == 2) { + else if (which == 2) { if (String.valueOf(directItemModel.getUserId()).equals(myId)) new Unsend().execute(); else searchUsername(getUser(directItemModel.getUserId()).getUsername()); } @@ -256,8 +256,7 @@ public class DirectMessageThreadFragment extends Fragment { Object tag = v.getTag(); if (tag instanceof ProfileModel) { searchUsername(((ProfileModel) tag).getUsername()); - } - else if (tag instanceof DirectItemModel) { + } else if (tag instanceof DirectItemModel) { directItemModel = (DirectItemModel) tag; final DirectItemType itemType = directItemModel.getItemType(); int firstOption = R.string.dms_inbox_raven_message_unknown; @@ -302,12 +301,12 @@ public class DirectMessageThreadFragment extends Fragment { new AlertDialog.Builder(requireContext()) //.setTitle(title) .setAdapter(dialogAdapter, onDialogListener) - .setNeutralButton(R.string.cancel, null) + // .setNeutralButton(R.string.cancel, null) .show(); } }; final MentionClickListener mentionClickListener = (view, text, isHashtag) -> searchUsername(text); - final MessageItemsAdapter adapter = new MessageItemsAdapter(users, leftUsers, onClickListener, mentionClickListener); + final DirectMessageItemsAdapter adapter = new DirectMessageItemsAdapter(users, leftUsers, onClickListener, mentionClickListener); messageList.setAdapter(adapter); listViewModel = new ViewModelProvider(fragmentActivity).get(DirectItemModelListViewModel.class); listViewModel.getList().observe(fragmentActivity, adapter::submitList); @@ -344,8 +343,7 @@ public class DirectMessageThreadFragment extends Fragment { Log.e(TAG, "Error", e); return; } - } - else { + } else { reactionOptions = new DirectThreadBroadcaster.ReactionBroadcastOptions(itemId, delete); } broadcast(text != null ? textOptions : reactionOptions, result -> { @@ -355,10 +353,11 @@ public class DirectMessageThreadFragment extends Fragment { } if (text != null) { binding.commentText.setText(""); - } - else { - LinearLayout dim = (LinearLayout) binding.messageList.findViewWithTag(directItemModel); - if (dim.findViewById(R.id.liked) != null) dim.findViewById(R.id.liked).setVisibility(delete ? View.GONE : View.VISIBLE); + } else { + final LinearLayout dim = (LinearLayout) binding.messageList.findViewWithTag(directItemModel).getParent(); + if (dim.findViewById(R.id.liked_container) != null) { + dim.findViewById(R.id.liked_container).setVisibility(delete ? View.GONE : View.VISIBLE); + } directItemModel.setLiked(); } hasSentSomething = true; @@ -386,15 +385,14 @@ public class DirectMessageThreadFragment extends Fragment { // Broadcast 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)); + broadcast(options, broadcastResponse -> new DirectMessageInboxThreadFetcher(threadId, UserInboxDirection.OLDER, null, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)); } catch (JSONException e) { Log.e(TAG, "Error parsing json response", e); } }); final ImageUploadOptions options = ImageUploadOptions.builder(bitmap).build(); imageUploader.execute(options); - } - catch (IOException e) { + } catch (IOException e) { Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); Log.e(TAG, "Error opening file", e); } diff --git a/app/src/main/java/awais/instagrabber/models/direct_messages/DirectItemModel.java b/app/src/main/java/awais/instagrabber/models/direct_messages/DirectItemModel.java index 98a01ab2..d5a79c07 100755 --- a/app/src/main/java/awais/instagrabber/models/direct_messages/DirectItemModel.java +++ b/app/src/main/java/awais/instagrabber/models/direct_messages/DirectItemModel.java @@ -31,8 +31,7 @@ public final class DirectItemModel implements Serializable, Comparable map = new HashMap<>(); + + static { + for (DirectItemType type : DirectItemType.values()) { + map.put(type.id, type); + } + } + + DirectItemType(final int id) { + this.id = id; + } + + public int getId() { + return id; + } + + public static DirectItemType valueOf(final int id) { + return map.get(id); + } } \ 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 deleted file mode 100755 index 18206795..00000000 --- a/app/src/main/res/layout/item_message_item.xml +++ /dev/null @@ -1,263 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/layout_dm_animated_media.xml b/app/src/main/res/layout/layout_dm_animated_media.xml new file mode 100644 index 00000000..bdf2673a --- /dev/null +++ b/app/src/main/res/layout/layout_dm_animated_media.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_dm_base.xml b/app/src/main/res/layout/layout_dm_base.xml new file mode 100644 index 00000000..c1048b28 --- /dev/null +++ b/app/src/main/res/layout/layout_dm_base.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_dm_link.xml b/app/src/main/res/layout/layout_dm_link.xml new file mode 100644 index 00000000..f7b63efe --- /dev/null +++ b/app/src/main/res/layout/layout_dm_link.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_dm_media.xml b/app/src/main/res/layout/layout_dm_media.xml new file mode 100644 index 00000000..b8ac3745 --- /dev/null +++ b/app/src/main/res/layout/layout_dm_media.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_dm_media_share.xml b/app/src/main/res/layout/layout_dm_media_share.xml new file mode 100644 index 00000000..8dc9a8d6 --- /dev/null +++ b/app/src/main/res/layout/layout_dm_media_share.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_dm_profile.xml b/app/src/main/res/layout/layout_dm_profile.xml new file mode 100644 index 00000000..f00fc59b --- /dev/null +++ b/app/src/main/res/layout/layout_dm_profile.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_dm_raven_media.xml b/app/src/main/res/layout/layout_dm_raven_media.xml new file mode 100644 index 00000000..4c836dd3 --- /dev/null +++ b/app/src/main/res/layout/layout_dm_raven_media.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_dm_story_share.xml b/app/src/main/res/layout/layout_dm_story_share.xml new file mode 100644 index 00000000..44773a58 --- /dev/null +++ b/app/src/main/res/layout/layout_dm_story_share.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_dm_text.xml b/app/src/main/res/layout/layout_dm_text.xml new file mode 100644 index 00000000..221e28ed --- /dev/null +++ b/app/src/main/res/layout/layout_dm_text.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_dm_voice_media.xml b/app/src/main/res/layout/layout_dm_voice_media.xml new file mode 100644 index 00000000..a8fc9ee2 --- /dev/null +++ b/app/src/main/res/layout/layout_dm_voice_media.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 17af16c1..be3e011d 100755 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -7,6 +7,7 @@ 48dp 80dp 70dp + 120dp 80dp 45dp @@ -16,4 +17,6 @@ @dimen/simple_item_picture_size @dimen/feed_profile_size + 500dp + 8dp \ No newline at end of file