diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 01838249..566e46ed 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -141,14 +141,14 @@
-
+
+
+
-
-
+
+
+
+
diff --git a/app/src/main/java/awais/instagrabber/MainHelper.java b/app/src/main/java/awais/instagrabber/MainHelper.java
index 607ad088..79cafea6 100755
--- a/app/src/main/java/awais/instagrabber/MainHelper.java
+++ b/app/src/main/java/awais/instagrabber/MainHelper.java
@@ -49,7 +49,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-import awais.instagrabber.activities.CommentsViewer;
+import awais.instagrabber.activities.CommentsViewerFragment;
import awais.instagrabber.activities.FollowViewer;
import awais.instagrabber.activities.MainActivityBackup;
import awais.instagrabber.activities.PostViewer;
@@ -604,7 +604,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
final int id = v.getId();
switch (id) {
case R.id.btnComments:
- mainActivity.startActivityForResult(new Intent(mainActivity, CommentsViewer.class)
+ mainActivity.startActivityForResult(new Intent(mainActivity, CommentsViewerFragment.class)
.putExtra(Constants.EXTRAS_SHORTCODE, feedModel.getShortCode())
.putExtra(Constants.EXTRAS_POST, feedModel.getPostId())
.putExtra(Constants.EXTRAS_USER, feedModel.getProfileModel().getId()), 6969);
diff --git a/app/src/main/java/awais/instagrabber/activities/CommentsViewer.java b/app/src/main/java/awais/instagrabber/activities/CommentsViewer.java
deleted file mode 100755
index cf418180..00000000
--- a/app/src/main/java/awais/instagrabber/activities/CommentsViewer.java
+++ /dev/null
@@ -1,302 +0,0 @@
-package awais.instagrabber.activities;
-
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.style.RelativeSizeSpan;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.ArrayAdapter;
-import android.widget.Toast;
-
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.widget.SearchView;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-
-import java.io.DataOutputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLEncoder;
-
-import awais.instagrabber.R;
-import awais.instagrabber.adapters.CommentsAdapter;
-import awais.instagrabber.asyncs.CommentsFetcher;
-import awais.instagrabber.databinding.ActivityCommentsBinding;
-import awais.instagrabber.interfaces.FetchListener;
-import awais.instagrabber.interfaces.MentionClickListener;
-import awais.instagrabber.models.CommentModel;
-import awais.instagrabber.models.ProfileModel;
-import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
-
-public final class CommentsViewer extends BaseLanguageActivity implements SwipeRefreshLayout.OnRefreshListener {
- private CommentsAdapter commentsAdapter;
- private CommentModel commentModel;
- private ActivityCommentsBinding commentsBinding;
- private ArrayAdapter commmentDialogAdapter;
- private String shortCode, postId, userId;
- private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
- private Resources resources;
- private InputMethodManager imm;
- private View focus;
-
- @Override
- protected void onCreate(@Nullable final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- commentsBinding = ActivityCommentsBinding.inflate(getLayoutInflater());
- setContentView(commentsBinding.getRoot());
- commentsBinding.swipeRefreshLayout.setOnRefreshListener(this);
-
- final Intent intent = getIntent();
- if (intent == null || !intent.hasExtra(Constants.EXTRAS_SHORTCODE)
- || Utils.isEmpty((shortCode = intent.getStringExtra(Constants.EXTRAS_SHORTCODE)))
- || !intent.hasExtra(Constants.EXTRAS_POST)
- || Utils.isEmpty((postId = intent.getStringExtra(Constants.EXTRAS_POST)))
- || !intent.hasExtra(Constants.EXTRAS_USER)
- || Utils.isEmpty((userId = intent.getStringExtra(Constants.EXTRAS_USER)))) {
- Utils.errorFinish(this);
- return;
- }
-
- commentsBinding.swipeRefreshLayout.setRefreshing(true);
- setSupportActionBar(commentsBinding.toolbar.toolbar);
- commentsBinding.toolbar.toolbar.setTitle(R.string.title_comments);
- commentsBinding.toolbar.toolbar.setSubtitle(shortCode);
-
- resources = getResources();
-
- if (!Utils.isEmpty(cookie)) {
- commentsBinding.commentText.setVisibility(View.VISIBLE);
- commentsBinding.commentSend.setVisibility(View.VISIBLE);
-
- commentsBinding.commentSend.setOnClickListener(newCommentListener);
- commentsBinding.commentCancelParent.setOnClickListener(newCommentListener);
- }
-
- new CommentsFetcher(shortCode, new FetchListener() {
- @Override
- public void onResult(final CommentModel[] commentModels) {
- commentsAdapter = new CommentsAdapter(commentModels, true, clickListener, mentionClickListener);
-
- commentsBinding.rvComments.setAdapter(commentsAdapter);
- commentsBinding.swipeRefreshLayout.setRefreshing(false);
- }
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- @Override
- public void onRefresh() {
- commentsBinding.swipeRefreshLayout.setRefreshing(true);
- new CommentsFetcher(shortCode, new FetchListener() {
- @Override
- public void onResult(final CommentModel[] commentModels) {
- commentsBinding.swipeRefreshLayout.setRefreshing(false);
-
- commentsAdapter = new CommentsAdapter(commentModels, true, clickListener, mentionClickListener);
-
- commentsBinding.rvComments.setAdapter(commentsAdapter);
- }
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> {
- final ProfileModel profileModel = commentModel.getProfileModel();
-
- if (which == 0) {
- searchUsername(profileModel.getUsername());
- } else if (which == 1) {
- startActivity(new Intent(this, ProfilePicViewer.class).putExtra(Constants.EXTRAS_PROFILE, profileModel));
- } else if (which == 2) {
- Utils.copyText(this, profileModel.getUsername());
- } else if (which == 3) {
- Utils.copyText(this, commentModel.getText().toString());
- } else if (which == 4) {
- if (commentModel == null) {
- Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }
- else {
- focus = commentsBinding.rvComments.findViewWithTag(commentModel);
- focus.setBackgroundColor(0x80888888);
- commentsBinding.commentCancelParent.setVisibility(View.VISIBLE);
- String mention = "@" + profileModel.getUsername() + " ";
- commentsBinding.commentText.setText(mention);
- commentsBinding.commentText.requestFocus();
- commentsBinding.commentText.setSelection(mention.length());
- commentsBinding.commentText.postDelayed(new Runnable() {
- @Override
- public void run() {
- imm = (InputMethodManager) getSystemService(getApplicationContext().INPUT_METHOD_SERVICE);
- imm.showSoftInput(commentsBinding.commentText, 0);
- }
- }, 200);
- }
- } else if (which == 5) {
- new CommentAction().execute((commentModel.getLiked() ? "unlike/" : "like/")+commentModel.getId());
- } else if (which == 6) {
- new CommentAction().execute("delete/"+commentModel.getId());
- }
- };
-
- private final View.OnClickListener clickListener = v -> {
- final Object tag = v.getTag();
- if (tag instanceof CommentModel) {
- commentModel = (CommentModel) tag;
-
- final String username = commentModel.getProfileModel().getUsername();
- final SpannableString title = new SpannableString(username + ":\n" + commentModel.getText());
- title.setSpan(new RelativeSizeSpan(1.23f), 0, username.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
-
- String[] commentDialogList;
-
- if (!Utils.isEmpty(cookie) &&
- (Utils.getUserIdFromCookie(cookie).equals(commentModel.getProfileModel().getId()) ||
- Utils.getUserIdFromCookie(cookie).equals(userId))) commentDialogList = new String[]{
- resources.getString(R.string.open_profile),
- resources.getString(R.string.view_pfp),
- resources.getString(R.string.comment_viewer_copy_user),
- resources.getString(R.string.comment_viewer_copy_comment),
- resources.getString(R.string.comment_viewer_reply_comment),
- commentModel.getLiked() ? resources.getString(R.string.comment_viewer_unlike_comment) : resources.getString(R.string.comment_viewer_like_comment),
- resources.getString(R.string.comment_viewer_delete_comment)
- };
- else if (!Utils.isEmpty(cookie)) commentDialogList = new String[]{
- resources.getString(R.string.open_profile),
- resources.getString(R.string.view_pfp),
- resources.getString(R.string.comment_viewer_copy_user),
- resources.getString(R.string.comment_viewer_copy_comment),
- resources.getString(R.string.comment_viewer_reply_comment),
- commentModel.getLiked() ? resources.getString(R.string.comment_viewer_unlike_comment) : resources.getString(R.string.comment_viewer_like_comment),
- };
- else commentDialogList = new String[]{
- resources.getString(R.string.open_profile),
- resources.getString(R.string.view_pfp),
- resources.getString(R.string.comment_viewer_copy_user),
- resources.getString(R.string.comment_viewer_copy_comment)
- };
-
- commmentDialogAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, commentDialogList);
-
- new AlertDialog.Builder(this).setTitle(title)
- .setAdapter(commmentDialogAdapter, profileDialogListener)
- .setNeutralButton(R.string.cancel, null)
- .show();
- }
- };
-
- private final MentionClickListener mentionClickListener = (view, text, isHashtag, isLocation) ->
- new AlertDialog.Builder(this).setTitle(text)
- .setMessage(isHashtag ? R.string.comment_view_mention_hash_search : R.string.comment_view_mention_user_search)
- .setNegativeButton(R.string.cancel, null).setPositiveButton(R.string.ok,
- (dialog, which) -> searchUsername(text)).show();
-
- private final View.OnClickListener newCommentListener = v -> {
- if (Utils.isEmpty(commentsBinding.commentText.getText().toString()) && v == commentsBinding.commentSend)
- Toast.makeText(getApplicationContext(), R.string.comment_send_empty_comment, Toast.LENGTH_SHORT).show();
- else if (v == commentsBinding.commentSend) new CommentAction().execute("add");
- else if (v == commentsBinding.commentCancelParent) {
- focus.setBackgroundColor(commentModel.getLiked() ? 0x40FF69B4 : 0x00000000);
- commentsBinding.commentCancelParent.setVisibility(View.GONE);
- commentsBinding.commentText.setText("");
- commentModel = null;
- focus = null;
- }
- };
-
- private void searchUsername(final String text) {
- startActivity(
- new Intent(getApplicationContext(), ProfileViewer.class)
- .putExtra(Constants.EXTRAS_USERNAME, text)
- );
- }
-
- @Override
- public boolean onCreateOptionsMenu(final Menu menu) {
- getMenuInflater().inflate(R.menu.follow, menu);
-
- final MenuItem menuSearch = menu.findItem(R.id.action_search);
- final SearchView searchView = (SearchView) menuSearch.getActionView();
- searchView.setQueryHint(getResources().getString(R.string.action_search));
- searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(final String query) {
- return false;
- }
-
- @Override
- public boolean onQueryTextChange(final String query) {
- if (commentsAdapter != null) commentsAdapter.getFilter().filter(query);
- return true;
- }
- });
-
- menu.findItem(R.id.action_compare).setVisible(false);
-
- return true;
- }
-
- class CommentAction extends AsyncTask {
- boolean ok = false;
-
- protected Void doInBackground(String... rawAction) {
- final String action = rawAction[0];
- final String url = "https://www.instagram.com/web/comments/"+postId+"/"+action+"/";
- try {
- final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setUseCaches(false);
- urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT);
- urlConnection.setRequestProperty("x-csrftoken", cookie.split("csrftoken=")[1].split(";")[0]);
- if (action == "add") {
- // https://stackoverflow.com/questions/14321873/java-url-encoding-urlencoder-vs-uri
- final String commentText = URLEncoder.encode(commentsBinding.commentText.getText().toString(), "UTF-8")
- .replaceAll("\\+", "%20").replaceAll("\\%21", "!").replaceAll("\\%27", "'")
- .replaceAll("\\%28", "(").replaceAll("\\%29", ")").replaceAll("\\%7E", "~");
- final String urlParameters = "comment_text="+commentText+"&replied_to_comment_id="+
- (commentModel == null ? "" : commentModel.getId());
- urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- urlConnection.setRequestProperty("Content-Length", "" +
- urlParameters.getBytes().length);
- urlConnection.setDoOutput(true);
- DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
- wr.writeBytes(urlParameters);
- wr.flush();
- wr.close();
- }
- urlConnection.connect();
- if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
- ok = true;
- if (action == "add") {
- commentsBinding.commentText.setText("");
- commentsBinding.commentText.clearFocus();
- }
- }
- urlConnection.disconnect();
- } catch (Throwable ex) {
- Log.e("austin_debug", action+": " + ex);
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- if (ok == true) {
- if (focus != null) {
- focus.setBackgroundColor(commentModel.getLiked() ? 0x40FF69B4 : 0x00000000);
- commentsBinding.commentCancelParent.setVisibility(View.GONE);
- commentModel = null;
- focus = null;
- }
- onRefresh();
- }
- else Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/activities/CommentsViewerFragment.java b/app/src/main/java/awais/instagrabber/activities/CommentsViewerFragment.java
new file mode 100644
index 00000000..73888826
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/activities/CommentsViewerFragment.java
@@ -0,0 +1,370 @@
+package awais.instagrabber.activities;
+
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.TextWatcher;
+import android.text.style.RelativeSizeSpan;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.LinearLayout;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.SearchView;
+import androidx.fragment.app.Fragment;
+import androidx.navigation.NavDirections;
+import androidx.navigation.fragment.NavHostFragment;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+
+import awais.instagrabber.R;
+import awais.instagrabber.adapters.CommentsAdapter;
+import awais.instagrabber.asyncs.CommentsFetcher;
+import awais.instagrabber.databinding.FragmentCommentsBinding;
+import awais.instagrabber.interfaces.MentionClickListener;
+import awais.instagrabber.models.CommentModel;
+import awais.instagrabber.models.ProfileModel;
+import awais.instagrabber.services.MediaService;
+import awais.instagrabber.services.ServiceCallback;
+import awais.instagrabber.utils.Constants;
+import awais.instagrabber.utils.Utils;
+
+import static android.content.Context.INPUT_METHOD_SERVICE;
+
+public final class CommentsViewerFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
+ private static final String TAG = "CommentsViewerFragment";
+
+ private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
+
+ private CommentsAdapter commentsAdapter;
+ private CommentModel commentModel;
+ private FragmentCommentsBinding binding;
+ private String shortCode;
+ private String userId;
+ private Resources resources;
+ private InputMethodManager imm;
+ private AppCompatActivity fragmentActivity;
+ private LinearLayout root;
+ private boolean shouldRefresh = true;
+ private MediaService mediaService;
+ private String postId;
+
+ @Override
+ public void onCreate(@Nullable final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ fragmentActivity = (AppCompatActivity) getActivity();
+ mediaService = MediaService.getInstance();
+ setHasOptionsMenu(true);
+ }
+
+ @NonNull
+ @Override
+ public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
+ if (root != null) {
+ shouldRefresh = false;
+ return root;
+ }
+ binding = FragmentCommentsBinding.inflate(getLayoutInflater());
+ root = binding.getRoot();
+ return root;
+ }
+
+ @Override
+ public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
+ if (!shouldRefresh) return;
+ init();
+ shouldRefresh = false;
+ }
+
+ @Override
+ public void onCreateOptionsMenu(@NonNull final Menu menu, @NonNull final MenuInflater inflater) {
+ inflater.inflate(R.menu.follow, menu);
+ final MenuItem favItem = menu.findItem(R.id.favourites);
+ if (favItem != null) favItem.setVisible(false);
+ menu.findItem(R.id.action_compare).setVisible(false);
+ final MenuItem menuSearch = menu.findItem(R.id.action_search);
+ final SearchView searchView = (SearchView) menuSearch.getActionView();
+ searchView.setQueryHint(getResources().getString(R.string.action_search));
+ searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
+ @Override
+ public boolean onQueryTextSubmit(final String query) {
+ return false;
+ }
+
+ @Override
+ public boolean onQueryTextChange(final String query) {
+ if (commentsAdapter != null) commentsAdapter.getFilter().filter(query);
+ return true;
+ }
+ });
+ }
+
+ @Override
+ public void onRefresh() {
+ binding.swipeRefreshLayout.setRefreshing(true);
+ new CommentsFetcher(shortCode, commentModels -> {
+ binding.swipeRefreshLayout.setRefreshing(false);
+ commentsAdapter = new CommentsAdapter(commentModels, true, clickListener, mentionClickListener);
+ binding.rvComments.setAdapter(commentsAdapter);
+ }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
+ private void init() {
+ if (getArguments() == null) return;
+ final CommentsViewerFragmentArgs fragmentArgs = CommentsViewerFragmentArgs.fromBundle(getArguments());
+ shortCode = fragmentArgs.getShortCode();
+ postId = fragmentArgs.getPostId();
+ userId = fragmentArgs.getPostUserId();
+ setTitle();
+ binding.swipeRefreshLayout.setOnRefreshListener(this);
+ binding.swipeRefreshLayout.setRefreshing(true);
+ resources = getResources();
+ if (!Utils.isEmpty(cookie)) {
+ binding.commentField.setStartIconVisible(false);
+ binding.commentField.setEndIconVisible(false);
+ binding.commentField.setVisibility(View.VISIBLE);
+ binding.commentText.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {}
+
+ @Override
+ public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
+ binding.commentField.setStartIconVisible(s.length() > 0);
+ binding.commentField.setEndIconVisible(s.length() > 0);
+ }
+
+ @Override
+ public void afterTextChanged(final Editable s) {}
+ });
+ binding.commentField.setStartIconOnClickListener(v -> {
+ commentModel = null;
+ binding.commentText.setText("");
+ });
+ binding.commentField.setEndIconOnClickListener(newCommentListener);
+ }
+ new CommentsFetcher(this.shortCode, commentModels -> {
+ commentsAdapter = new CommentsAdapter(commentModels, true, clickListener, mentionClickListener);
+ binding.rvComments.setAdapter(commentsAdapter);
+ binding.swipeRefreshLayout.setRefreshing(false);
+ }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
+ private void setTitle() {
+ final ActionBar actionBar = fragmentActivity.getSupportActionBar();
+ if (actionBar == null) return;
+ actionBar.setTitle(R.string.title_comments);
+ // actionBar.setSubtitle(shortCode);
+ }
+
+ final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> {
+ if (commentModel == null) {
+ Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ final ProfileModel profileModel = commentModel.getProfileModel();
+ switch (which) {
+ case 0: // open profile
+ openProfile(profileModel.getUsername());
+ break;
+ case 1: // view profile pic
+ startActivity(new Intent(requireContext(), ProfilePicViewer.class).putExtra(Constants.EXTRAS_PROFILE, profileModel));
+ break;
+ case 2: // copy username
+ Utils.copyText(requireContext(), profileModel.getUsername());
+ break;
+ case 3: // copy comment
+ Utils.copyText(requireContext(), commentModel.getText().toString());
+ break;
+ case 4: // reply to comment
+ final View focus = binding.rvComments.findViewWithTag(commentModel);
+ focus.setBackgroundColor(0x80888888);
+ String mention = "@" + profileModel.getUsername() + " ";
+ binding.commentText.setText(mention);
+ binding.commentText.requestFocus();
+ binding.commentText.setSelection(mention.length());
+ binding.commentText.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ imm = (InputMethodManager) requireContext().getSystemService(INPUT_METHOD_SERVICE);
+ if (imm == null) return;
+ imm.showSoftInput(binding.commentText, 0);
+ }
+ }, 200);
+ break;
+ case 5: // like/unlike comment
+ if (!commentModel.getLiked()) {
+ mediaService.commentLike(commentModel.getId(), Utils.getCsrfTokenFromCookie(cookie), new ServiceCallback() {
+ @Override
+ public void onSuccess(final Boolean result) {
+ commentModel = null;
+ if (!result) {
+ Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ onRefresh();
+ }
+
+ @Override
+ public void onFailure(final Throwable t) {
+ Log.e(TAG, "Error liking comment", t);
+ Toast.makeText(requireContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
+ }
+ });
+ return;
+ }
+ mediaService.commentUnlike(commentModel.getId(), Utils.getCsrfTokenFromCookie(cookie), new ServiceCallback() {
+ @Override
+ public void onSuccess(final Boolean result) {
+ commentModel = null;
+ if (!result) {
+ Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ onRefresh();
+ }
+
+ @Override
+ public void onFailure(final Throwable t) {
+ Log.e(TAG, "Error unliking comment", t);
+ Toast.makeText(requireContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
+ }
+ });
+ break;
+ case 6: // delete comment
+ final String userId = Utils.getUserIdFromCookie(cookie);
+ if (userId == null) return;
+ mediaService.deleteComment(
+ postId, userId, commentModel.getId(), Utils.getCsrfTokenFromCookie(cookie),
+ new ServiceCallback() {
+ @Override
+ public void onSuccess(final Boolean result) {
+ commentModel = null;
+ if (!result) {
+ Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ onRefresh();
+ }
+
+ @Override
+ public void onFailure(final Throwable t) {
+ Log.e(TAG, "Error deleting comment", t);
+ Toast.makeText(requireContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
+ }
+ });
+ break;
+ }
+ };
+
+ private final View.OnClickListener clickListener = v -> {
+ final Object tag = v.getTag();
+ if (tag instanceof CommentModel) {
+ commentModel = (CommentModel) tag;
+
+ final String username = commentModel.getProfileModel().getUsername();
+ final SpannableString title = new SpannableString(username + ":\n" + commentModel.getText());
+ title.setSpan(new RelativeSizeSpan(1.23f), 0, username.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+
+ String[] commentDialogList;
+
+ final String userIdFromCookie = Utils.getUserIdFromCookie(cookie);
+ if (!Utils.isEmpty(cookie)
+ && userIdFromCookie != null
+ && (userIdFromCookie.equals(commentModel.getProfileModel().getId()) || userIdFromCookie.equals(userId))) {
+ commentDialogList = new String[]{
+ resources.getString(R.string.open_profile),
+ resources.getString(R.string.view_pfp),
+ resources.getString(R.string.comment_viewer_copy_user),
+ resources.getString(R.string.comment_viewer_copy_comment),
+ resources.getString(R.string.comment_viewer_reply_comment),
+ commentModel.getLiked() ? resources.getString(R.string.comment_viewer_unlike_comment)
+ : resources.getString(R.string.comment_viewer_like_comment),
+ resources.getString(R.string.comment_viewer_delete_comment)
+ };
+ } else if (!Utils.isEmpty(cookie)) {
+ commentDialogList = new String[]{
+ resources.getString(R.string.open_profile),
+ resources.getString(R.string.view_pfp),
+ resources.getString(R.string.comment_viewer_copy_user),
+ resources.getString(R.string.comment_viewer_copy_comment),
+ resources.getString(R.string.comment_viewer_reply_comment),
+ commentModel.getLiked() ? resources.getString(R.string.comment_viewer_unlike_comment)
+ : resources.getString(R.string.comment_viewer_like_comment),
+ };
+ } else {
+ commentDialogList = new String[]{
+ resources.getString(R.string.open_profile),
+ resources.getString(R.string.view_pfp),
+ resources.getString(R.string.comment_viewer_copy_user),
+ resources.getString(R.string.comment_viewer_copy_comment)
+ };
+ }
+ new AlertDialog.Builder(requireContext())
+ .setTitle(title)
+ .setItems(commentDialogList, profileDialogListener)
+ .setNegativeButton(R.string.cancel, null)
+ .show();
+ }
+ };
+
+ private final MentionClickListener mentionClickListener = (view, text, isHashtag, isLocation) -> {
+ if (isHashtag) {
+ final NavDirections action = CommentsViewerFragmentDirections.actionGlobalHashTagFragment(text);
+ NavHostFragment.findNavController(this).navigate(action);
+ return;
+ }
+ openProfile(text);
+ };
+
+ private final View.OnClickListener newCommentListener = v -> {
+ final Editable text = binding.commentText.getText();
+ if (text == null || Utils.isEmpty(text.toString())) {
+ Toast.makeText(requireContext(), R.string.comment_send_empty_comment, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ final String userId = Utils.getUserIdFromCookie(cookie);
+ if (userId == null) return;
+ String replyToId = null;
+ if (commentModel != null) {
+ replyToId = commentModel.getId();
+ }
+ mediaService.comment(postId, text.toString(), userId, replyToId, Utils.getCsrfTokenFromCookie(cookie), new ServiceCallback() {
+ @Override
+ public void onSuccess(final Boolean result) {
+ commentModel = null;
+ binding.commentText.setText("");
+ if (!result) {
+ Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ onRefresh();
+ }
+
+ @Override
+ public void onFailure(final Throwable t) {
+ Log.e(TAG, "Error during comment", t);
+ Toast.makeText(requireContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
+ }
+ });
+ };
+
+ private void openProfile(final String username) {
+ final NavDirections action = CommentsViewerFragmentDirections.actionGlobalProfileFragment("@" + username);
+ NavHostFragment.findNavController(this).navigate(action);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/activities/DirectMessagesActivity.java b/app/src/main/java/awais/instagrabber/activities/DirectMessagesActivity.java
index d8043469..029ca84f 100644
--- a/app/src/main/java/awais/instagrabber/activities/DirectMessagesActivity.java
+++ b/app/src/main/java/awais/instagrabber/activities/DirectMessagesActivity.java
@@ -21,6 +21,7 @@ import awais.instagrabber.fragments.directmessages.DirectMessageThreadFragmentAr
import awais.instagrabber.utils.Constants;
import static awais.instagrabber.utils.Utils.settingsHelper;
+@Deprecated
public class DirectMessagesActivity extends BaseLanguageActivity implements NavController.OnDestinationChangedListener {
private TextView toolbarTitle;
diff --git a/app/src/main/java/awais/instagrabber/activities/MainActivity.java b/app/src/main/java/awais/instagrabber/activities/MainActivity.java
index 673beb2c..2aa6b32b 100644
--- a/app/src/main/java/awais/instagrabber/activities/MainActivity.java
+++ b/app/src/main/java/awais/instagrabber/activities/MainActivity.java
@@ -14,9 +14,11 @@ import androidx.navigation.NavController;
import androidx.navigation.ui.NavigationUI;
import com.google.android.material.appbar.AppBarLayout;
+import com.google.android.material.appbar.CollapsingToolbarLayout;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import awais.instagrabber.R;
@@ -46,7 +48,9 @@ public class MainActivity extends BaseLanguageActivity {
R.id.settingsPreferencesFragment,
R.id.hashTagFragment,
R.id.locationFragment,
- R.id.savedViewerFragment);
+ R.id.savedViewerFragment,
+ R.id.commentsViewerFragment);
+ private static final List REMOVE_COLLAPSING_TOOLBAR_SCROLL_DESTINATIONS = Collections.singletonList(R.id.commentsViewerFragment);
private ActivityMainBinding binding;
private LiveData currentNavControllerLiveData;
@@ -110,6 +114,11 @@ public class MainActivity extends BaseLanguageActivity {
} else {
removeScrollingBehaviour();
}
+ if (REMOVE_COLLAPSING_TOOLBAR_SCROLL_DESTINATIONS.contains(destinationId)) {
+ removeCollapsingToolbarScrollFlags();
+ } else {
+ setCollapsingToolbarScrollFlags();
+ }
});
}
@@ -125,6 +134,22 @@ public class MainActivity extends BaseLanguageActivity {
binding.mainNavHost.requestLayout();
}
+ private void setCollapsingToolbarScrollFlags() {
+ final CollapsingToolbarLayout collapsingToolbarLayout = binding.collapsingToolbarLayout;
+ final AppBarLayout.LayoutParams toolbarLayoutLayoutParams = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams();
+ toolbarLayoutLayoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
+ | AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP
+ | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS);
+ binding.collapsingToolbarLayout.requestLayout();
+ }
+
+ private void removeCollapsingToolbarScrollFlags() {
+ final CollapsingToolbarLayout collapsingToolbarLayout = binding.collapsingToolbarLayout;
+ final AppBarLayout.LayoutParams toolbarLayoutLayoutParams = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams();
+ toolbarLayoutLayoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL);
+ binding.collapsingToolbarLayout.requestLayout();
+ }
+
@Override
protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
diff --git a/app/src/main/java/awais/instagrabber/activities/PostViewer.java b/app/src/main/java/awais/instagrabber/activities/PostViewer.java
index 00567bad..bc47dde0 100755
--- a/app/src/main/java/awais/instagrabber/activities/PostViewer.java
+++ b/app/src/main/java/awais/instagrabber/activities/PostViewer.java
@@ -221,7 +221,7 @@ public final class PostViewer extends BaseLanguageActivity {
viewerBinding.bottomPanel.btnComments.setVisibility(View.VISIBLE);
viewerBinding.bottomPanel.btnComments.setOnClickListener(v -> startActivityForResult(
- new Intent(this, CommentsViewer.class)
+ new Intent(this, CommentsViewerFragment.class)
.putExtra(Constants.EXTRAS_SHORTCODE, postModel.getShortCode())
.putExtra(Constants.EXTRAS_POST, viewerPostModel.getPostId())
.putExtra(Constants.EXTRAS_USER, postUserId),
diff --git a/app/src/main/java/awais/instagrabber/activities/ProfileViewer.java b/app/src/main/java/awais/instagrabber/activities/ProfileViewer.java
index d781d637..30177311 100755
--- a/app/src/main/java/awais/instagrabber/activities/ProfileViewer.java
+++ b/app/src/main/java/awais/instagrabber/activities/ProfileViewer.java
@@ -72,6 +72,7 @@ import awaisomereport.LogCollector;
import static awais.instagrabber.utils.Constants.AUTOLOAD_POSTS;
import static awais.instagrabber.utils.Utils.logCollector;
+@Deprecated
public final class ProfileViewer extends BaseLanguageActivity implements SwipeRefreshLayout.OnRefreshListener {
private final ArrayList allItems = new ArrayList<>(), selectedItems = new ArrayList<>();
private static AsyncTask, ?, ?> currentlyExecuting;
diff --git a/app/src/main/java/awais/instagrabber/activities/StoryViewer.java b/app/src/main/java/awais/instagrabber/activities/StoryViewer.java
deleted file mode 100755
index dd63ba7a..00000000
--- a/app/src/main/java/awais/instagrabber/activities/StoryViewer.java
+++ /dev/null
@@ -1,167 +0,0 @@
-// package awais.instagrabber.activities;
-//
-// import android.content.Intent;
-// import android.os.AsyncTask;
-// import android.os.Bundle;
-// import android.view.MenuItem;
-// import android.view.View;
-// import android.widget.Toast;
-//
-// import androidx.annotation.Nullable;
-// import androidx.core.view.GestureDetectorCompat;
-// import androidx.recyclerview.widget.LinearLayoutManager;
-//
-// import awais.instagrabber.R;
-// import awais.instagrabber.adapters.StoriesAdapter;
-// import awais.instagrabber.asyncs.SeenAction;
-// import awais.instagrabber.asyncs.i.iStoryStatusFetcher;
-// import awais.instagrabber.customviews.helpers.SwipeGestureListener;
-// import awais.instagrabber.databinding.ActivityStoryViewerBinding;
-// import awais.instagrabber.interfaces.SwipeEvent;
-// import awais.instagrabber.models.FeedStoryModel;
-// import awais.instagrabber.models.StoryModel;
-// import awais.instagrabber.models.stickers.PollModel;
-// import awais.instagrabber.models.stickers.QuestionModel;
-// import awais.instagrabber.models.stickers.QuizModel;
-// import awais.instagrabber.utils.Constants;
-// import awais.instagrabber.utils.Utils;
-//
-// import static awais.instagrabber.utils.Constants.MARK_AS_SEEN;
-// import static awais.instagrabber.utils.Utils.settingsHelper;
-//
-// public final class StoryViewer extends BaseLanguageActivity {
-// private final StoriesAdapter storiesAdapter = new StoriesAdapter(null, new View.OnClickListener() {
-// @Override
-// public void onClick(final View v) {
-// final Object tag = v.getTag();
-// if (tag instanceof StoryModel) {
-// currentStory = (StoryModel) tag;
-// slidePos = currentStory.getPosition();
-// refreshStory();
-// }
-// }
-// });
-// private ActivityStoryViewerBinding storyViewerBinding;
-// private StoryModel[] storyModels;
-// private GestureDetectorCompat gestureDetector;
-//
-// private SwipeEvent swipeEvent;
-// private MenuItem menuDownload, menuDm;
-// private PollModel poll;
-// private QuestionModel question;
-// private String[] mentions;
-// private QuizModel quiz;
-// private StoryModel currentStory;
-// private String url, username;
-// private int slidePos = 0, lastSlidePos = 0;
-// private final String cookie = settingsHelper.getString(Constants.COOKIE);
-// private boolean fetching = false;
-//
-// @Override
-// protected void onCreate(@Nullable final Bundle savedInstanceState) {
-// super.onCreate(savedInstanceState);
-// storyViewerBinding = ActivityStoryViewerBinding.inflate(getLayoutInflater());
-// setContentView(storyViewerBinding.getRoot());
-//
-// setSupportActionBar(storyViewerBinding.toolbar.toolbar);
-//
-// final Intent intent = getIntent();
-// if (intent == null || !intent.hasExtra(Constants.EXTRAS_STORIES)
-// || (storyModels = (StoryModel[]) intent.getSerializableExtra(Constants.EXTRAS_STORIES)) == null) {
-// Utils.errorFinish(this);
-// return;
-// }
-//
-// username = intent.getStringExtra(Constants.EXTRAS_USERNAME);
-// final String highlight = intent.getStringExtra(Constants.EXTRAS_HIGHLIGHT);
-// final boolean hasUsername = !Utils.isEmpty(username);
-// final boolean hasHighlight = !Utils.isEmpty(highlight);
-//
-// if (hasUsername) {
-// username = username.replace("@", "");
-// storyViewerBinding.toolbar.toolbar.setTitle(username);
-// storyViewerBinding.toolbar.toolbar.setOnClickListener(v -> {
-// searchUsername(username);
-// });
-// if (hasHighlight) storyViewerBinding.toolbar.toolbar.setSubtitle(getString(R.string.title_highlight, highlight));
-// else storyViewerBinding.toolbar.toolbar.setSubtitle(R.string.title_user_story);
-// }
-//
-// storyViewerBinding.storiesList.setVisibility(View.GONE);
-// storyViewerBinding.storiesList.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
-// storyViewerBinding.storiesList.setAdapter(storiesAdapter);
-//
-// swipeEvent = new SwipeEvent() {
-// private final int storiesLen = storyModels != null ? storyModels.length : 0;
-//
-// @Override
-// public void onSwipe(final boolean isRightSwipe) {
-// if (storyModels != null && storiesLen > 0) {
-// if (((slidePos + 1 >= storiesLen && isRightSwipe == false) || (slidePos == 0 && isRightSwipe == true))
-// && intent.hasExtra(Constants.FEED)) {
-// final FeedStoryModel[] storyFeed = (FeedStoryModel[]) intent.getSerializableExtra(Constants.FEED);
-// final int index = intent.getIntExtra(Constants.FEED_ORDER, 1738);
-// if (settingsHelper.getBoolean(MARK_AS_SEEN)) new SeenAction(cookie, storyModel).execute();
-// if ((isRightSwipe == true && index == 0) || (isRightSwipe == false && index == storyFeed.length - 1))
-// Toast.makeText(getApplicationContext(), R.string.no_more_stories, Toast.LENGTH_SHORT).show();
-// else {
-// final FeedStoryModel feedStoryModel = isRightSwipe ?
-// (index == 0 ? null : storyFeed[index - 1]) :
-// (storyFeed.length == index + 1 ? null : storyFeed[index + 1]);
-// if (feedStoryModel != null) {
-// if (fetching) {
-// Toast.makeText(getApplicationContext(), R.string.be_patient, Toast.LENGTH_SHORT).show();
-// } else {
-// fetching = true;
-// new iStoryStatusFetcher(feedStoryModel.getStoryMediaId(), null, false, false, false, false, result -> {
-// if (result != null && result.length > 0) {
-// final Intent newIntent = new Intent(getApplicationContext(), StoryViewer.class)
-// .putExtra(Constants.EXTRAS_STORIES, result)
-// .putExtra(Constants.EXTRAS_USERNAME, feedStoryModel.getProfileModel().getUsername())
-// .putExtra(Constants.FEED, storyFeed)
-// .putExtra(Constants.FEED_ORDER, isRightSwipe ? (index - 1) : (index + 1));
-// newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-// startActivity(newIntent);
-// } else
-// Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
-// }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-// }
-// }
-// }
-// }
-// else {
-// if (isRightSwipe) {
-// if (--slidePos <= 0) slidePos = 0;
-// } else if (++slidePos >= storiesLen) slidePos = storiesLen - 1;
-// currentStory = storyModels[slidePos];
-// refreshStory();
-// }
-// }
-// }
-// };
-// gestureDetector = new GestureDetectorCompat(this, new SwipeGestureListener(swipeEvent));
-//
-// viewPost();
-// }
-//
-// private void searchUsername(final String text) {
-// startActivity(
-// new Intent(getApplicationContext(), ProfileViewer.class)
-// .putExtra(Constants.EXTRAS_USERNAME, text)
-// );
-// }
-//
-//
-//
-// public static int indexOfIntArray(Object[] array, Object key) {
-// int returnvalue = -1;
-// for (int i = 0; i < array.length; ++i) {
-// if (key == array[i]) {
-// returnvalue = i;
-// break;
-// }
-// }
-// return returnvalue;
-// }
-//
-// }
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java
index 3a456c21..77e308cd 100755
--- a/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java
+++ b/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java
@@ -10,9 +10,6 @@ import android.widget.Filterable;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.request.RequestOptions;
-
import java.util.ArrayList;
import awais.instagrabber.R;
@@ -24,7 +21,15 @@ import awais.instagrabber.utils.LocaleUtils;
import awais.instagrabber.utils.Utils;
public final class CommentsAdapter extends RecyclerView.Adapter implements Filterable {
+
+ private CommentModel[] filteredCommentModels;
+ private LayoutInflater layoutInflater;
+
private final boolean isParent;
+ private final View.OnClickListener onClickListener;
+ private final MentionClickListener mentionClickListener;
+ private final CommentModel[] commentModels;
+ private final String[] quantityStrings = new String[2];
private final Filter filter = new Filter() {
@NonNull
@Override
@@ -66,14 +71,10 @@ public final class CommentsAdapter extends RecyclerView.Adapter 0)
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/CommentViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/CommentViewHolder.java
index d34b0597..0a2e7687 100755
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/CommentViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/CommentViewHolder.java
@@ -2,12 +2,13 @@ package awais.instagrabber.adapters.viewholder;
import android.text.Spannable;
import android.view.View;
-import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
+import com.facebook.drawee.view.SimpleDraweeView;
+
import awais.instagrabber.R;
import awais.instagrabber.adapters.CommentsAdapter;
import awais.instagrabber.customviews.RamboTextView;
@@ -17,11 +18,16 @@ import awais.instagrabber.models.CommentModel;
public final class CommentViewHolder extends RecyclerView.ViewHolder {
private final MentionClickListener mentionClickListener;
private final RecyclerView rvChildComments;
- private final ImageView ivProfilePic;
- private final TextView tvUsername, tvDate, tvComment, tvLikes;
+ private final SimpleDraweeView ivProfilePic;
+ private final TextView tvUsername;
+ private final TextView tvDate;
+ private final TextView tvComment;
+ private final TextView tvLikes;
private final View container;
- public CommentViewHolder(@NonNull final View itemView, final View.OnClickListener onClickListener, final MentionClickListener mentionClickListener) {
+ public CommentViewHolder(@NonNull final View itemView,
+ final View.OnClickListener onClickListener,
+ final MentionClickListener mentionClickListener) {
super(itemView);
container = itemView.findViewById(R.id.container);
@@ -41,7 +47,7 @@ public final class CommentViewHolder extends RecyclerView.ViewHolder {
rvChildComments = itemView.findViewById(R.id.rvChildComments);
}
- public final ImageView getProfilePicView() {
+ public final SimpleDraweeView getProfilePicView() {
return ivProfilePic;
}
@@ -69,9 +75,9 @@ public final class CommentViewHolder extends RecyclerView.ViewHolder {
if (liked) container.setBackgroundColor(0x40FF69B4);
}
- public final void setCommment(final CharSequence commment) {
+ public final void setComment(final CharSequence comment) {
if (tvComment != null) {
- tvComment.setText(commment, commment instanceof Spannable ? TextView.BufferType.SPANNABLE : TextView.BufferType.NORMAL);
+ tvComment.setText(comment, comment instanceof Spannable ? TextView.BufferType.SPANNABLE : TextView.BufferType.NORMAL);
((RamboTextView) tvComment).setMentionClickListener(mentionClickListener);
}
}
diff --git a/app/src/main/java/awais/instagrabber/asyncs/ImageUploader.java b/app/src/main/java/awais/instagrabber/asyncs/ImageUploader.java
index e4cdaa6e..dd4b1cd1 100644
--- a/app/src/main/java/awais/instagrabber/asyncs/ImageUploader.java
+++ b/app/src/main/java/awais/instagrabber/asyncs/ImageUploader.java
@@ -18,7 +18,6 @@ import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
-import java.util.Random;
import java.util.UUID;
import awais.instagrabber.models.ImageUploadOptions;
@@ -52,7 +51,7 @@ public class ImageUploader extends AsyncTask headers = new HashMap<>();
final String uploadId = String.valueOf(new Date().getTime());
- final long random = LOWER + new Random().nextLong() * (UPPER - LOWER + 1);
+ final long random = Utils.random(LOWER, UPPER + 1);
final String name = String.format("%s_0_%s", uploadId, random);
final String waterfallId = options.getWaterfallId() != null ? options.getWaterfallId() : UUID.randomUUID().toString();
headers.put("X-Entity-Type", "image/jpeg");
diff --git a/app/src/main/java/awais/instagrabber/asyncs/i/iPostFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/i/iPostFetcher.java
index 3e8378f2..c022a80f 100755
--- a/app/src/main/java/awais/instagrabber/asyncs/i/iPostFetcher.java
+++ b/app/src/main/java/awais/instagrabber/asyncs/i/iPostFetcher.java
@@ -65,7 +65,7 @@ public final class iPostFetcher extends AsyncTask
user.optBoolean("is_private"),
user.optBoolean("is_private"),
user.optBoolean("is_verified"),
- null,
+ user.optString("pk"),
user.getString(Constants.EXTRAS_USERNAME),
user.optString("fullname"),
null,
diff --git a/app/src/main/java/awais/instagrabber/fragments/PostViewFragment.java b/app/src/main/java/awais/instagrabber/fragments/PostViewFragment.java
index bcb58d8b..f5a67884 100644
--- a/app/src/main/java/awais/instagrabber/fragments/PostViewFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/PostViewFragment.java
@@ -1,7 +1,6 @@
package awais.instagrabber.fragments;
import android.content.DialogInterface;
-import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -26,7 +25,6 @@ import java.util.Collections;
import java.util.List;
import awais.instagrabber.R;
-import awais.instagrabber.activities.CommentsViewer;
import awais.instagrabber.adapters.PostViewAdapter;
import awais.instagrabber.adapters.PostViewAdapter.OnPostViewChildViewClickListener;
import awais.instagrabber.asyncs.PostFetcher;
@@ -114,12 +112,18 @@ public class PostViewFragment extends Fragment {
case R.id.viewerCaption:
break;
case R.id.btnComments:
- startActivity(new Intent(requireContext(), CommentsViewer.class)
- .putExtra(Constants.EXTRAS_SHORTCODE,
- postModel.getShortCode())
- .putExtra(Constants.EXTRAS_POST, postModel.getPostId())
- .putExtra(Constants.EXTRAS_USER,
- Utils.getUserIdFromCookie(COOKIE)));
+ // startActivity(new Intent(requireContext(), CommentsViewerFragment.class)
+ // .putExtra(Constants.EXTRAS_SHORTCODE, postModel.getShortCode())
+ // .putExtra(Constants.EXTRAS_POST, postModel.getPostId())
+ // .putExtra(Constants.EXTRAS_USER, Utils.getUserIdFromCookie(COOKIE)));
+ String postId = postModel.getPostId();
+ if (postId.contains("_")) postId = postId.substring(0, postId.indexOf("_"));
+ final NavDirections commentsAction = PostViewFragmentDirections.actionGlobalCommentsViewerFragment(
+ postModel.getShortCode(),
+ postId,
+ postModel.getProfileModel().getId()
+ );
+ NavHostFragment.findNavController(this).navigate(commentsAction);
break;
case R.id.btnDownload:
if (checkSelfPermission(requireContext(),
diff --git a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java
index 6f441bc4..bdba2e0b 100644
--- a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java
@@ -1,7 +1,6 @@
package awais.instagrabber.fragments.main;
import android.content.DialogInterface;
-import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -35,7 +34,6 @@ import java.util.List;
import java.util.Map;
import awais.instagrabber.R;
-import awais.instagrabber.activities.CommentsViewer;
import awais.instagrabber.activities.MainActivity;
import awais.instagrabber.adapters.FeedAdapter;
import awais.instagrabber.adapters.FeedStoriesAdapter;
@@ -187,17 +185,14 @@ public class FeedFragment extends Fragment {
final int id = v.getId();
switch (id) {
case R.id.btnComments:
- startActivity(new Intent(requireContext(), CommentsViewer.class)
- .putExtra(Constants.EXTRAS_SHORTCODE, feedModel.getShortCode())
- .putExtra(Constants.EXTRAS_POST, feedModel.getPostId())
- .putExtra(Constants.EXTRAS_USER, feedModel.getProfileModel().getId()));
+ final NavDirections commentsAction = FeedFragmentDirections.actionGlobalCommentsViewerFragment(
+ feedModel.getShortCode(),
+ feedModel.getPostId(),
+ feedModel.getProfileModel().getId()
+ );
+ NavHostFragment.findNavController(this).navigate(commentsAction);
break;
-
case R.id.viewStoryPost:
- // startActivity(new Intent(requireContext(), PostViewer.class)
- // .putExtra(Constants.EXTRAS_INDEX, feedModel.getPosition())
- // .putExtra(Constants.EXTRAS_POST, new PostModel(feedModel.getShortCode(), false))
- // .putExtra(Constants.EXTRAS_TYPE, ItemGetType.FEED_ITEMS));
final List feedModels = feedViewModel.getList().getValue();
if (feedModels == null || feedModels.size() == 0) return;
if (feedModels.get(0) == null) return;
@@ -296,11 +291,9 @@ public class FeedFragment extends Fragment {
@Override
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
if (!shouldRefresh) return;
- // setupActionBar();
setupFeedStories();
setupFeed();
shouldRefresh = false;
- // feedService.getFeed(11, null);
}
@Override
diff --git a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
index 7707fa13..5ab38b63 100644
--- a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
@@ -456,16 +456,14 @@ public class ProfileFragment extends Fragment {
binding.mainFollowers.setClickable(true);
if (isLoggedIn) {
- final View.OnClickListener followClickListener = v -> startActivity(new Intent(
- requireContext(),
- FollowViewer.class).putExtra(Constants.EXTRAS_FOLLOWERS, v == binding.mainFollowers)
- .putExtra(Constants.EXTRAS_NAME, profileModel.getUsername())
- .putExtra(Constants.EXTRAS_ID, profileId));
+ final View.OnClickListener followClickListener = v -> startActivity(
+ new Intent(requireContext(), FollowViewer.class)
+ .putExtra(Constants.EXTRAS_FOLLOWERS, v == binding.mainFollowers)
+ .putExtra(Constants.EXTRAS_NAME, profileModel.getUsername())
+ .putExtra(Constants.EXTRAS_ID, profileId));
- binding.mainFollowers
- .setOnClickListener(followersCount > 0 ? followClickListener : null);
- binding.mainFollowing
- .setOnClickListener(followingCount > 0 ? followClickListener : null);
+ binding.mainFollowers.setOnClickListener(followersCount > 0 ? followClickListener : null);
+ binding.mainFollowing.setOnClickListener(followingCount > 0 ? followClickListener : null);
}
if (profileModel.getPostCount() == 0) {
diff --git a/app/src/main/java/awais/instagrabber/repositories/MediaRepository.java b/app/src/main/java/awais/instagrabber/repositories/MediaRepository.java
index e9075ab1..048df6ca 100644
--- a/app/src/main/java/awais/instagrabber/repositories/MediaRepository.java
+++ b/app/src/main/java/awais/instagrabber/repositories/MediaRepository.java
@@ -13,8 +13,32 @@ public interface MediaRepository {
@FormUrlEncoded
@POST("/api/v1/media/{mediaId}/{action}/")
- Call likeAction(@Header("User-Agent") final String userAgent,
- @Path("action") final String action,
- @Path("mediaId") final String mediaId,
- @FieldMap final Map signedForm);
+ Call action(@Header("User-Agent") final String userAgent,
+ @Path("action") final String action,
+ @Path("mediaId") final String mediaId,
+ @FieldMap final Map signedForm);
+
+ @FormUrlEncoded
+ @POST("/api/v1/media/{mediaId}/comment/")
+ Call comment(@Header("User-Agent") final String userAgent,
+ @Path("mediaId") final String mediaId,
+ @FieldMap final Map signedForm);
+
+ @FormUrlEncoded
+ @POST("/api/v1/media/{mediaId}/comment/bulk_delete/")
+ Call commentsBulkDelete(@Header("User-Agent") final String userAgent,
+ @Path("mediaId") final String mediaId,
+ @FieldMap final Map signedForm);
+
+ @FormUrlEncoded
+ @POST("/api/v1/media/{commentId}/comment_like/")
+ Call commentLike(@Header("User-Agent") final String userAgent,
+ @Path("commentId") final String commentId,
+ @FieldMap final Map signedForm);
+
+ @FormUrlEncoded
+ @POST("/api/v1/media/{commentId}/comment_unlike/")
+ Call commentUnlike(@Header("User-Agent") final String userAgent,
+ @Path("commentId") final String commentId,
+ @FieldMap final Map signedForm);
}
diff --git a/app/src/main/java/awais/instagrabber/services/BaseService.java b/app/src/main/java/awais/instagrabber/services/BaseService.java
index 99022370..6347ed0c 100644
--- a/app/src/main/java/awais/instagrabber/services/BaseService.java
+++ b/app/src/main/java/awais/instagrabber/services/BaseService.java
@@ -11,6 +11,7 @@ import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
public abstract class BaseService {
+ private static final String TAG = "BaseService";
private Retrofit.Builder builder;
@@ -33,4 +34,29 @@ public abstract class BaseService {
}
return builder;
}
+
+ // protected String userBreadcrumb(final int size) {
+ // final long term = (random(2, 4) * 1000) + size + (random(15, 21) * 1000);
+ // final float div = (float) size / random(2, 4);
+ // final int round = Math.round(div);
+ // final long textChangeEventCount = round > 0 ? round : 1;
+ // final String data = String.format(Locale.getDefault(), "%d %d %d %d", size, term, textChangeEventCount, new Date().getTime());
+ // try {
+ // final Mac hasher = Mac.getInstance("HmacSHA256");
+ // hasher.init(new SecretKeySpec(Constants.BREADCRUMB_KEY.getBytes(), "HmacSHA256"));
+ // byte[] hash = hasher.doFinal(data.getBytes());
+ // final StringBuilder hexString = new StringBuilder();
+ // for (byte b : hash) {
+ // final String hex = Integer.toHexString(0xff & b);
+ // if (hex.length() == 1) hexString.append('0');
+ // hexString.append(hex);
+ // }
+ // final String encodedData = Base64.encodeToString(data.getBytes(), Base64.NO_WRAP);
+ // final String encodedHex = Base64.encodeToString(hexString.toString().getBytes(), Base64.NO_WRAP);
+ // return String.format("%s\n%s\n", encodedHex, encodedData);
+ // } catch (Exception e) {
+ // Log.e(TAG, "Error creating breadcrumb", e);
+ // return null;
+ // }
+ // }
}
diff --git a/app/src/main/java/awais/instagrabber/services/LoggingInterceptor.java b/app/src/main/java/awais/instagrabber/services/LoggingInterceptor.java
index 3da71476..15fce4c9 100644
--- a/app/src/main/java/awais/instagrabber/services/LoggingInterceptor.java
+++ b/app/src/main/java/awais/instagrabber/services/LoggingInterceptor.java
@@ -21,7 +21,7 @@ class LoggingInterceptor implements Interceptor {
Request request = chain.request();
long t1 = System.nanoTime();
Log.i(TAG, String.format("Sending request %s on %s%n%s",
- request.url(), chain.connection(), request.headers()));
+ request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);
long t2 = System.nanoTime();
Log.i(TAG, String.format("Received response for %s in %.1fms%n%s", response.request().url(), (t2 - t1) / 1e6d, response.headers()));
@@ -30,6 +30,8 @@ class LoggingInterceptor implements Interceptor {
Log.d("OkHttp", content);
ResponseBody wrappedBody = ResponseBody.create(contentType, content);
- return response.newBuilder().body(wrappedBody).build();
+ return response.newBuilder()
+ .body(wrappedBody)
+ .build();
}
}
diff --git a/app/src/main/java/awais/instagrabber/services/MediaService.java b/app/src/main/java/awais/instagrabber/services/MediaService.java
index 273357c6..125b99c6 100644
--- a/app/src/main/java/awais/instagrabber/services/MediaService.java
+++ b/app/src/main/java/awais/instagrabber/services/MediaService.java
@@ -1,11 +1,16 @@
package awais.instagrabber.services;
+import android.text.TextUtils;
+import android.util.Log;
+
import androidx.annotation.NonNull;
import org.json.JSONException;
import org.json.JSONObject;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -42,35 +47,35 @@ public class MediaService extends BaseService {
final String userId,
final String csrfToken,
final ServiceCallback callback) {
- likeAction(mediaId, userId, "like", csrfToken, callback);
+ action(mediaId, userId, "like", csrfToken, callback);
}
public void unlike(final String mediaId,
final String userId,
final String csrfToken,
final ServiceCallback callback) {
- likeAction(mediaId, userId, "unlike", csrfToken, callback);
+ action(mediaId, userId, "unlike", csrfToken, callback);
}
public void save(final String mediaId,
final String userId,
final String csrfToken,
final ServiceCallback callback) {
- likeAction(mediaId, userId, "save", csrfToken, callback);
+ action(mediaId, userId, "save", csrfToken, callback);
}
public void unsave(final String mediaId,
final String userId,
final String csrfToken,
final ServiceCallback callback) {
- likeAction(mediaId, userId, "unsave", csrfToken, callback);
+ action(mediaId, userId, "unsave", csrfToken, callback);
}
- private void likeAction(final String mediaId,
- final String userId,
- final String action,
- final String csrfToken,
- final ServiceCallback callback) {
+ private void action(final String mediaId,
+ final String userId,
+ final String action,
+ final String csrfToken,
+ final ServiceCallback callback) {
final Map form = new HashMap<>(4);
form.put("media_id", mediaId);
form.put("_csrftoken", csrfToken);
@@ -78,7 +83,7 @@ public class MediaService extends BaseService {
form.put("_uuid", UUID.randomUUID().toString());
// form.put("radio_type", "wifi-none");
final Map signedForm = Utils.sign(form);
- final Call request = repository.likeAction(Constants.I_USER_AGENT, action, mediaId, signedForm);
+ final Call request = repository.action(Constants.I_USER_AGENT, action, mediaId, signedForm);
request.enqueue(new Callback() {
@Override
public void onResponse(@NonNull final Call call,
@@ -106,23 +111,170 @@ public class MediaService extends BaseService {
}
}
});
- // const signedFormData = this.client.request.sign({
- // media_id: options.mediaId,
- // _csrftoken: this.client.state.cookieCsrfToken,
- // _uid: this.client.state.cookieUserId,
- // _uuid: this.client.state.uuid,
- // });
- //
- // const { body } = await this.client.request.send({
- // url: `/api/v1/media/${options.mediaId}/${options.action}/`,
- // method: 'POST',
- // form: {
- // ...signedFormData,
- // d: options.d,
- // },
- // });
- // return body;
}
+ public void comment(@NonNull final String mediaId,
+ @NonNull final String comment,
+ @NonNull final String userId,
+ final String replyToCommentId,
+ final String csrfToken,
+ @NonNull final ServiceCallback callback) {
+ final String module = "self_comments_v2";
+ final Map form = new HashMap<>();
+ // form.put("user_breadcrumb", userBreadcrumb(comment.length()));
+ form.put("idempotence_token", UUID.randomUUID().toString());
+ form.put("_csrftoken", csrfToken);
+ form.put("_uid", userId);
+ form.put("_uuid", UUID.randomUUID().toString());
+ form.put("comment_text", comment);
+ form.put("containermodule", module);
+ if (!Utils.isEmpty(replyToCommentId)) {
+ form.put("replied_to_comment_id", replyToCommentId);
+ }
+ final Map signedForm = Utils.sign(form);
+ final Call commentRequest = repository.comment(Constants.I_USER_AGENT, mediaId, signedForm);
+ commentRequest.enqueue(new Callback() {
+ @Override
+ public void onResponse(@NonNull final Call call, @NonNull final Response response) {
+ final String body = response.body();
+ if (body == null) {
+ Log.e(TAG, "Error occurred while creating comment");
+ callback.onSuccess(false);
+ return;
+ }
+ try {
+ final JSONObject jsonObject = new JSONObject(body);
+ final String status = jsonObject.optString("status");
+ callback.onSuccess(status.equals("ok"));
+ } catch (JSONException e) {
+ // Log.e(TAG, "Error parsing body", e);
+ callback.onFailure(e);
+ }
+ }
+ @Override
+ public void onFailure(@NonNull final Call call, @NonNull final Throwable t) {
+ callback.onFailure(t);
+ }
+ });
+ }
+
+ public void deleteComment(final String mediaId,
+ final String userId,
+ final String commentId,
+ final String csrfToken,
+ @NonNull final ServiceCallback callback) {
+ deleteComments(mediaId, userId, Collections.singletonList(commentId), csrfToken, callback);
+ }
+
+ public void deleteComments(final String mediaId,
+ final String userId,
+ final List commentIds,
+ final String csrfToken,
+ @NonNull final ServiceCallback callback) {
+ final Map form = new HashMap<>();
+ form.put("comment_ids_to_delete", TextUtils.join(",", commentIds));
+ form.put("_csrftoken", csrfToken);
+ form.put("_uid", userId);
+ form.put("_uuid", UUID.randomUUID().toString());
+ final Map signedForm = Utils.sign(form);
+ final Call bulkDeleteRequest = repository.commentsBulkDelete(Constants.USER_AGENT, mediaId, signedForm);
+ bulkDeleteRequest.enqueue(new Callback() {
+ @Override
+ public void onResponse(@NonNull final Call call, @NonNull final Response response) {
+ final String body = response.body();
+ if (body == null) {
+ Log.e(TAG, "Error occurred while deleting comments");
+ callback.onSuccess(false);
+ return;
+ }
+ try {
+ final JSONObject jsonObject = new JSONObject(body);
+ final String status = jsonObject.optString("status");
+ callback.onSuccess(status.equals("ok"));
+ } catch (JSONException e) {
+ // Log.e(TAG, "Error parsing body", e);
+ callback.onFailure(e);
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull final Call call, @NonNull final Throwable t) {
+ // Log.e(TAG, "Error deleting comments", t);
+ callback.onFailure(t);
+ }
+ });
+ }
+
+ public void commentLike(@NonNull final String commentId,
+ @NonNull final String csrfToken,
+ @NonNull final ServiceCallback callback) {
+ final Map form = new HashMap<>();
+ form.put("_csrftoken", csrfToken);
+ // form.put("_uid", userId);
+ // form.put("_uuid", UUID.randomUUID().toString());
+ final Map signedForm = Utils.sign(form);
+ final Call commentLikeRequest = repository.commentLike(Constants.USER_AGENT, commentId, signedForm);
+ commentLikeRequest.enqueue(new Callback() {
+ @Override
+ public void onResponse(@NonNull final Call call, @NonNull final Response response) {
+ final String body = response.body();
+ if (body == null) {
+ Log.e(TAG, "Error occurred while liking comment");
+ callback.onSuccess(false);
+ return;
+ }
+ try {
+ final JSONObject jsonObject = new JSONObject(body);
+ final String status = jsonObject.optString("status");
+ callback.onSuccess(status.equals("ok"));
+ } catch (JSONException e) {
+ // Log.e(TAG, "Error parsing body", e);
+ callback.onFailure(e);
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull final Call call, @NonNull final Throwable t) {
+ Log.e(TAG, "Error liking comment", t);
+ callback.onFailure(t);
+ }
+ });
+ }
+
+ public void commentUnlike(final String commentId,
+ @NonNull final String csrfToken,
+ @NonNull final ServiceCallback callback) {
+ final Map form = new HashMap<>();
+ form.put("_csrftoken", csrfToken);
+ // form.put("_uid", userId);
+ // form.put("_uuid", UUID.randomUUID().toString());
+ final Map signedForm = Utils.sign(form);
+ final Call commentUnlikeRequest = repository.commentUnlike(Constants.USER_AGENT, commentId, signedForm);
+ commentUnlikeRequest.enqueue(new Callback() {
+ @Override
+ public void onResponse(@NonNull final Call call, @NonNull final Response response) {
+ final String body = response.body();
+ if (body == null) {
+ Log.e(TAG, "Error occurred while unliking comment");
+ callback.onSuccess(false);
+ return;
+ }
+ try {
+ final JSONObject jsonObject = new JSONObject(body);
+ final String status = jsonObject.optString("status");
+ callback.onSuccess(status.equals("ok"));
+ } catch (JSONException e) {
+ // Log.e(TAG, "Error parsing body", e);
+ callback.onFailure(e);
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull final Call call, @NonNull final Throwable t) {
+ Log.e(TAG, "Error unliking comment", t);
+ callback.onFailure(t);
+ }
+ });
+ }
}
diff --git a/app/src/main/java/awais/instagrabber/utils/Constants.java b/app/src/main/java/awais/instagrabber/utils/Constants.java
index 4354f548..1fe142de 100755
--- a/app/src/main/java/awais/instagrabber/utils/Constants.java
+++ b/app/src/main/java/awais/instagrabber/utils/Constants.java
@@ -66,5 +66,6 @@ public final class Constants {
"\"gyroscope\", \"value\": \"gyroscope_enabled\" } ]";
public static final String SIGNATURE_VERSION = "4";
public static final String SIGNATURE_KEY = "9193488027538fd3450b83b7d05286d4ca9599a0f7eeed90d8c85925698a05dc";
+ public static final String BREADCRUMB_KEY = "iN4$aGr0m";
public static final int LOGIN_RESULT_CODE = 5000;
}
\ 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 75874785..1f4f3185 100755
--- a/app/src/main/java/awais/instagrabber/utils/Utils.java
+++ b/app/src/main/java/awais/instagrabber/utils/Utils.java
@@ -63,6 +63,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Random;
import java.util.Set;
import java.util.regex.Pattern;
@@ -1220,9 +1221,13 @@ public final class Utils {
}
public static String sign(final String message) {
+ return sign(Constants.SIGNATURE_KEY, message);
+ }
+
+ public static String sign(final String key, final String message) {
try {
final Mac hasher = Mac.getInstance("HmacSHA256");
- hasher.init(new SecretKeySpec(Constants.SIGNATURE_KEY.getBytes(), "HmacSHA256"));
+ hasher.init(new SecretKeySpec(key.getBytes(), "HmacSHA256"));
byte[] hash = hasher.doFinal(message.getBytes());
final StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
@@ -1458,4 +1463,29 @@ public final class Utils {
}
return cookie.split("csrftoken=")[1].split(";")[0];
}
+
+ // public static long random(final long lower, final long upper) {
+ // final long result = lower + new Random().nextLong() * (upper - lower + 1);
+ // return result;
+ // }
+
+ public static long random(long origin, long bound) {
+ final Random random = new Random();
+ long r = random.nextLong();
+ long n = bound - origin, m = n - 1;
+ if ((n & m) == 0L) // power of two
+ r = (r & m) + origin;
+ else if (n > 0L) { // reject over-represented candidates
+ for (long u = r >>> 1; // ensure nonnegative
+ u + m - (r = u % n) < 0L; // rejection check
+ u = random.nextLong() >>> 1) // retry
+ ;
+ r += origin;
+ }
+ else { // range not representable as long
+ while (r < origin || r >= bound)
+ r = random.nextLong();
+ }
+ return r;
+ }
}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_search_24.xml b/app/src/main/res/drawable/ic_search_24.xml
new file mode 100644
index 00000000..07b76d62
--- /dev/null
+++ b/app/src/main/res/drawable/ic_search_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_comments.xml b/app/src/main/res/layout/activity_comments.xml
deleted file mode 100755
index 3006fc23..00000000
--- a/app/src/main/res/layout/activity_comments.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index c02f7c58..2966a155 100755
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -17,6 +17,7 @@
app:layout_constraintTop_toTopOf="parent">
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_comment.xml b/app/src/main/res/layout/item_comment.xml
index 064a50bc..c1bff83f 100755
--- a/app/src/main/res/layout/item_comment.xml
+++ b/app/src/main/res/layout/item_comment.xml
@@ -15,8 +15,8 @@
android:id="@+id/rvChildComments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginStart="80dp"
- android:layout_marginLeft="80dp"
+ android:layout_marginStart="40dp"
+ android:layout_marginLeft="40dp"
app:layoutManager="LinearLayoutManager"
tools:itemCount="5"
tools:listitem="@layout/item_comment_small" />
@@ -25,6 +25,8 @@
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="bottom"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="4dp"
android:layout_marginBottom="4dp"
- android:background="#80888888" />
+ android:background="#32888888" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_comment_small.xml b/app/src/main/res/layout/item_comment_small.xml
index eff11707..69c07980 100755
--- a/app/src/main/res/layout/item_comment_small.xml
+++ b/app/src/main/res/layout/item_comment_small.xml
@@ -23,34 +23,35 @@
android:paddingLeft="4dp"
android:paddingRight="4dp">
-
+ app:actualImageScaleType="centerCrop"
+ app:roundAsCircle="true" />
-
+
+
-
+ android:textAppearance="@style/TextAppearance.AppCompat.Small"
+ android:textSize="12sp" />
+
+
diff --git a/app/src/main/res/layout/item_post.xml b/app/src/main/res/layout/item_post.xml
index 3888f32b..077c3666 100755
--- a/app/src/main/res/layout/item_post.xml
+++ b/app/src/main/res/layout/item_post.xml
@@ -9,7 +9,7 @@
android:id="@+id/postImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- app:actualImageScaleType="fitCenter"
+ app:actualImageScaleType="centerCrop"
app:viewAspectRatio="1"/>
+ android:orientation="vertical"
+ android:padding="8dp">
diff --git a/app/src/main/res/menu/menu.xml b/app/src/main/res/menu/menu.xml
index bdc259b8..a760f439 100755
--- a/app/src/main/res/menu/menu.xml
+++ b/app/src/main/res/menu/menu.xml
@@ -55,7 +55,7 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/navigation/discover_nav_graph.xml b/app/src/main/res/navigation/discover_nav_graph.xml
index f75fd475..a80ecb70 100644
--- a/app/src/main/res/navigation/discover_nav_graph.xml
+++ b/app/src/main/res/navigation/discover_nav_graph.xml
@@ -7,6 +7,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+