mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-18 12:47:30 +00:00
Convert comment viewer activity to fragment and update layouts
This commit is contained in:
parent
7807fe7f59
commit
c64ae3a101
@ -141,14 +141,14 @@
|
|||||||
<!-- android:value=".activities.MainActivity" />-->
|
<!-- android:value=".activities.MainActivity" />-->
|
||||||
<!--</activity>-->
|
<!--</activity>-->
|
||||||
|
|
||||||
<activity
|
<!--<activity-->
|
||||||
android:name=".activities.CommentsViewer"
|
<!-- android:name=".activities.CommentsViewerFragment"-->
|
||||||
android:parentActivityName=".activities.PostViewer">
|
<!-- android:parentActivityName=".activities.PostViewer">-->
|
||||||
|
|
||||||
<meta-data
|
<!-- <meta-data-->
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
<!-- android:name="android.support.PARENT_ACTIVITY"-->
|
||||||
android:value=".activities.PostViewer" />
|
<!-- android:value=".activities.PostViewer" />-->
|
||||||
</activity>
|
<!--</activity>-->
|
||||||
|
|
||||||
<!--<activity-->
|
<!--<activity-->
|
||||||
<!-- android:name=".activities.StoryViewer"-->
|
<!-- android:name=".activities.StoryViewer"-->
|
||||||
|
@ -49,7 +49,7 @@ import java.util.Collections;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import awais.instagrabber.activities.CommentsViewer;
|
import awais.instagrabber.activities.CommentsViewerFragment;
|
||||||
import awais.instagrabber.activities.FollowViewer;
|
import awais.instagrabber.activities.FollowViewer;
|
||||||
import awais.instagrabber.activities.MainActivityBackup;
|
import awais.instagrabber.activities.MainActivityBackup;
|
||||||
import awais.instagrabber.activities.PostViewer;
|
import awais.instagrabber.activities.PostViewer;
|
||||||
@ -604,7 +604,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
|
|||||||
final int id = v.getId();
|
final int id = v.getId();
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case R.id.btnComments:
|
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_SHORTCODE, feedModel.getShortCode())
|
||||||
.putExtra(Constants.EXTRAS_POST, feedModel.getPostId())
|
.putExtra(Constants.EXTRAS_POST, feedModel.getPostId())
|
||||||
.putExtra(Constants.EXTRAS_USER, feedModel.getProfileModel().getId()), 6969);
|
.putExtra(Constants.EXTRAS_USER, feedModel.getProfileModel().getId()), 6969);
|
||||||
|
@ -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<String> 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<CommentModel[]>() {
|
|
||||||
@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<CommentModel[]>() {
|
|
||||||
@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<String, Void, Void> {
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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<Boolean>() {
|
||||||
|
@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<Boolean>() {
|
||||||
|
@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<Boolean>() {
|
||||||
|
@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<Boolean>() {
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@ import awais.instagrabber.fragments.directmessages.DirectMessageThreadFragmentAr
|
|||||||
import awais.instagrabber.utils.Constants;
|
import awais.instagrabber.utils.Constants;
|
||||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public class DirectMessagesActivity extends BaseLanguageActivity implements NavController.OnDestinationChangedListener {
|
public class DirectMessagesActivity extends BaseLanguageActivity implements NavController.OnDestinationChangedListener {
|
||||||
|
|
||||||
private TextView toolbarTitle;
|
private TextView toolbarTitle;
|
||||||
|
@ -14,9 +14,11 @@ import androidx.navigation.NavController;
|
|||||||
import androidx.navigation.ui.NavigationUI;
|
import androidx.navigation.ui.NavigationUI;
|
||||||
|
|
||||||
import com.google.android.material.appbar.AppBarLayout;
|
import com.google.android.material.appbar.AppBarLayout;
|
||||||
|
import com.google.android.material.appbar.CollapsingToolbarLayout;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import awais.instagrabber.R;
|
import awais.instagrabber.R;
|
||||||
@ -46,7 +48,9 @@ public class MainActivity extends BaseLanguageActivity {
|
|||||||
R.id.settingsPreferencesFragment,
|
R.id.settingsPreferencesFragment,
|
||||||
R.id.hashTagFragment,
|
R.id.hashTagFragment,
|
||||||
R.id.locationFragment,
|
R.id.locationFragment,
|
||||||
R.id.savedViewerFragment);
|
R.id.savedViewerFragment,
|
||||||
|
R.id.commentsViewerFragment);
|
||||||
|
private static final List<Integer> REMOVE_COLLAPSING_TOOLBAR_SCROLL_DESTINATIONS = Collections.singletonList(R.id.commentsViewerFragment);
|
||||||
private ActivityMainBinding binding;
|
private ActivityMainBinding binding;
|
||||||
private LiveData<NavController> currentNavControllerLiveData;
|
private LiveData<NavController> currentNavControllerLiveData;
|
||||||
|
|
||||||
@ -110,6 +114,11 @@ public class MainActivity extends BaseLanguageActivity {
|
|||||||
} else {
|
} else {
|
||||||
removeScrollingBehaviour();
|
removeScrollingBehaviour();
|
||||||
}
|
}
|
||||||
|
if (REMOVE_COLLAPSING_TOOLBAR_SCROLL_DESTINATIONS.contains(destinationId)) {
|
||||||
|
removeCollapsingToolbarScrollFlags();
|
||||||
|
} else {
|
||||||
|
setCollapsingToolbarScrollFlags();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,6 +134,22 @@ public class MainActivity extends BaseLanguageActivity {
|
|||||||
binding.mainNavHost.requestLayout();
|
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
|
@Override
|
||||||
protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) {
|
protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) {
|
||||||
super.onRestoreInstanceState(savedInstanceState);
|
super.onRestoreInstanceState(savedInstanceState);
|
||||||
|
@ -221,7 +221,7 @@ public final class PostViewer extends BaseLanguageActivity {
|
|||||||
viewerBinding.bottomPanel.btnComments.setVisibility(View.VISIBLE);
|
viewerBinding.bottomPanel.btnComments.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
viewerBinding.bottomPanel.btnComments.setOnClickListener(v -> startActivityForResult(
|
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_SHORTCODE, postModel.getShortCode())
|
||||||
.putExtra(Constants.EXTRAS_POST, viewerPostModel.getPostId())
|
.putExtra(Constants.EXTRAS_POST, viewerPostModel.getPostId())
|
||||||
.putExtra(Constants.EXTRAS_USER, postUserId),
|
.putExtra(Constants.EXTRAS_USER, postUserId),
|
||||||
|
@ -72,6 +72,7 @@ import awaisomereport.LogCollector;
|
|||||||
import static awais.instagrabber.utils.Constants.AUTOLOAD_POSTS;
|
import static awais.instagrabber.utils.Constants.AUTOLOAD_POSTS;
|
||||||
import static awais.instagrabber.utils.Utils.logCollector;
|
import static awais.instagrabber.utils.Utils.logCollector;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final class ProfileViewer extends BaseLanguageActivity implements SwipeRefreshLayout.OnRefreshListener {
|
public final class ProfileViewer extends BaseLanguageActivity implements SwipeRefreshLayout.OnRefreshListener {
|
||||||
private final ArrayList<PostModel> allItems = new ArrayList<>(), selectedItems = new ArrayList<>();
|
private final ArrayList<PostModel> allItems = new ArrayList<>(), selectedItems = new ArrayList<>();
|
||||||
private static AsyncTask<?, ?, ?> currentlyExecuting;
|
private static AsyncTask<?, ?, ?> currentlyExecuting;
|
||||||
|
@ -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;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
@ -10,9 +10,6 @@ import android.widget.Filterable;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import awais.instagrabber.R;
|
import awais.instagrabber.R;
|
||||||
@ -24,7 +21,15 @@ import awais.instagrabber.utils.LocaleUtils;
|
|||||||
import awais.instagrabber.utils.Utils;
|
import awais.instagrabber.utils.Utils;
|
||||||
|
|
||||||
public final class CommentsAdapter extends RecyclerView.Adapter<CommentViewHolder> implements Filterable {
|
public final class CommentsAdapter extends RecyclerView.Adapter<CommentViewHolder> implements Filterable {
|
||||||
|
|
||||||
|
private CommentModel[] filteredCommentModels;
|
||||||
|
private LayoutInflater layoutInflater;
|
||||||
|
|
||||||
private final boolean isParent;
|
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() {
|
private final Filter filter = new Filter() {
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
@ -66,14 +71,10 @@ public final class CommentsAdapter extends RecyclerView.Adapter<CommentViewHolde
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private final View.OnClickListener onClickListener;
|
|
||||||
private final MentionClickListener mentionClickListener;
|
|
||||||
private final CommentModel[] commentModels;
|
|
||||||
private final String[] quantityStrings = new String[2];
|
|
||||||
private LayoutInflater layoutInflater;
|
|
||||||
private CommentModel[] filteredCommentModels;
|
|
||||||
|
|
||||||
public CommentsAdapter(final CommentModel[] commentModels, final boolean isParent, final View.OnClickListener onClickListener,
|
public CommentsAdapter(final CommentModel[] commentModels,
|
||||||
|
final boolean isParent,
|
||||||
|
final View.OnClickListener onClickListener,
|
||||||
final MentionClickListener mentionClickListener) {
|
final MentionClickListener mentionClickListener) {
|
||||||
this.commentModels = this.filteredCommentModels = commentModels;
|
this.commentModels = this.filteredCommentModels = commentModels;
|
||||||
this.isParent = isParent;
|
this.isParent = isParent;
|
||||||
@ -93,10 +94,13 @@ public final class CommentsAdapter extends RecyclerView.Adapter<CommentViewHolde
|
|||||||
if (quantityStrings[0] == null) quantityStrings[0] = context.getString(R.string.single_like);
|
if (quantityStrings[0] == null) quantityStrings[0] = context.getString(R.string.single_like);
|
||||||
if (quantityStrings[1] == null) quantityStrings[1] = context.getString(R.string.multiple_likes);
|
if (quantityStrings[1] == null) quantityStrings[1] = context.getString(R.string.multiple_likes);
|
||||||
if (layoutInflater == null) layoutInflater = LayoutInflater.from(context);
|
if (layoutInflater == null) layoutInflater = LayoutInflater.from(context);
|
||||||
return new CommentViewHolder(layoutInflater.inflate(
|
final View view = layoutInflater.inflate(isParent ? R.layout.item_comment
|
||||||
isParent ? R.layout.item_comment // parent
|
: R.layout.item_comment_small,
|
||||||
: R.layout.item_comment_small, // child
|
parent,
|
||||||
parent, false), onClickListener, mentionClickListener);
|
false);
|
||||||
|
return new CommentViewHolder(view,
|
||||||
|
onClickListener,
|
||||||
|
mentionClickListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -105,7 +109,7 @@ public final class CommentsAdapter extends RecyclerView.Adapter<CommentViewHolde
|
|||||||
if (commentModel != null) {
|
if (commentModel != null) {
|
||||||
holder.setCommentModel(commentModel);
|
holder.setCommentModel(commentModel);
|
||||||
|
|
||||||
holder.setCommment(commentModel.getText());
|
holder.setComment(commentModel.getText());
|
||||||
holder.setDate(commentModel.getDateTime());
|
holder.setDate(commentModel.getDateTime());
|
||||||
holder.setLiked(commentModel.getLiked());
|
holder.setLiked(commentModel.getLiked());
|
||||||
|
|
||||||
@ -115,12 +119,8 @@ public final class CommentsAdapter extends RecyclerView.Adapter<CommentViewHolde
|
|||||||
final ProfileModel profileModel = commentModel.getProfileModel();
|
final ProfileModel profileModel = commentModel.getProfileModel();
|
||||||
if (profileModel != null) {
|
if (profileModel != null) {
|
||||||
holder.setUsername(profileModel.getUsername());
|
holder.setUsername(profileModel.getUsername());
|
||||||
|
holder.getProfilePicView().setImageURI(profileModel.getSdProfilePic());
|
||||||
Glide.with(layoutInflater.getContext())
|
|
||||||
.applyDefaultRequestOptions(new RequestOptions().skipMemoryCache(true))
|
|
||||||
.load(profileModel.getSdProfilePic()).into(holder.getProfilePicView());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (holder.isParent()) {
|
if (holder.isParent()) {
|
||||||
final CommentModel[] childCommentModels = commentModel.getChildCommentModels();
|
final CommentModel[] childCommentModels = commentModel.getChildCommentModels();
|
||||||
if (childCommentModels != null && childCommentModels.length > 0)
|
if (childCommentModels != null && childCommentModels.length > 0)
|
||||||
|
@ -2,12 +2,13 @@ package awais.instagrabber.adapters.viewholder;
|
|||||||
|
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.facebook.drawee.view.SimpleDraweeView;
|
||||||
|
|
||||||
import awais.instagrabber.R;
|
import awais.instagrabber.R;
|
||||||
import awais.instagrabber.adapters.CommentsAdapter;
|
import awais.instagrabber.adapters.CommentsAdapter;
|
||||||
import awais.instagrabber.customviews.RamboTextView;
|
import awais.instagrabber.customviews.RamboTextView;
|
||||||
@ -17,11 +18,16 @@ import awais.instagrabber.models.CommentModel;
|
|||||||
public final class CommentViewHolder extends RecyclerView.ViewHolder {
|
public final class CommentViewHolder extends RecyclerView.ViewHolder {
|
||||||
private final MentionClickListener mentionClickListener;
|
private final MentionClickListener mentionClickListener;
|
||||||
private final RecyclerView rvChildComments;
|
private final RecyclerView rvChildComments;
|
||||||
private final ImageView ivProfilePic;
|
private final SimpleDraweeView ivProfilePic;
|
||||||
private final TextView tvUsername, tvDate, tvComment, tvLikes;
|
private final TextView tvUsername;
|
||||||
|
private final TextView tvDate;
|
||||||
|
private final TextView tvComment;
|
||||||
|
private final TextView tvLikes;
|
||||||
private final View container;
|
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);
|
super(itemView);
|
||||||
|
|
||||||
container = itemView.findViewById(R.id.container);
|
container = itemView.findViewById(R.id.container);
|
||||||
@ -41,7 +47,7 @@ public final class CommentViewHolder extends RecyclerView.ViewHolder {
|
|||||||
rvChildComments = itemView.findViewById(R.id.rvChildComments);
|
rvChildComments = itemView.findViewById(R.id.rvChildComments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final ImageView getProfilePicView() {
|
public final SimpleDraweeView getProfilePicView() {
|
||||||
return ivProfilePic;
|
return ivProfilePic;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,9 +75,9 @@ public final class CommentViewHolder extends RecyclerView.ViewHolder {
|
|||||||
if (liked) container.setBackgroundColor(0x40FF69B4);
|
if (liked) container.setBackgroundColor(0x40FF69B4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void setCommment(final CharSequence commment) {
|
public final void setComment(final CharSequence comment) {
|
||||||
if (tvComment != null) {
|
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);
|
((RamboTextView) tvComment).setMentionClickListener(mentionClickListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ import java.net.URL;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import awais.instagrabber.models.ImageUploadOptions;
|
import awais.instagrabber.models.ImageUploadOptions;
|
||||||
@ -52,7 +51,7 @@ public class ImageUploader extends AsyncTask<ImageUploadOptions, Void, ImageUplo
|
|||||||
final String contentLength = String.valueOf(bytes.length);
|
final String contentLength = String.valueOf(bytes.length);
|
||||||
final Map<String, String> headers = new HashMap<>();
|
final Map<String, String> headers = new HashMap<>();
|
||||||
final String uploadId = String.valueOf(new Date().getTime());
|
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 name = String.format("%s_0_%s", uploadId, random);
|
||||||
final String waterfallId = options.getWaterfallId() != null ? options.getWaterfallId() : UUID.randomUUID().toString();
|
final String waterfallId = options.getWaterfallId() != null ? options.getWaterfallId() : UUID.randomUUID().toString();
|
||||||
headers.put("X-Entity-Type", "image/jpeg");
|
headers.put("X-Entity-Type", "image/jpeg");
|
||||||
|
@ -65,7 +65,7 @@ public final class iPostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
|
|||||||
user.optBoolean("is_private"),
|
user.optBoolean("is_private"),
|
||||||
user.optBoolean("is_private"),
|
user.optBoolean("is_private"),
|
||||||
user.optBoolean("is_verified"),
|
user.optBoolean("is_verified"),
|
||||||
null,
|
user.optString("pk"),
|
||||||
user.getString(Constants.EXTRAS_USERNAME),
|
user.getString(Constants.EXTRAS_USERNAME),
|
||||||
user.optString("fullname"),
|
user.optString("fullname"),
|
||||||
null,
|
null,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package awais.instagrabber.fragments;
|
package awais.instagrabber.fragments;
|
||||||
|
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -26,7 +25,6 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import awais.instagrabber.R;
|
import awais.instagrabber.R;
|
||||||
import awais.instagrabber.activities.CommentsViewer;
|
|
||||||
import awais.instagrabber.adapters.PostViewAdapter;
|
import awais.instagrabber.adapters.PostViewAdapter;
|
||||||
import awais.instagrabber.adapters.PostViewAdapter.OnPostViewChildViewClickListener;
|
import awais.instagrabber.adapters.PostViewAdapter.OnPostViewChildViewClickListener;
|
||||||
import awais.instagrabber.asyncs.PostFetcher;
|
import awais.instagrabber.asyncs.PostFetcher;
|
||||||
@ -114,12 +112,18 @@ public class PostViewFragment extends Fragment {
|
|||||||
case R.id.viewerCaption:
|
case R.id.viewerCaption:
|
||||||
break;
|
break;
|
||||||
case R.id.btnComments:
|
case R.id.btnComments:
|
||||||
startActivity(new Intent(requireContext(), CommentsViewer.class)
|
// startActivity(new Intent(requireContext(), CommentsViewerFragment.class)
|
||||||
.putExtra(Constants.EXTRAS_SHORTCODE,
|
// .putExtra(Constants.EXTRAS_SHORTCODE, postModel.getShortCode())
|
||||||
postModel.getShortCode())
|
// .putExtra(Constants.EXTRAS_POST, postModel.getPostId())
|
||||||
.putExtra(Constants.EXTRAS_POST, postModel.getPostId())
|
// .putExtra(Constants.EXTRAS_USER, Utils.getUserIdFromCookie(COOKIE)));
|
||||||
.putExtra(Constants.EXTRAS_USER,
|
String postId = postModel.getPostId();
|
||||||
Utils.getUserIdFromCookie(COOKIE)));
|
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;
|
break;
|
||||||
case R.id.btnDownload:
|
case R.id.btnDownload:
|
||||||
if (checkSelfPermission(requireContext(),
|
if (checkSelfPermission(requireContext(),
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package awais.instagrabber.fragments.main;
|
package awais.instagrabber.fragments.main;
|
||||||
|
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -35,7 +34,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import awais.instagrabber.R;
|
import awais.instagrabber.R;
|
||||||
import awais.instagrabber.activities.CommentsViewer;
|
|
||||||
import awais.instagrabber.activities.MainActivity;
|
import awais.instagrabber.activities.MainActivity;
|
||||||
import awais.instagrabber.adapters.FeedAdapter;
|
import awais.instagrabber.adapters.FeedAdapter;
|
||||||
import awais.instagrabber.adapters.FeedStoriesAdapter;
|
import awais.instagrabber.adapters.FeedStoriesAdapter;
|
||||||
@ -187,17 +185,14 @@ public class FeedFragment extends Fragment {
|
|||||||
final int id = v.getId();
|
final int id = v.getId();
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case R.id.btnComments:
|
case R.id.btnComments:
|
||||||
startActivity(new Intent(requireContext(), CommentsViewer.class)
|
final NavDirections commentsAction = FeedFragmentDirections.actionGlobalCommentsViewerFragment(
|
||||||
.putExtra(Constants.EXTRAS_SHORTCODE, feedModel.getShortCode())
|
feedModel.getShortCode(),
|
||||||
.putExtra(Constants.EXTRAS_POST, feedModel.getPostId())
|
feedModel.getPostId(),
|
||||||
.putExtra(Constants.EXTRAS_USER, feedModel.getProfileModel().getId()));
|
feedModel.getProfileModel().getId()
|
||||||
|
);
|
||||||
|
NavHostFragment.findNavController(this).navigate(commentsAction);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R.id.viewStoryPost:
|
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<FeedModel> feedModels = feedViewModel.getList().getValue();
|
final List<FeedModel> feedModels = feedViewModel.getList().getValue();
|
||||||
if (feedModels == null || feedModels.size() == 0) return;
|
if (feedModels == null || feedModels.size() == 0) return;
|
||||||
if (feedModels.get(0) == null) return;
|
if (feedModels.get(0) == null) return;
|
||||||
@ -296,11 +291,9 @@ public class FeedFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
|
||||||
if (!shouldRefresh) return;
|
if (!shouldRefresh) return;
|
||||||
// setupActionBar();
|
|
||||||
setupFeedStories();
|
setupFeedStories();
|
||||||
setupFeed();
|
setupFeed();
|
||||||
shouldRefresh = false;
|
shouldRefresh = false;
|
||||||
// feedService.getFeed(11, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -456,16 +456,14 @@ public class ProfileFragment extends Fragment {
|
|||||||
binding.mainFollowers.setClickable(true);
|
binding.mainFollowers.setClickable(true);
|
||||||
|
|
||||||
if (isLoggedIn) {
|
if (isLoggedIn) {
|
||||||
final View.OnClickListener followClickListener = v -> startActivity(new Intent(
|
final View.OnClickListener followClickListener = v -> startActivity(
|
||||||
requireContext(),
|
new Intent(requireContext(), FollowViewer.class)
|
||||||
FollowViewer.class).putExtra(Constants.EXTRAS_FOLLOWERS, v == binding.mainFollowers)
|
.putExtra(Constants.EXTRAS_FOLLOWERS, v == binding.mainFollowers)
|
||||||
.putExtra(Constants.EXTRAS_NAME, profileModel.getUsername())
|
.putExtra(Constants.EXTRAS_NAME, profileModel.getUsername())
|
||||||
.putExtra(Constants.EXTRAS_ID, profileId));
|
.putExtra(Constants.EXTRAS_ID, profileId));
|
||||||
|
|
||||||
binding.mainFollowers
|
binding.mainFollowers.setOnClickListener(followersCount > 0 ? followClickListener : null);
|
||||||
.setOnClickListener(followersCount > 0 ? followClickListener : null);
|
binding.mainFollowing.setOnClickListener(followingCount > 0 ? followClickListener : null);
|
||||||
binding.mainFollowing
|
|
||||||
.setOnClickListener(followingCount > 0 ? followClickListener : null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profileModel.getPostCount() == 0) {
|
if (profileModel.getPostCount() == 0) {
|
||||||
|
@ -13,8 +13,32 @@ public interface MediaRepository {
|
|||||||
|
|
||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
@POST("/api/v1/media/{mediaId}/{action}/")
|
@POST("/api/v1/media/{mediaId}/{action}/")
|
||||||
Call<String> likeAction(@Header("User-Agent") final String userAgent,
|
Call<String> action(@Header("User-Agent") final String userAgent,
|
||||||
@Path("action") final String action,
|
@Path("action") final String action,
|
||||||
@Path("mediaId") final String mediaId,
|
@Path("mediaId") final String mediaId,
|
||||||
@FieldMap final Map<String, String> signedForm);
|
@FieldMap final Map<String, String> signedForm);
|
||||||
|
|
||||||
|
@FormUrlEncoded
|
||||||
|
@POST("/api/v1/media/{mediaId}/comment/")
|
||||||
|
Call<String> comment(@Header("User-Agent") final String userAgent,
|
||||||
|
@Path("mediaId") final String mediaId,
|
||||||
|
@FieldMap final Map<String, String> signedForm);
|
||||||
|
|
||||||
|
@FormUrlEncoded
|
||||||
|
@POST("/api/v1/media/{mediaId}/comment/bulk_delete/")
|
||||||
|
Call<String> commentsBulkDelete(@Header("User-Agent") final String userAgent,
|
||||||
|
@Path("mediaId") final String mediaId,
|
||||||
|
@FieldMap final Map<String, String> signedForm);
|
||||||
|
|
||||||
|
@FormUrlEncoded
|
||||||
|
@POST("/api/v1/media/{commentId}/comment_like/")
|
||||||
|
Call<String> commentLike(@Header("User-Agent") final String userAgent,
|
||||||
|
@Path("commentId") final String commentId,
|
||||||
|
@FieldMap final Map<String, String> signedForm);
|
||||||
|
|
||||||
|
@FormUrlEncoded
|
||||||
|
@POST("/api/v1/media/{commentId}/comment_unlike/")
|
||||||
|
Call<String> commentUnlike(@Header("User-Agent") final String userAgent,
|
||||||
|
@Path("commentId") final String commentId,
|
||||||
|
@FieldMap final Map<String, String> signedForm);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import retrofit2.converter.gson.GsonConverterFactory;
|
|||||||
import retrofit2.converter.scalars.ScalarsConverterFactory;
|
import retrofit2.converter.scalars.ScalarsConverterFactory;
|
||||||
|
|
||||||
public abstract class BaseService {
|
public abstract class BaseService {
|
||||||
|
private static final String TAG = "BaseService";
|
||||||
|
|
||||||
private Retrofit.Builder builder;
|
private Retrofit.Builder builder;
|
||||||
|
|
||||||
@ -33,4 +34,29 @@ public abstract class BaseService {
|
|||||||
}
|
}
|
||||||
return builder;
|
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;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ class LoggingInterceptor implements Interceptor {
|
|||||||
Request request = chain.request();
|
Request request = chain.request();
|
||||||
long t1 = System.nanoTime();
|
long t1 = System.nanoTime();
|
||||||
Log.i(TAG, String.format("Sending request %s on %s%n%s",
|
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);
|
Response response = chain.proceed(request);
|
||||||
long t2 = System.nanoTime();
|
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()));
|
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);
|
Log.d("OkHttp", content);
|
||||||
|
|
||||||
ResponseBody wrappedBody = ResponseBody.create(contentType, content);
|
ResponseBody wrappedBody = ResponseBody.create(contentType, content);
|
||||||
return response.newBuilder().body(wrappedBody).build();
|
return response.newBuilder()
|
||||||
|
.body(wrappedBody)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
package awais.instagrabber.services;
|
package awais.instagrabber.services;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -42,35 +47,35 @@ public class MediaService extends BaseService {
|
|||||||
final String userId,
|
final String userId,
|
||||||
final String csrfToken,
|
final String csrfToken,
|
||||||
final ServiceCallback<Boolean> callback) {
|
final ServiceCallback<Boolean> callback) {
|
||||||
likeAction(mediaId, userId, "like", csrfToken, callback);
|
action(mediaId, userId, "like", csrfToken, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unlike(final String mediaId,
|
public void unlike(final String mediaId,
|
||||||
final String userId,
|
final String userId,
|
||||||
final String csrfToken,
|
final String csrfToken,
|
||||||
final ServiceCallback<Boolean> callback) {
|
final ServiceCallback<Boolean> callback) {
|
||||||
likeAction(mediaId, userId, "unlike", csrfToken, callback);
|
action(mediaId, userId, "unlike", csrfToken, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(final String mediaId,
|
public void save(final String mediaId,
|
||||||
final String userId,
|
final String userId,
|
||||||
final String csrfToken,
|
final String csrfToken,
|
||||||
final ServiceCallback<Boolean> callback) {
|
final ServiceCallback<Boolean> callback) {
|
||||||
likeAction(mediaId, userId, "save", csrfToken, callback);
|
action(mediaId, userId, "save", csrfToken, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unsave(final String mediaId,
|
public void unsave(final String mediaId,
|
||||||
final String userId,
|
final String userId,
|
||||||
final String csrfToken,
|
final String csrfToken,
|
||||||
final ServiceCallback<Boolean> callback) {
|
final ServiceCallback<Boolean> callback) {
|
||||||
likeAction(mediaId, userId, "unsave", csrfToken, callback);
|
action(mediaId, userId, "unsave", csrfToken, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void likeAction(final String mediaId,
|
private void action(final String mediaId,
|
||||||
final String userId,
|
final String userId,
|
||||||
final String action,
|
final String action,
|
||||||
final String csrfToken,
|
final String csrfToken,
|
||||||
final ServiceCallback<Boolean> callback) {
|
final ServiceCallback<Boolean> callback) {
|
||||||
final Map<String, Object> form = new HashMap<>(4);
|
final Map<String, Object> form = new HashMap<>(4);
|
||||||
form.put("media_id", mediaId);
|
form.put("media_id", mediaId);
|
||||||
form.put("_csrftoken", csrfToken);
|
form.put("_csrftoken", csrfToken);
|
||||||
@ -78,7 +83,7 @@ public class MediaService extends BaseService {
|
|||||||
form.put("_uuid", UUID.randomUUID().toString());
|
form.put("_uuid", UUID.randomUUID().toString());
|
||||||
// form.put("radio_type", "wifi-none");
|
// form.put("radio_type", "wifi-none");
|
||||||
final Map<String, String> signedForm = Utils.sign(form);
|
final Map<String, String> signedForm = Utils.sign(form);
|
||||||
final Call<String> request = repository.likeAction(Constants.I_USER_AGENT, action, mediaId, signedForm);
|
final Call<String> request = repository.action(Constants.I_USER_AGENT, action, mediaId, signedForm);
|
||||||
request.enqueue(new Callback<String>() {
|
request.enqueue(new Callback<String>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(@NonNull final Call<String> call,
|
public void onResponse(@NonNull final Call<String> 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<Boolean> callback) {
|
||||||
|
final String module = "self_comments_v2";
|
||||||
|
final Map<String, Object> 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<String, String> signedForm = Utils.sign(form);
|
||||||
|
final Call<String> commentRequest = repository.comment(Constants.I_USER_AGENT, mediaId, signedForm);
|
||||||
|
commentRequest.enqueue(new Callback<String>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> 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<String> 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<Boolean> callback) {
|
||||||
|
deleteComments(mediaId, userId, Collections.singletonList(commentId), csrfToken, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteComments(final String mediaId,
|
||||||
|
final String userId,
|
||||||
|
final List<String> commentIds,
|
||||||
|
final String csrfToken,
|
||||||
|
@NonNull final ServiceCallback<Boolean> callback) {
|
||||||
|
final Map<String, Object> 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<String, String> signedForm = Utils.sign(form);
|
||||||
|
final Call<String> bulkDeleteRequest = repository.commentsBulkDelete(Constants.USER_AGENT, mediaId, signedForm);
|
||||||
|
bulkDeleteRequest.enqueue(new Callback<String>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> 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<String> 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<Boolean> callback) {
|
||||||
|
final Map<String, Object> form = new HashMap<>();
|
||||||
|
form.put("_csrftoken", csrfToken);
|
||||||
|
// form.put("_uid", userId);
|
||||||
|
// form.put("_uuid", UUID.randomUUID().toString());
|
||||||
|
final Map<String, String> signedForm = Utils.sign(form);
|
||||||
|
final Call<String> commentLikeRequest = repository.commentLike(Constants.USER_AGENT, commentId, signedForm);
|
||||||
|
commentLikeRequest.enqueue(new Callback<String>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> 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<String> 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<Boolean> callback) {
|
||||||
|
final Map<String, Object> form = new HashMap<>();
|
||||||
|
form.put("_csrftoken", csrfToken);
|
||||||
|
// form.put("_uid", userId);
|
||||||
|
// form.put("_uuid", UUID.randomUUID().toString());
|
||||||
|
final Map<String, String> signedForm = Utils.sign(form);
|
||||||
|
final Call<String> commentUnlikeRequest = repository.commentUnlike(Constants.USER_AGENT, commentId, signedForm);
|
||||||
|
commentUnlikeRequest.enqueue(new Callback<String>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> 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<String> call, @NonNull final Throwable t) {
|
||||||
|
Log.e(TAG, "Error unliking comment", t);
|
||||||
|
callback.onFailure(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,5 +66,6 @@ public final class Constants {
|
|||||||
"\"gyroscope\", \"value\": \"gyroscope_enabled\" } ]";
|
"\"gyroscope\", \"value\": \"gyroscope_enabled\" } ]";
|
||||||
public static final String SIGNATURE_VERSION = "4";
|
public static final String SIGNATURE_VERSION = "4";
|
||||||
public static final String SIGNATURE_KEY = "9193488027538fd3450b83b7d05286d4ca9599a0f7eeed90d8c85925698a05dc";
|
public static final String SIGNATURE_KEY = "9193488027538fd3450b83b7d05286d4ca9599a0f7eeed90d8c85925698a05dc";
|
||||||
|
public static final String BREADCRUMB_KEY = "iN4$aGr0m";
|
||||||
public static final int LOGIN_RESULT_CODE = 5000;
|
public static final int LOGIN_RESULT_CODE = 5000;
|
||||||
}
|
}
|
@ -63,6 +63,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@ -1220,9 +1221,13 @@ public final class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String sign(final String message) {
|
public static String sign(final String message) {
|
||||||
|
return sign(Constants.SIGNATURE_KEY, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String sign(final String key, final String message) {
|
||||||
try {
|
try {
|
||||||
final Mac hasher = Mac.getInstance("HmacSHA256");
|
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());
|
byte[] hash = hasher.doFinal(message.getBytes());
|
||||||
final StringBuilder hexString = new StringBuilder();
|
final StringBuilder hexString = new StringBuilder();
|
||||||
for (byte b : hash) {
|
for (byte b : hash) {
|
||||||
@ -1458,4 +1463,29 @@ public final class Utils {
|
|||||||
}
|
}
|
||||||
return cookie.split("csrftoken=")[1].split(";")[0];
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
10
app/src/main/res/drawable/ic_search_24.xml
Normal file
10
app/src/main/res/drawable/ic_search_24.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
|
||||||
|
</vector>
|
@ -1,70 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
tools:context=".activities.CommentsViewer">
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_weight="1"
|
|
||||||
layout="@layout/layout_include_toolbar" />
|
|
||||||
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
|
||||||
android:id="@+id/swipeRefreshLayout"
|
|
||||||
android:layout_weight="8"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/rvComments"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:clipToPadding="false"
|
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingLeft="8dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:paddingRight="8dp"
|
|
||||||
app:layoutManager="LinearLayoutManager"
|
|
||||||
tools:listitem="@layout/item_comment" />
|
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
|
||||||
|
|
||||||
<LinearLayout android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/commentCancelParent"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="?selectableItemBackgroundBorderless"
|
|
||||||
android:clickable="true"
|
|
||||||
android:paddingRight="8dp"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:srcCompat="@android:drawable/ic_menu_revert" />
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/commentText"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="2"
|
|
||||||
android:paddingLeft="8dp"
|
|
||||||
android:gravity="bottom"
|
|
||||||
android:hint="@string/comment_hint"
|
|
||||||
android:inputType="textMultiLine"
|
|
||||||
android:maxLength="2200"
|
|
||||||
android:maxLines="10"
|
|
||||||
android:visibility="gone"
|
|
||||||
android:scrollHorizontally="false" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/commentSend"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="?selectableItemBackgroundBorderless"
|
|
||||||
android:clickable="true"
|
|
||||||
android:paddingRight="8dp"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:srcCompat="@android:drawable/ic_menu_send" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
@ -17,6 +17,7 @@
|
|||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||||
|
android:id="@+id/collapsingToolbarLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_scrollFlags="scroll|snap|enterAlways"
|
app:layout_scrollFlags="scroll|snap|enterAlways"
|
||||||
|
48
app/src/main/res/layout/fragment_comments.xml
Normal file
48
app/src/main/res/layout/fragment_comments.xml
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
android:id="@+id/swipeRefreshLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rvComments"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
app:layoutManager="LinearLayoutManager"
|
||||||
|
tools:listitem="@layout/item_comment" />
|
||||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/commentField"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="4dp"
|
||||||
|
android:hint="@string/comment_hint"
|
||||||
|
app:counterEnabled="true"
|
||||||
|
app:counterMaxLength="2200"
|
||||||
|
app:endIconDrawable="@drawable/ic_send_24"
|
||||||
|
app:endIconMode="custom"
|
||||||
|
app:startIconDrawable="@drawable/ic_close_24">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/commentText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:autofillHints="no"
|
||||||
|
android:inputType="textMultiLine"
|
||||||
|
android:maxLength="2200"
|
||||||
|
android:maxLines="10"
|
||||||
|
android:scrollHorizontally="false" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
</LinearLayout>
|
@ -15,8 +15,8 @@
|
|||||||
android:id="@+id/rvChildComments"
|
android:id="@+id/rvChildComments"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="80dp"
|
android:layout_marginStart="40dp"
|
||||||
android:layout_marginLeft="80dp"
|
android:layout_marginLeft="40dp"
|
||||||
app:layoutManager="LinearLayoutManager"
|
app:layoutManager="LinearLayoutManager"
|
||||||
tools:itemCount="5"
|
tools:itemCount="5"
|
||||||
tools:listitem="@layout/item_comment_small" />
|
tools:listitem="@layout/item_comment_small" />
|
||||||
@ -25,6 +25,8 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
android:layout_marginBottom="4dp"
|
android:layout_marginBottom="4dp"
|
||||||
android:background="#80888888" />
|
android:background="#32888888" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -23,34 +23,35 @@
|
|||||||
android:paddingLeft="4dp"
|
android:paddingLeft="4dp"
|
||||||
android:paddingRight="4dp">
|
android:paddingRight="4dp">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
android:id="@+id/ivProfilePic"
|
android:id="@+id/ivProfilePic"
|
||||||
android:layout_width="50dp"
|
android:layout_width="50dp"
|
||||||
android:layout_height="50dp"
|
android:layout_height="50dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
app:srcCompat="@mipmap/ic_launcher" />
|
app:actualImageScaleType="centerCrop"
|
||||||
|
app:roundAsCircle="true" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
android:id="@+id/tvUsername"
|
android:id="@+id/tvUsername"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
android:layout_weight="1.0"
|
android:layout_weight="1.0"
|
||||||
android:ellipsize="marquee"
|
android:ellipsize="marquee"
|
||||||
android:paddingStart="8dp"
|
android:paddingStart="8dp"
|
||||||
android:paddingLeft="8dp"
|
android:paddingLeft="8dp"
|
||||||
android:paddingTop="4dp"
|
android:paddingTop="4dp"
|
||||||
android:paddingEnd="4dp"
|
android:paddingEnd="4dp"
|
||||||
android:paddingRight="4dp"
|
android:paddingRight="4dp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat"
|
android:textAppearance="@style/TextAppearance.AppCompat"
|
||||||
android:textColor="?android:textColorPrimary"
|
android:textColor="?android:textColorPrimary"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
|
||||||
<awais.instagrabber.customviews.RamboTextView
|
<awais.instagrabber.customviews.RamboTextView
|
||||||
@ -68,31 +69,17 @@
|
|||||||
android:paddingRight="8dp"
|
android:paddingRight="8dp"
|
||||||
android:paddingBottom="8dp"
|
android:paddingBottom="8dp"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat" />
|
android:textAppearance="@style/TextAppearance.AppCompat" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:weightSum="3.5">
|
android:weightSum="3.5">
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
|
||||||
android:id="@+id/tvLikes"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:ellipsize="marquee"
|
|
||||||
android:paddingStart="4dp"
|
|
||||||
android:paddingLeft="4dp"
|
|
||||||
android:paddingTop="4dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:paddingRight="8dp"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
android:id="@+id/tvDate"
|
android:id="@+id/tvLikes"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="2.5"
|
android:layout_weight="1"
|
||||||
android:layout_gravity="start"
|
|
||||||
android:ellipsize="marquee"
|
android:ellipsize="marquee"
|
||||||
android:paddingStart="4dp"
|
android:paddingStart="4dp"
|
||||||
android:paddingLeft="4dp"
|
android:paddingLeft="4dp"
|
||||||
@ -100,8 +87,24 @@
|
|||||||
android:paddingEnd="8dp"
|
android:paddingEnd="8dp"
|
||||||
android:paddingRight="8dp"
|
android:paddingRight="8dp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textStyle="italic"
|
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||||
android:gravity="right"/>
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/tvDate"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="start"
|
||||||
|
android:layout_weight="2.5"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:gravity="end"
|
||||||
|
android:paddingStart="4dp"
|
||||||
|
android:paddingLeft="4dp"
|
||||||
|
android:paddingTop="4dp"
|
||||||
|
android:paddingEnd="8dp"
|
||||||
|
android:paddingRight="8dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textStyle="italic" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
android:id="@+id/postImage"
|
android:id="@+id/postImage"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:actualImageScaleType="fitCenter"
|
app:actualImageScaleType="centerCrop"
|
||||||
app:viewAspectRatio="1"/>
|
app:viewAspectRatio="1"/>
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
android:id="@+id/ivProfilePic"
|
android:id="@+id/ivProfilePic"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
app:actualImageScaleType="centerCrop"
|
||||||
app:roundAsCircle="true" />
|
app:roundAsCircle="true" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@ -52,8 +53,8 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:padding="8dp"
|
android:orientation="vertical"
|
||||||
android:orientation="vertical">
|
android:padding="8dp">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
android:id="@+id/tvUsername"
|
android:id="@+id/tvUsername"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<item
|
<item
|
||||||
android:id="@+id/action_search"
|
android:id="@+id/action_search"
|
||||||
android:actionLayout="@layout/layout_searchview"
|
android:actionLayout="@layout/layout_searchview"
|
||||||
android:icon="@android:drawable/ic_menu_search"
|
android:icon="@drawable/ic_search_24"
|
||||||
android:title="@string/action_search"
|
android:title="@string/action_search"
|
||||||
android:titleCondensed="@string/action_search"
|
android:titleCondensed="@string/action_search"
|
||||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||||
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_compare"
|
android:id="@+id/action_compare"
|
||||||
android:icon="@android:drawable/ic_menu_view"
|
android:icon="@drawable/ic_outline_views_24"
|
||||||
android:title="@string/action_compare"
|
android:title="@string/action_compare"
|
||||||
android:titleCondensed="@string/action_compare"
|
android:titleCondensed="@string/action_compare"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
<item
|
<item
|
||||||
android:id="@+id/action_search"
|
android:id="@+id/action_search"
|
||||||
android:actionLayout="@layout/layout_searchview"
|
android:actionLayout="@layout/layout_searchview"
|
||||||
android:icon="@android:drawable/ic_menu_search"
|
android:icon="@drawable/ic_search_24"
|
||||||
android:title="@string/action_search"
|
android:title="@string/action_search"
|
||||||
android:titleCondensed="@string/action_search"
|
android:titleCondensed="@string/action_search"
|
||||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||||
|
65
app/src/main/res/navigation/comments_nav_graph.xml
Normal file
65
app/src/main/res/navigation/comments_nav_graph.xml
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/comments_nav_graph"
|
||||||
|
app:startDestination="@id/commentsViewerFragment">
|
||||||
|
|
||||||
|
<include app:graph="@navigation/hashtag_nav_graph" />
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_global_hashTagFragment"
|
||||||
|
app:destination="@id/hashtag_nav_graph">
|
||||||
|
<argument
|
||||||
|
android:name="hashtag"
|
||||||
|
app:argType="string"
|
||||||
|
app:nullable="false" />
|
||||||
|
</action>
|
||||||
|
|
||||||
|
<!--<include app:graph="@navigation/profile_nav_graph" />-->
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_global_profileFragment"
|
||||||
|
app:destination="@id/profile_nav_graph">
|
||||||
|
<argument
|
||||||
|
android:name="username"
|
||||||
|
app:argType="string"
|
||||||
|
app:nullable="true" />
|
||||||
|
</action>
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/commentsViewerFragment"
|
||||||
|
android:name="awais.instagrabber.activities.CommentsViewerFragment"
|
||||||
|
android:label="Comments"
|
||||||
|
tools:layout="@layout/fragment_comments">
|
||||||
|
<argument
|
||||||
|
android:name="shortCode"
|
||||||
|
app:argType="string"
|
||||||
|
app:nullable="false" />
|
||||||
|
<argument
|
||||||
|
android:name="postId"
|
||||||
|
app:argType="string"
|
||||||
|
app:nullable="false" />
|
||||||
|
<argument
|
||||||
|
android:name="postUserId"
|
||||||
|
app:argType="string"
|
||||||
|
app:nullable="false" />
|
||||||
|
</fragment>
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_global_commentsViewerFragment"
|
||||||
|
app:destination="@id/commentsViewerFragment">
|
||||||
|
<argument
|
||||||
|
android:name="shortCode"
|
||||||
|
app:argType="string"
|
||||||
|
app:nullable="false" />
|
||||||
|
<argument
|
||||||
|
android:name="postId"
|
||||||
|
app:argType="string"
|
||||||
|
app:nullable="false" />
|
||||||
|
<argument
|
||||||
|
android:name="postUserId"
|
||||||
|
app:argType="string"
|
||||||
|
app:nullable="false" />
|
||||||
|
</action>
|
||||||
|
</navigation>
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
<include app:graph="@navigation/post_view_nav_graph" />
|
<include app:graph="@navigation/post_view_nav_graph" />
|
||||||
<include app:graph="@navigation/profile_nav_graph" />
|
<include app:graph="@navigation/profile_nav_graph" />
|
||||||
|
<include app:graph="@navigation/comments_nav_graph" />
|
||||||
|
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_global_postViewFragment"
|
android:id="@+id/action_global_postViewFragment"
|
||||||
|
@ -54,6 +54,25 @@
|
|||||||
app:argType="boolean" />
|
app:argType="boolean" />
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
|
<include app:graph="@navigation/comments_nav_graph" />
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_global_commentsViewerFragment"
|
||||||
|
app:destination="@id/comments_nav_graph">
|
||||||
|
<argument
|
||||||
|
android:name="shortCode"
|
||||||
|
app:argType="string"
|
||||||
|
app:nullable="false" />
|
||||||
|
<argument
|
||||||
|
android:name="postId"
|
||||||
|
app:argType="string"
|
||||||
|
app:nullable="false" />
|
||||||
|
<argument
|
||||||
|
android:name="postUserId"
|
||||||
|
app:argType="string"
|
||||||
|
app:nullable="false" />
|
||||||
|
</action>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/feedFragment"
|
android:id="@+id/feedFragment"
|
||||||
android:name="awais.instagrabber.fragments.main.FeedFragment"
|
android:name="awais.instagrabber.fragments.main.FeedFragment"
|
||||||
|
@ -36,6 +36,24 @@
|
|||||||
app:argType="string"
|
app:argType="string"
|
||||||
app:nullable="false" />
|
app:nullable="false" />
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_global_commentsViewerFragment"
|
||||||
|
app:destination="@id/comments_nav_graph">
|
||||||
|
<argument
|
||||||
|
android:name="shortCode"
|
||||||
|
app:argType="string"
|
||||||
|
app:nullable="false" />
|
||||||
|
<argument
|
||||||
|
android:name="postId"
|
||||||
|
app:argType="string"
|
||||||
|
app:nullable="false" />
|
||||||
|
<argument
|
||||||
|
android:name="postUserId"
|
||||||
|
app:argType="string"
|
||||||
|
app:nullable="false" />
|
||||||
|
</action>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/postViewFragment"
|
android:id="@+id/postViewFragment"
|
||||||
android:name="awais.instagrabber.fragments.PostViewFragment"
|
android:name="awais.instagrabber.fragments.PostViewFragment"
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
app:argType="boolean" />
|
app:argType="boolean" />
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
|
<include app:graph="@navigation/comments_nav_graph" />
|
||||||
|
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_global_profileFragment"
|
android:id="@+id/action_global_profileFragment"
|
||||||
app:destination="@id/profileFragment">
|
app:destination="@id/profileFragment">
|
||||||
|
Loading…
Reference in New Issue
Block a user