Merge branch 'master' into l10n_master

This commit is contained in:
Austin Huang 2020-07-27 09:04:42 -04:00 committed by GitHub
commit 4ec190c008
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 443 additions and 169 deletions

View File

@ -9,11 +9,11 @@ android {
minSdkVersion 16
targetSdkVersion 29
// REMEMBER TO CHANGE versionCode as well
// REMEMBER TO CHANGE versionCode AS WELL
// 16.7 is 32
versionCode 33
versionName '16.8'
versionCode 34
versionName '16.9'
multiDexEnabled true

View File

@ -8,15 +8,25 @@ import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.RelativeSizeSpan;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
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;
@ -29,79 +39,74 @@ import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils;
public final class CommentsViewer extends AppCompatActivity {
import static awais.instagrabber.utils.Utils.settingsHelper;
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;
@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ActivityCommentsBinding commentsBinding = ActivityCommentsBinding.inflate(getLayoutInflater());
commentsBinding = ActivityCommentsBinding.inflate(getLayoutInflater());
setContentView(commentsBinding.getRoot());
commentsBinding.swipeRefreshLayout.setOnRefreshListener(this);
final String shortCode;
final Intent intent = getIntent();
if (intent == null || !intent.hasExtra(Constants.EXTRAS_SHORTCODE)
|| Utils.isEmpty((shortCode = intent.getStringExtra(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;
}
Log.d("austin_debug", "f:"+postId);
commentsBinding.swipeRefreshLayout.setRefreshing(true);
setSupportActionBar(commentsBinding.toolbar.toolbar);
commentsBinding.toolbar.toolbar.setTitle(R.string.title_comments);
commentsBinding.toolbar.toolbar.setSubtitle(shortCode);
final Resources resources = getResources();
resources = getResources();
final ArrayAdapter<String> commmentDialogAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
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)});
final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> {
final ProfileModel profileModel = commentModel.getProfileModel();
if (!Utils.isEmpty(cookie)) {
commentsBinding.commentText.setVisibility(View.VISIBLE);
commentsBinding.commentSend.setVisibility(View.VISIBLE);
if (which == 0) {
searchUsername(profileModel.getUsername());
} else if (which == 1) {
startActivity(new Intent(this, ProfileViewer.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());
}
};
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);
new AlertDialog.Builder(this).setTitle(title)
.setAdapter(commmentDialogAdapter, profileDialogListener)
.setNeutralButton(R.string.cancel, null)
.show();
}
};
final MentionClickListener mentionClickListener = (view, text, isHashtag) ->
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();
commentsBinding.commentSend.setOnClickListener(newCommentListener);
commentsBinding.commentCancelParent.setOnClickListener(newCommentListener);
}
new CommentsFetcher(shortCode, new FetchListener<CommentModel[]>() {
@Override
public void doBefore() {
commentsBinding.toolbar.progressCircular.setVisibility(View.VISIBLE);
}
public void onResult(final CommentModel[] commentModels) {
commentsBinding.toolbar.progressCircular.setVisibility(View.GONE);
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);
commentsBinding.toolbar.progressCircular.setVisibility(View.GONE);
commentsAdapter = new CommentsAdapter(commentModels, true, clickListener, mentionClickListener);
@ -111,6 +116,103 @@ public final class CommentsViewer extends AppCompatActivity {
}).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, ProfileViewer.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) {
commentsBinding.rvComments.findViewWithTag(commentModel).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) ->
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) {
commentsBinding.rvComments.findViewWithTag(commentModel).setBackgroundColor(commentModel.getLiked() ? 0x40FF69B4 : 0x00000000);
commentsBinding.commentCancelParent.setVisibility(View.GONE);
commentsBinding.commentText.setText("");
commentModel = null;
}
};
private void searchUsername(final String text) {
if (Main.scanHack != null) {
Main.scanHack.onResult(text);
@ -143,4 +245,63 @@ public final class CommentsViewer extends AppCompatActivity {
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 {
Log.d("austin_debug", url);
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", "" +
Integer.toString(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();
}
}
else Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
urlConnection.disconnect();
} catch (Throwable ex) {
Log.e("austin_debug", action+": " + ex);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
if (ok == true) {
if (commentModel != null) {
commentsBinding.rvComments.findViewWithTag(commentModel).setBackgroundColor(commentModel.getLiked() ? 0x40FF69B4 : 0x00000000);
commentsBinding.commentCancelParent.setVisibility(View.GONE);
}
//imm.hideSoftInputFromWindow(commentsBinding.getView().getRootView().getWindowToken(), 0);
onRefresh();
}
}
}
}

View File

@ -95,6 +95,7 @@ public final class Main extends BaseLanguageActivity {
private ArrayAdapter<String> profileDialogAdapter;
private DialogInterface.OnClickListener profileDialogListener;
private Stack<String> queriesStack;
private DataBox.CookieModel cookieModel;
public Main() {
super();
@ -152,13 +153,13 @@ public final class Main extends BaseLanguageActivity {
if (mainHelper != null && !mainBinding.swipeRefreshLayout.isRefreshing()) mainHelper.onRefresh();
}
// adds cookies to database for quick access
final DataBox.CookieModel cookieModel = Utils.dataBox.getCookie(uid);
cookieModel = Utils.dataBox.getCookie(uid);
if (Utils.dataBox.getCookieCount() == 0 || cookieModel == null || Utils.isEmpty(cookieModel.getUsername()))
Utils.dataBox.addUserCookie(new DataBox.CookieModel(uid, username, cookie));
}
};
boolean found = false;
final DataBox.CookieModel cookieModel = Utils.dataBox.getCookie(uid);
cookieModel = Utils.dataBox.getCookie(uid);
if (cookieModel != null) {
final String username = cookieModel.getUsername();
if (username != null) {
@ -316,7 +317,7 @@ public final class Main extends BaseLanguageActivity {
searchView.setQueryHint(getResources().getString(R.string.action_search));
searchView.setSuggestionsAdapter(suggestionAdapter);
searchView.setOnSearchClickListener(v -> {
searchView.setQuery(userQuery, false);
searchView.setQuery(userQuery.equals(cookieModel.getUsername()) ? "" : userQuery, false);
menu.findItem(R.id.action_about).setVisible(false);
menu.findItem(R.id.action_settings).setVisible(false);
menu.findItem(R.id.action_dms).setVisible(false);

View File

@ -81,7 +81,7 @@ public final class PostViewer extends BaseLanguageActivity {
private View viewsContainer, viewerCaptionParent;
private GestureDetectorCompat gestureDetector;
private SwipeEvent swipeEvent;
private CharSequence postCaption = null, postShortCode;
private CharSequence postCaption = null, postShortCode, postUserId;
private Resources resources;
private boolean session = false, isFromShare;
private int slidePos = 0, lastSlidePos = 0;
@ -153,7 +153,7 @@ public final class PostViewer extends BaseLanguageActivity {
if (player != null) {
final float intVol = player.getVolume() == 0f ? 1f : 0f;
player.setVolume(intVol);
viewerBinding.bottomPanel.btnMute.setImageResource(intVol == 0f ? R.drawable.vol : R.drawable.mute);
viewerBinding.bottomPanel.btnMute.setImageResource(intVol == 0f ? R.drawable.mute : R.drawable.vol);
Utils.sessionVolumeFull = intVol == 1f;
}
} else if (v == viewerBinding.btnLike) {
@ -355,18 +355,14 @@ public final class PostViewer extends BaseLanguageActivity {
viewerBinding.bottomPanel.commentsCount.setText(String.valueOf(commentsCount));
viewerBinding.bottomPanel.btnComments.setVisibility(View.VISIBLE);
if (commentsCount > 0) {
viewerBinding.bottomPanel.btnComments.setOnClickListener(v ->
startActivityForResult(new Intent(this, CommentsViewer.class)
.putExtra(Constants.EXTRAS_END_CURSOR, commentsEndCursor)
.putExtra(Constants.EXTRAS_SHORTCODE, postShortCode), 6969));
viewerBinding.bottomPanel.btnComments.setClickable(true);
viewerBinding.bottomPanel.btnComments.setEnabled(true);
} else {
viewerBinding.bottomPanel.btnComments.setOnClickListener(null);
viewerBinding.bottomPanel.btnComments.setClickable(false);
viewerBinding.bottomPanel.btnComments.setEnabled(false);
}
viewerBinding.bottomPanel.btnComments.setOnClickListener(v ->
startActivityForResult(new Intent(this, CommentsViewer.class)
.putExtra(Constants.EXTRAS_END_CURSOR, commentsEndCursor)
.putExtra(Constants.EXTRAS_SHORTCODE, postShortCode)
.putExtra(Constants.EXTRAS_POST, viewerPostModel.getPostId())
.putExtra(Constants.EXTRAS_USER, postUserId), 6969));
viewerBinding.bottomPanel.btnComments.setClickable(true);
viewerBinding.bottomPanel.btnComments.setEnabled(true);
if (postModel instanceof PostModel) {
final PostModel postModel = (PostModel) this.postModel;
@ -592,12 +588,12 @@ public final class PostViewer extends BaseLanguageActivity {
postModel.setLike(viewerPostModel.getLike());
postModel.setBookmark(viewerPostModel.getBookmark());
if (viewerPostModel.getLike() == true) {
viewerBinding.btnLike.setText(R.string.unlike);
viewerBinding.btnLike.setText(resources.getString(R.string.unlike, postModel.getLikes()));
viewerBinding.btnLike.setBackgroundTintList(ColorStateList.valueOf(resources.getColor(
R.color.btn_pink_background, null)));
}
else {
viewerBinding.btnLike.setText(R.string.like);
viewerBinding.btnLike.setText(resources.getString(R.string.like, postModel.getLikes()));
viewerBinding.btnLike.setBackgroundTintList(ColorStateList.valueOf(resources.getColor(
R.color.btn_lightpink_background, null)));
}
@ -620,7 +616,7 @@ public final class PostViewer extends BaseLanguageActivity {
url = viewerPostModel.getDisplayUrl();
releasePlayer();
viewerBinding.btnDownload.setVisibility(containerLayoutParams.weight == 3.3f ? View.GONE : View.VISIBLE);
viewerBinding.btnDownload.setVisibility(containerLayoutParams.weight == 3.3f ? View.VISIBLE : View.GONE);
if (viewerPostModel.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO) setupVideo();
else setupImage();
}
@ -645,6 +641,7 @@ public final class PostViewer extends BaseLanguageActivity {
if (result != null) {
final String hdProfilePic = result.getHdProfilePic();
final String sdProfilePic = result.getSdProfilePic();
postUserId = result.getId();
final boolean hdPicEmpty = Utils.isEmpty(hdProfilePic);
glideRequestManager.load(hdPicEmpty ? sdProfilePic : hdProfilePic).listener(new RequestListener<Drawable>() {
@ -732,13 +729,13 @@ public final class PostViewer extends BaseLanguageActivity {
@Override
protected void onPostExecute(Void result) {
if (ok == true && action == "likes") {
viewerPostModel.setLike(postModel.getLike() == true ? false : true);
postModel.setLike(postModel.getLike() == true ? false : true);
viewerPostModel.setLike(!postModel.getLike());
postModel.setManualLike(!postModel.getLike());
refreshPost();
}
else if (ok == true && action == "save") {
viewerPostModel.setBookmark(postModel.getBookmark() == true ? false : true);
postModel.setBookmark(postModel.getBookmark() == true ? false : true);
viewerPostModel.setBookmark(!postModel.getBookmark());
postModel.setBookmark(!postModel.getBookmark());
refreshPost();
}
}

View File

@ -121,8 +121,10 @@ public final class StoryViewer extends BaseLanguageActivity {
@Override
public void onSwipe(final boolean isRightSwipe) {
Log.d("austin_debug", "swipe: "+(isRightSwipe ? "backward " : "forward ") + slidePos + "/" + storiesLen + " "
+ (slidePos == storiesLen - 1 && isRightSwipe == false) + " " + intent.hasExtra(Constants.FEED));
if (storyModels != null && storiesLen > 0) {
if (((slidePos == storiesLen - 1 && isRightSwipe == false) || (slidePos == 0 && isRightSwipe == true))
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);
@ -148,9 +150,8 @@ public final class StoryViewer extends BaseLanguageActivity {
if (isRightSwipe) {
if (--slidePos <= 0) slidePos = 0;
} else if (++slidePos >= storiesLen) slidePos = storiesLen - 1;
currentStory = storyModels[slidePos];
slidePos = currentStory.getPosition();
//slidePos = currentStory.getPosition();
refreshStory();
}
}

View File

@ -107,6 +107,7 @@ public final class CommentsAdapter extends RecyclerView.Adapter<CommentViewHolde
holder.setCommment(commentModel.getText());
holder.setDate(commentModel.getDateTime());
holder.setLiked(commentModel.getLiked());
final long likes = commentModel.getLikes();
holder.setLikes(String.format(LocaleUtils.getCurrentLocale(), "%d %s", likes, quantityStrings[likes == 1 ? 0 : 1]));

View File

@ -82,7 +82,9 @@ public final class FeedAdapter extends RecyclerView.Adapter<FeedItemViewHolder>
switch (id) {
case R.id.btnComments:
activity.startActivityForResult(new Intent(activity, CommentsViewer.class)
.putExtra(Constants.EXTRAS_SHORTCODE, feedModel.getShortCode()), 6969);
.putExtra(Constants.EXTRAS_SHORTCODE, feedModel.getShortCode())
.putExtra(Constants.EXTRAS_POST, feedModel.getPostId())
.putExtra(Constants.EXTRAS_USER, feedModel.getProfileModel().getId()), 6969);
break;
case R.id.viewStoryPost:
@ -305,7 +307,7 @@ public final class FeedAdapter extends RecyclerView.Adapter<FeedItemViewHolder>
final SimpleExoPlayer exoPlayer = (SimpleExoPlayer) player;
final float intVol = exoPlayer.getVolume() == 0f ? 1f : 0f;
exoPlayer.setVolume(intVol);
viewHolder.btnMute.setImageResource(intVol == 0f ? R.drawable.vol : R.drawable.mute);
viewHolder.btnMute.setImageResource(intVol == 0f ? R.drawable.mute : R.drawable.vol);
Utils.sessionVolumeFull = intVol == 1f;
}
};

View File

@ -65,6 +65,10 @@ public final class CommentViewHolder extends RecyclerView.ViewHolder {
if (tvLikes != null) tvLikes.setText(likes);
}
public final void setLiked(final boolean liked) {
if (liked) container.setBackgroundColor(0x40FF69B4);
}
public final void setCommment(final CharSequence commment) {
if (tvComment != null) {
tvComment.setText(commment, commment instanceof Spannable ? TextView.BufferType.SPANNABLE : TextView.BufferType.NORMAL);

View File

@ -123,6 +123,7 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, CommentModel[]>
childComment.getString("text"),
childComment.getLong("created_at"),
likedBy != null ? likedBy.optLong("count", 0) : 0,
childComment.getBoolean("viewer_has_liked"),
profileModel));
}
}
@ -201,6 +202,7 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, CommentModel[]>
comment.getString("text"),
comment.getLong("created_at"),
likedBy != null ? likedBy.optLong("count", 0) : 0,
comment.getBoolean("viewer_has_liked"),
profileModel);
JSONObject tempJsonObject;
@ -238,6 +240,7 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, CommentModel[]>
childComment.getString("text"),
childComment.getLong("created_at"),
tempJsonObject != null ? tempJsonObject.optLong("count", 0) : 0,
childComment.getBoolean("viewer_has_liked"),
childProfileModel);
}

View File

@ -131,7 +131,8 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> {
commentsCount,
feedItem.optLong("taken_at_timestamp", -1),
feedItem.getBoolean("viewer_has_liked"),
feedItem.getBoolean("viewer_has_saved"));
feedItem.getBoolean("viewer_has_saved"),
feedItem.getJSONObject("edge_media_preview_like").getLong("count"));
final boolean isSlider = "GraphSidecar".equals(mediaType) && feedItem.has("edge_sidecar_to_children");

View File

@ -81,6 +81,7 @@ public final class PostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
endCursor = commentObject.optString("end_cursor");
if (mediaItemType != MediaItemType.MEDIA_TYPE_SLIDER) {
Log.d("austin_debug", "m: "+media);
final ViewerPostModel postModel = new ViewerPostModel(mediaItemType,
media.getString(Constants.EXTRAS_ID),
isVideo ? media.getString("video_url") : Utils.getHighQualityImage(media),

View File

@ -107,7 +107,7 @@ public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
mediaNode.getString(Constants.EXTRAS_SHORTCODE),
captions.length() > 0 ? captions.getJSONObject(0).getJSONObject("node").getString("text") : null,
mediaNode.getLong("taken_at_timestamp"), mediaNode.optBoolean("viewer_has_liked"),
mediaNode.optBoolean("viewer_has_saved"));
mediaNode.optBoolean("viewer_has_saved"), mediaNode.getJSONObject("edge_liked_by").getLong("count"));
Utils.checkExistence(downloadDir, customDir, username, isSlider, -1, models[i]);
}

View File

@ -48,7 +48,9 @@ public class VideoAwareRecyclerScroller extends RecyclerView.OnScrollListener {
if (tag instanceof FeedModel && context instanceof Activity) {
if (player != null) player.setPlayWhenReady(false);
((Activity) context).startActivityForResult(new Intent(context, CommentsViewer.class)
.putExtra(Constants.EXTRAS_SHORTCODE, ((FeedModel) tag).getShortCode()), 6969);
.putExtra(Constants.EXTRAS_SHORTCODE, ((FeedModel) tag).getShortCode())
.putExtra(Constants.EXTRAS_POST, ((FeedModel) tag).getPostId())
.putExtra(Constants.EXTRAS_POST, ((FeedModel) tag).getProfileModel().getId()), 6969);
}
}
};
@ -56,7 +58,7 @@ public class VideoAwareRecyclerScroller extends RecyclerView.OnScrollListener {
if (player == null) return;
final float intVol = player.getVolume() == 0f ? 1f : 0f;
player.setVolume(intVol);
if (btnMute != null) btnMute.setImageResource(intVol == 0f ? R.drawable.vol : R.drawable.mute);
if (btnMute != null) btnMute.setImageResource(intVol == 0f ? R.drawable.mute : R.drawable.vol);
Utils.sessionVolumeFull = intVol == 1f;
};
private final VideoChangeCallback videoChangeCallback;

View File

@ -36,6 +36,7 @@ public final class QuickAccessDialog extends BottomSheetDialogFragment implement
private String userQuery;
private View btnFavorite, btnImportExport;
private SimpleAdapter<DataBox.FavoriteModel> favoritesAdapter;
private RecyclerView rvFavorites, rvQuickAccess;
public QuickAccessDialog setQuery(final String userQuery) {
this.userQuery = userQuery;
@ -66,8 +67,8 @@ public final class QuickAccessDialog extends BottomSheetDialogFragment implement
btnFavorite.setOnClickListener(this);
btnImportExport.setOnClickListener(this);
final RecyclerView rvFavorites = contentView.findViewById(R.id.rvFavorites);
final RecyclerView rvQuickAccess = contentView.findViewById(R.id.rvQuickAccess);
rvFavorites = contentView.findViewById(R.id.rvFavorites);
rvQuickAccess = contentView.findViewById(R.id.rvQuickAccess);
final DividerItemDecoration itemDecoration = new DividerItemDecoration(activity, DividerItemDecoration.VERTICAL);
rvFavorites.addItemDecoration(itemDecoration);
@ -133,9 +134,12 @@ public final class QuickAccessDialog extends BottomSheetDialogFragment implement
if (tag instanceof DataBox.FavoriteModel) {
final DataBox.FavoriteModel favoriteModel = (DataBox.FavoriteModel) tag;
new AlertDialog.Builder(activity).setPositiveButton(R.string.yes, (d, which) -> Utils.dataBox.delFavorite(favoriteModel))
.setNegativeButton(R.string.no, null).setMessage(getString(R.string.quick_access_confirm_delete,
favoriteModel.getQuery())).show();
new AlertDialog.Builder(activity).setPositiveButton(R.string.yes, (d, which) -> {
Utils.dataBox.delFavorite(favoriteModel);
rvFavorites.findViewWithTag(favoriteModel).setVisibility(View.GONE);
})
.setNegativeButton(R.string.no, null).setMessage(getString(R.string.quick_access_confirm_delete,
favoriteModel.getQuery())).show();
} else if (tag instanceof DataBox.CookieModel) {
final DataBox.CookieModel cookieModel = (DataBox.CookieModel) tag;
@ -143,7 +147,10 @@ public final class QuickAccessDialog extends BottomSheetDialogFragment implement
if (cookieModel.isSelected())
Toast.makeText(v.getContext(), R.string.quick_access_cannot_delete_curr, Toast.LENGTH_SHORT).show();
else
new AlertDialog.Builder(activity).setPositiveButton(R.string.yes, (d, which) -> Utils.dataBox.delUserCookie(cookieModel))
new AlertDialog.Builder(activity).setPositiveButton(R.string.yes, (d, which) -> {
Utils.dataBox.delUserCookie(cookieModel);
rvQuickAccess.findViewWithTag(cookieModel).setVisibility(View.GONE);
})
.setNegativeButton(R.string.no, null).setMessage(getString(R.string.quick_access_confirm_delete,
cookieModel.getUsername())).show();
}

View File

@ -60,7 +60,7 @@ public final class MultiDirectDialog extends BaseLanguageActivity {
for (final ViewerPostModel postModel : postModels)
models.add(new PostModel(postModel.getItemType(), postModel.getPostId(), postModel.getDisplayUrl(),
postModel.getSliderDisplayUrl(), postModel.getShortCode(), postModel.getPostCaption(), postModel.getTimestamp(),
postModel.getLike(), postModel.getBookmark()));
postModel.getLike(), postModel.getBookmark(), postModel.getLikes()));
postsAdapter = new PostsAdapter(models, v -> {
final Object tag = v.getTag();

View File

@ -19,10 +19,14 @@ public abstract class BasePostModel implements Serializable {
protected long timestamp;
protected int position;
boolean liked, bookmarked;
long likes;
public boolean getLike() {
return liked;
}
public long getLikes() {
return likes;
}
public boolean getBookmark() {
return bookmarked;
}
@ -30,6 +34,14 @@ public abstract class BasePostModel implements Serializable {
public boolean setLike(final boolean like) {
liked = like; return liked;
}
// setManualLike means user liked from InstaGrabber
public boolean setManualLike(final boolean like) {
liked = like;
likes = (like) ? (likes + 1) : (likes - 1);
return liked;
}
public boolean setBookmark(final boolean bookmark) {
bookmarked = bookmark; return bookmarked;
}

View File

@ -12,13 +12,15 @@ public final class CommentModel {
private final CharSequence text;
private final long likes, timestamp;
private CommentModel[] childCommentModels;
private boolean hasNextPage;
private boolean hasNextPage, liked;
private String endCursor;
public CommentModel(final String id, final String text, final long timestamp, final long likes, final ProfileModel profileModel) {
public CommentModel(final String id, final String text, final long timestamp, final long likes, final boolean liked,
final ProfileModel profileModel) {
this.id = id;
this.text = Utils.hasMentions(text) ? Utils.getMentionText(text) : text;
this.likes = likes;
this.liked = liked;
this.timestamp = timestamp;
this.profileModel = profileModel;
}
@ -40,6 +42,10 @@ public final class CommentModel {
return likes;
}
public boolean getLiked() {
return liked;
}
public ProfileModel getProfileModel() {
return profileModel;
}

View File

@ -10,8 +10,8 @@ public final class FeedModel extends PostModel {
public FeedModel(final ProfileModel profileModel, final MediaItemType itemType, final long viewCount, final String postId,
final String displayUrl, final String thumbnailUrl, final String shortCode, final String postCaption,
final long commentsCount, final long timestamp, boolean liked, boolean bookmarked) {
super(itemType, postId, displayUrl, thumbnailUrl, shortCode, postCaption, timestamp, liked, bookmarked);
final long commentsCount, final long timestamp, boolean liked, boolean bookmarked, long likes) {
super(itemType, postId, displayUrl, thumbnailUrl, shortCode, postCaption, timestamp, liked, bookmarked, likes);
this.profileModel = profileModel;
this.commentsCount = commentsCount;
this.viewCount = viewCount;

View File

@ -13,7 +13,8 @@ public class PostModel extends BasePostModel {
}
public PostModel(final MediaItemType itemType, final String postId, final String displayUrl, final String thumbnailUrl,
final String shortCode, final CharSequence postCaption, long timestamp, boolean liked, boolean bookmarked) {
final String shortCode, final CharSequence postCaption, long timestamp, boolean liked, boolean bookmarked,
long likes) {
this.itemType = itemType;
this.postId = postId;
this.displayUrl = displayUrl;
@ -22,6 +23,7 @@ public class PostModel extends BasePostModel {
this.postCaption = postCaption;
this.timestamp = timestamp;
this.liked = liked;
this.likes = likes;
this.bookmarked = bookmarked;
}
@ -33,6 +35,10 @@ public class PostModel extends BasePostModel {
return endCursor;
}
public long getLikes() {
return likes;
}
public boolean hasNextPage() {
return endCursor != null && hasNextPage;
}

View File

@ -30,7 +30,7 @@ public final class FlavorTown {
Resources res = context.getResources();
new UpdateChecker(version -> {
new AlertDialog.Builder(context)
.setTitle(res.getString(R.string.update_available) + " (" + version + ")")
.setTitle(res.getString(R.string.update_available, version))
.setMessage(R.string.update_notice)
.setNeutralButton(R.string.cancel, null)
.setNegativeButton(R.string.action_github, (dialog, which) -> {

View File

@ -5,21 +5,67 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".activities.CommentsViewer">
tools:context=".activities.CommentsViewer"
android:weightSum="8">
<include
android:id="@+id/toolbar"
android:layout_weight="1"
layout="@layout/layout_include_toolbar" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvComments"
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_weight="8"
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" />
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>

View File

@ -116,7 +116,7 @@
android:layout_weight="1"
android:text="@string/like"
android:textColor="@color/btn_lightpink_text_color"
android:textSize="20sp"
android:textSize="18sp"
app:backgroundTint="@color/btn_lightpink_background" />
<androidx.appcompat.widget.AppCompatButton
@ -130,7 +130,7 @@
android:layout_weight="1"
android:text="@string/bookmark"
android:textColor="@color/btn_lightorange_text_color"
android:textSize="20sp"
android:textSize="18sp"
app:backgroundTint="@color/btn_lightorange_background" />
</androidx.appcompat.widget.LinearLayoutCompat>
</LinearLayout>

View File

@ -35,13 +35,9 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvUsername"
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_weight="1.0"
@ -56,20 +52,6 @@
android:textColor="?android:textColorPrimary"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:ellipsize="marquee"
android:paddingStart="4dp"
android:paddingLeft="4dp"
android:paddingTop="4dp"
android:paddingEnd="8dp"
android:paddingRight="8dp"
android:singleLine="true"
android:textStyle="italic" />
</LinearLayout>
<awais.instagrabber.customviews.RamboTextView
android:id="@+id/tvComment"
@ -86,11 +68,15 @@
android:paddingRight="8dp"
android:paddingBottom="8dp"
android:textAppearance="@style/TextAppearance.AppCompat" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvLikes"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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"
@ -100,6 +86,23 @@
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textSize="12sp" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvDate"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2.5"
android:layout_gravity="start"
android:ellipsize="marquee"
android:paddingStart="4dp"
android:paddingLeft="4dp"
android:paddingTop="4dp"
android:paddingEnd="8dp"
android:paddingRight="8dp"
android:singleLine="true"
android:textStyle="italic"
android:gravity="right"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@ -51,13 +51,9 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvUsername"
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_weight="1.0"
@ -72,22 +68,7 @@
android:textColor="?android:textColorPrimary"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:ellipsize="marquee"
android:paddingStart="4dp"
android:paddingLeft="4dp"
android:paddingTop="4dp"
android:paddingEnd="8dp"
android:paddingRight="8dp"
android:singleLine="true"
android:textStyle="italic" />
</LinearLayout>
<LinearLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
@ -118,18 +99,40 @@
android:textAppearance="@style/TextAppearance.AppCompat" />
</LinearLayout>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvLikes"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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="14sp" />
android:weightSum="3">
<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="14sp" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvDate"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:layout_gravity="start"
android:ellipsize="marquee"
android:paddingStart="4dp"
android:paddingLeft="4dp"
android:paddingTop="4dp"
android:paddingEnd="8dp"
android:paddingRight="8dp"
android:singleLine="true"
android:textStyle="italic"
android:gravity="right"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@ -163,7 +163,7 @@
<string name="login_error_loading_cookies"> Errore durante il caricamento dei cookie</string>
<string name="login_success_loading_cookies">Cookie caricati correttamente! \nSe non riesci ancora ad aprire pagine / post privati, accedi nuovamente!</string>
<string name="comment_hint">Write a new comment...</string>
<string name="update_available">An update is available! (%s)</string>
<string name="update_available">Un aggiornamento è disponibile! (%s)</string>
<string name="update_notice">Reminder: If you downloaded from F-Droid, you must update from it! Same applies for GitHub.</string>
<string name="updated">Grazie per aver aggiornato InstaGrabber!</string>
<string name="crash_title">L\'app si è arrestata in modo anomalo</string>

View File

@ -162,8 +162,8 @@
<string name="followers_not_follower">%s 未关注</string>
<string name="login_error_loading_cookies">载入 cookies 时出错</string>
<string name="login_success_loading_cookies">成功载入 cookies!\n若你仍不能查看私密页面/帖子,重新登录!</string>
<string name="comment_hint">Write a new comment...</string>
<string name="update_available">An update is available! (%s)</string>
<string name="comment_hint">撰写新评论...</string>
<string name="update_available">检测到有新版本! (%s)</string>
<string name="update_notice">Reminder: If you downloaded from F-Droid, you must update from it! Same applies for GitHub.</string>
<string name="updated">感谢阁下更新InstaGrabber</string>
<string name="crash_title">应用崩溃了</string>

View File

@ -8,6 +8,8 @@
<item>Chinese Simplified</item>
<item>Indonesian [Thanks to @Galang23 (GitLab)]</item>
<item>Italian [Thanks to @RAR_Ramar (Telegram)]</item>
<item>German [Thanks to @MoaufmKlo (GitHub)]</item>
<item>Polish [Thanks to @Lego8486 (GitHub)]</item>
</string-array>
<string-array name="theme_presets">

View File

@ -71,8 +71,9 @@
<string name="project_link">Visit Project Page</string>
<string name="telegram_link">Join Telegram Group</string>
<string name="matrix_link">Join Matrix Room</string>
<string name="like">Like</string>
<string name="unlike">Unlike</string>
<string name="like">Like (%s)</string>
<string name="unlike">Unlike (%s)</string>
<string name="bookmark">Bookmark</string>
<string name="unbookmark">Unbookmark</string>
<string name="follow">Follow</string>
@ -150,6 +151,11 @@
<string name="downloader_error_download_file">Error downloading file</string>
<string name="comment_viewer_copy_user">Copy username</string>
<string name="comment_viewer_copy_comment">Copy comment</string>
<string name="comment_viewer_reply_comment">Reply to comment</string>
<string name="comment_viewer_like_comment">Like comment</string>
<string name="comment_viewer_unlike_comment">Unlike comment</string>
<string name="comment_viewer_delete_comment">Delete comment</string>
<string name="comment_send_empty_comment">No empty comments, dawg!</string>
<string name="comment_view_mention_user_search">Do you want to search the username?</string>
<string name="comment_view_mention_hash_search">Do you want to search the hashtag?</string>
<string name="followers_type_followers">Followers</string>
@ -160,7 +166,10 @@
<string name="followers_not_follower">%s not following</string>
<string name="login_error_loading_cookies">Error loading cookies</string>
<string name="login_success_loading_cookies">Successfully loaded cookies!\nIf you still can\'t open private pages/posts, re-login!</string>
<string name="update_available">An update is available!</string>
<string name="comment_hint">Write a new comment...</string>
<string name="update_available">An update is available! (%s)</string>
<string name="update_notice">Reminder: If you downloaded from F-Droid, you must update from it! Same applies for GitHub.</string>
<string name="updated">Thank you for updating InstaGrabber!</string>
<string name="crash_title">App crashed</string>

View File

@ -0,0 +1,6 @@
* You can now write comments, and reply/like/delete comments through the menu (by clicking the comment)
* You're actually
* Liked comments are shown with a pink background
* Post like counts are now displayed (The button texts are slightly reduced to accomodate @world_record_egg)
* Mute buttons are changed to display the current status (i.e. muted icon when muted, sound icon when not muted)
* Fixed a bug relating to viewing feed stories