diff --git a/.all-contributorsrc b/.all-contributorsrc
index 34959778..ac44348d 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -42,6 +42,15 @@
"bug"
]
},
+ {
+ "login": "MeLlamoPablo",
+ "name": "Pablo RodrΓguez",
+ "avatar_url": "https://avatars.githubusercontent.com/u/11708035?v=4",
+ "profile": "https://github.com/MeLlamoPablo",
+ "contributions": [
+ "code"
+ ]
+ },
{
"login": "AwaisKing",
"name": "AWAiS",
@@ -55,7 +64,7 @@
"login": "snajdovski",
"name": "Stefan Najdovski",
"avatar_url": "https://avatars2.githubusercontent.com/u/42580385?v=4",
- "profile": "https://stefannajdovski.com/",
+ "profile": "https://snajdovski.github.io",
"contributions": [
"design",
"translation"
diff --git a/README.md b/README.md
index 77e3e1dc..d3671d60 100755
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com)
[![GPLv3 license](https://img.shields.io/badge/License-GPLv3-blue.svg)](./LICENSE)
[![GitHub stars](https://img.shields.io/github/stars/austinhuang0131/instagrabber.svg?style=social&label=Star)](https://GitHub.com/austinhuang0131/barinsta/stargazers/)
-[![All Contributors](https://img.shields.io/badge/all_contributors-37-orange.svg)](#contributors)
+[![All Contributors](https://img.shields.io/badge/all_contributors-38-orange.svg)](#contributors)
Instagram client; previously known as InstaGrabber.
@@ -57,51 +57,52 @@ Prominent contributors are listed here in the [all-contributors](https://allcont
Austin Huang π» π π¬ π π€ |
Ammar Githam π» π¨ π€ π§ π¬ |
Anderson Mesquita π» π |
+ Pablo RodrΓguez π» |
AWAiS π» |
- Stefan Najdovski π¨ π |
- CrazyMarvin π΅ |
+ Stefan Najdovski π¨ π |
+ CrazyMarvin π΅ |
Kevin Thomas π΅ |
Shadowspear123 π π π€ π¬ |
Ricardo π π |
Airikr π€ π¬ |
Akrai π€ π |
- avtkal π |
+ avtkal π |
CΓ©zar Augusto π |
Dimitris T π |
farzadx π |
Fatih AydΔ±n π |
fouze555 π |
- Galang23 π |
+ Galang23 π |
Initdebugs π |
Jakub Janek π |
GenosseFlosse π |
kernoeb π |
MoaufmKlo π |
- nalinalini π |
+ nalinalini π |
peterge1998 π |
PierreM0 π |
RAMAR-RAR π |
rohang02 π |
retiolus π |
- rikishi0071 π |
+ rikishi0071 π |
Alexey Peschany π |
Still Hsu π |
Ten_Lego π |
wagnim π |
wokija π |
- ysakamoto π |
+ ysakamoto π |
ZDVokoun π |
@@ -131,7 +132,7 @@ This app's predecessor, InstaGrabber, was originally made by [@AwaisKing](https:
You should have received a copy of the GNU General Public License
along with this program. If not, see .
-Logo by [Stefan Najdovski](https://stefannajdovski.com/). Used under license.
+Logo by [Stefan Najdovski](https://snajdovski.github.io/). Used under license.
[![Snyk Vulnerabilities](https://img.shields.io/snyk/vulnerabilities/github/austinhuang0131/instagrabber)](https://snyk.io/test/github/austinhuang0131/barinsta)
[![LGTM Alerts](https://img.shields.io/lgtm/alerts/github/austinhuang0131/instagrabber)](https://lgtm.com/projects/g/austinhuang0131/barinsta)
diff --git a/app/build.gradle b/app/build.gradle
index 785b9daf..222f72ba 100755
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -10,8 +10,8 @@ android {
minSdkVersion 21
targetSdkVersion 29
- versionCode 58
- versionName '19.1.0-a1'
+ versionCode 59
+ versionName '19.1.0-a2'
multiDexEnabled true
diff --git a/app/src/main/java/awais/instagrabber/adapters/NotificationsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/NotificationsAdapter.java
index e912878f..394c2374 100644
--- a/app/src/main/java/awais/instagrabber/adapters/NotificationsAdapter.java
+++ b/app/src/main/java/awais/instagrabber/adapters/NotificationsAdapter.java
@@ -14,13 +14,11 @@ import java.util.List;
import awais.instagrabber.adapters.viewholder.NotificationViewHolder;
import awais.instagrabber.databinding.ItemNotificationBinding;
-import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.NotificationModel;
import awais.instagrabber.models.enums.NotificationType;
public final class NotificationsAdapter extends ListAdapter {
private final OnNotificationClickListener notificationClickListener;
- private final MentionClickListener mentionClickListener;
private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() {
@Override
@@ -34,11 +32,9 @@ public final class NotificationsAdapter extends ListAdapter {
- if (longClickListener != null) longClickListener.onLongClick(this);
- };
-
- public RamboTextView(final Context context) {
- super(context);
- }
-
- public RamboTextView(final Context context, final AttributeSet attrs) {
- super(context, attrs);
- }
-
- public RamboTextView(final Context context, final AttributeSet attrs, final int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- public void setMentionClickListener(final MentionClickListener mentionClickListener) {
- this.mentionClickListener = mentionClickListener;
- }
-
- // public void setCaptionIsExpandable(final boolean isExpandable) {
- // this.isExpandable = isExpandable;
- // }
-
- // public void setCaptionIsExpanded(final boolean isExpanded) {
- // this.isExpanded = isExpanded;
- // }
-
- @Override
- public void setOnLongClickListener(@Nullable final OnLongClickListener l) {
- if (l == null) return;
- this.longClickListener = l;
- }
-
- @SuppressLint("ClickableViewAccessibility")
- @Override
- public boolean onTouchEvent(final MotionEvent event) {
- final CharSequence text = getText();
- if (text instanceof SpannableString || text instanceof SpannableStringBuilder) {
- final Spannable spanText = (Spannable) text;
- final ClickableSpan clickableSpanUnderTouch = findClickableSpanUnderTouch(this, spanText, event);
-
- final int action = event.getAction();
-
- if (action == MotionEvent.ACTION_DOWN) clickableSpanUnderTouchOnActionDown = clickableSpanUnderTouch;
- final boolean touchStartedOverAClickableSpan = clickableSpanUnderTouchOnActionDown != null;
- final boolean isURLSpan = clickableSpanUnderTouch instanceof URLSpan;
-
- // feed view caption hacks
- // if (isExpandable && !touchStartedOverAClickableSpan)
- // return !isExpanded | super.onTouchEvent(event); // short operator, because we want two shits to work
-
- // final Object tag = getTag();
- // final FeedModel feedModel = tag instanceof FeedModel ? (FeedModel) tag : null;
-
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- final int longPressTimeout = ViewConfiguration.getLongPressTimeout();
- handler.postDelayed(longPressRunnable, longPressTimeout);
- // if (feedModel != null) feedModel.setMentionClicked(false);
- if (clickableSpanUnderTouch != null) {
- highlightUrl(clickableSpanUnderTouch, spanText);
- }
- return super.onTouchEvent(event);
- case MotionEvent.ACTION_UP:
- handler.removeCallbacks(longPressRunnable);
- if (touchStartedOverAClickableSpan && clickableSpanUnderTouch == clickableSpanUnderTouchOnActionDown) {
- dispatchUrlClick(spanText, clickableSpanUnderTouch);
- // if (feedModel != null) feedModel.setMentionClicked(true);
- }
- cleanupOnTouchUp(spanText);
- return super.onTouchEvent(event);
- case MotionEvent.ACTION_MOVE:
- // handler.removeCallbacks(longPressRunnable);
- // if (feedModel != null) feedModel.setMentionClicked(false);
- if (clickableSpanUnderTouch != null) highlightUrl(clickableSpanUnderTouch, spanText);
- else removeUrlHighlightColor(spanText);
- return super.onTouchEvent(event);
- case MotionEvent.ACTION_CANCEL:
- handler.removeCallbacks(longPressRunnable);
- // if (feedModel != null) feedModel.setMentionClicked(false);
- cleanupOnTouchUp(spanText);
- return super.onTouchEvent(event);
- }
- }
-
- return super.onTouchEvent(event);
- }
-
- protected void dispatchUrlClick(final Spanned s, final ClickableSpan clickableSpan) {
- if (mentionClickListener != null) {
- final int spanStart = s.getSpanStart(clickableSpan);
- final boolean ishHashtag = s.charAt(spanStart) == '#';
-
- final int start = ishHashtag || s.charAt(spanStart) != '@' ? spanStart : spanStart + 1;
-
- CharSequence subSequence = s.subSequence(start, s.getSpanEnd(clickableSpan));
-
- // for feed ellipsize
- final int indexOfEllipsize = TextUtils.indexOfChar(subSequence, 'β¦', 0);
- if (indexOfEllipsize != -1)
- subSequence = subSequence.subSequence(0, indexOfEllipsize - 1);
-
- mentionClickListener.onClick(this, subSequence.toString(), ishHashtag, false);
- }
- }
-
- protected void highlightUrl(final ClickableSpan clickableSpan, final Spannable text) {
- if (!isUrlHighlighted) {
- isUrlHighlighted = true;
-
- final int spanStart = text.getSpanStart(clickableSpan);
- final int spanEnd = text.getSpanEnd(clickableSpan);
- final BackgroundColorSpan highlightSpan = new BackgroundColorSpan(getHighlightColor());
- text.setSpan(highlightSpan, spanStart, spanEnd, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
- setTag(highlightBackgroundSpanKey, highlightSpan);
- Selection.setSelection(text, spanStart, spanEnd);
- }
- }
-
- protected void removeUrlHighlightColor(final Spannable text) {
- if (isUrlHighlighted) {
- isUrlHighlighted = false;
-
- final BackgroundColorSpan highlightSpan = (BackgroundColorSpan) getTag(highlightBackgroundSpanKey);
- text.removeSpan(highlightSpan);
-
- Selection.removeSelection(text);
- }
- }
-
- private void cleanupOnTouchUp(final Spannable text) {
- clickableSpanUnderTouchOnActionDown = null;
- removeUrlHighlightColor(text);
- }
-
- @Nullable
- private static ClickableSpan findClickableSpanUnderTouch(@NonNull final TextView textView,
- final Spanned text,
- @NonNull final MotionEvent event) {
- final int touchX = (int) (event.getX() - textView.getTotalPaddingLeft() + textView.getScrollX());
- final int touchY = (int) (event.getY() - textView.getTotalPaddingTop() + textView.getScrollY());
-
- final Layout layout = textView.getLayout();
- final int touchedLine = layout.getLineForVertical(touchY);
- final int touchOffset = layout.getOffsetForHorizontal(touchedLine, touchX);
-
- touchedLineBounds.left = layout.getLineLeft(touchedLine);
- touchedLineBounds.top = layout.getLineTop(touchedLine);
- touchedLineBounds.right = layout.getLineWidth(touchedLine) + touchedLineBounds.left;
- touchedLineBounds.bottom = layout.getLineBottom(touchedLine);
-
- if (touchedLineBounds.contains(touchX, touchY)) {
- final Object[] spans = text.getSpans(touchOffset, touchOffset, ClickableSpan.class);
- for (final Object span : spans)
- if (span instanceof ClickableSpan) return (ClickableSpan) span;
- }
-
- return null;
- }
-
- public boolean isCaptionExpanded() {
- return isExpanded;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/fragments/NotificationsViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/NotificationsViewerFragment.java
index 34dc5922..e272cb8f 100644
--- a/app/src/main/java/awais/instagrabber/fragments/NotificationsViewerFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/NotificationsViewerFragment.java
@@ -33,7 +33,6 @@ import awais.instagrabber.asyncs.NotificationsFetcher;
import awais.instagrabber.databinding.FragmentNotificationsViewerBinding;
import awais.instagrabber.fragments.settings.MorePreferencesFragmentDirections;
import awais.instagrabber.interfaces.FetchListener;
-import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.NotificationModel;
import awais.instagrabber.models.enums.NotificationType;
import awais.instagrabber.repositories.requests.StoryViewerOptions;
@@ -145,33 +144,8 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
}
});
return;
- } else if (model.getType() == NotificationType.RESPONDED_STORY) {
- final NavDirections action = NotificationsViewerFragmentDirections
- .actionNotificationsViewerFragmentToStoryViewerFragment(StoryViewerOptions.forStory(model.getPostId(),
- model.getUsername()));
- NavHostFragment.findNavController(NotificationsViewerFragment.this).navigate(action);
- return;
}
- final AlertDialog alertDialog = new AlertDialog.Builder(context)
- .setCancelable(false)
- .setView(R.layout.dialog_opening_post)
- .create();
- alertDialog.show();
- mediaService.fetch(model.getPostId(), new ServiceCallback() {
- @Override
- public void onSuccess(final Media feedModel) {
- final PostViewV2Fragment fragment = PostViewV2Fragment
- .builder(feedModel)
- .build();
- fragment.setOnShowListener(dialog1 -> alertDialog.dismiss());
- fragment.show(getChildFragmentManager(), "post_view");
- }
-
- @Override
- public void onFailure(final Throwable t) {
- Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }
- });
+ clickListener.onPreviewClick(model);
break;
case 2:
friendshipService.ignore(model.getUserId(), new ServiceCallback() {
@@ -196,16 +170,6 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
}
}
};
- private final MentionClickListener mentionClickListener = (view, text, isHashtag, isLocation) -> {
- if (getContext() == null) return;
- new AlertDialog.Builder(getContext())
- .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) -> openProfile(text))
- .show();
- };
@Override
public void onCreate(@Nullable final Bundle savedInstanceState) {
@@ -250,7 +214,7 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
CookieUtils.setupCookies(settingsHelper.getString(Constants.COOKIE));
binding.swipeRefreshLayout.setOnRefreshListener(this);
notificationViewModel = new ViewModelProvider(this).get(NotificationViewModel.class);
- final NotificationsAdapter adapter = new NotificationsAdapter(clickListener, mentionClickListener);
+ final NotificationsAdapter adapter = new NotificationsAdapter(clickListener);
binding.rvComments.setLayoutManager(new LinearLayoutManager(context));
binding.rvComments.setAdapter(adapter);
notificationViewModel.getList().observe(getViewLifecycleOwner(), adapter::submitList);
diff --git a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java
index 74bee61d..3111584d 100644
--- a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java
@@ -817,7 +817,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
}
private void setupCaption(final Caption caption) {
- if (caption == null) {
+ if (caption == null || TextUtils.isEmpty(caption.getText())) {
binding.caption.setVisibility(View.GONE);
binding.translate.setVisibility(View.GONE);
binding.captionToggle.setVisibility(View.GONE);
diff --git a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
index 856a2164..f045dcd4 100644
--- a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
@@ -709,7 +709,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
.trim()));
profileDetailsBinding.mainBiography
.addOnURLClickListener(autoLinkItem -> Utils.openURL(getContext(), autoLinkItem.getOriginalText().trim()));
- profileDetailsBinding.mainBiography.setOnClickListener(v -> {
+ profileDetailsBinding.mainBiography.setOnLongClickListener(v -> {
String[] commentDialogList;
if (!TextUtils.isEmpty(cookie)) {
commentDialogList = new String[]{
@@ -753,9 +753,6 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
})
.setNegativeButton(R.string.cancel, null)
.show();
- });
- profileDetailsBinding.mainBiography.setOnLongClickListener(v -> {
- Utils.copyText(context, biography);
return true;
});
}
diff --git a/app/src/main/java/awais/instagrabber/interfaces/MentionClickListener.java b/app/src/main/java/awais/instagrabber/interfaces/MentionClickListener.java
deleted file mode 100755
index c3b7c8b7..00000000
--- a/app/src/main/java/awais/instagrabber/interfaces/MentionClickListener.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package awais.instagrabber.interfaces;
-
-import awais.instagrabber.customviews.RamboTextView;
-
-@Deprecated
-public interface MentionClickListener {
- void onClick(final RamboTextView view,
- final String text,
- final boolean isHashtag,
- final boolean isLocation);
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/models/enums/NotificationType.java b/app/src/main/java/awais/instagrabber/models/enums/NotificationType.java
index 7e39443b..28a95153 100755
--- a/app/src/main/java/awais/instagrabber/models/enums/NotificationType.java
+++ b/app/src/main/java/awais/instagrabber/models/enums/NotificationType.java
@@ -9,7 +9,7 @@ public enum NotificationType implements Serializable {
LIKE("GraphLikeAggregatedStory"),
FOLLOW("GraphFollowAggregatedStory"),
COMMENT("GraphCommentMediaStory"),
- MENTION("GraphMentionStory"),
+ COMMENT_MENTION("GraphMentionStory"),
TAGGED("GraphUserTaggedStory"),
// app story_type
COMMENT_LIKE("13"),
diff --git a/app/src/main/java/awais/instagrabber/repositories/requests/directmessages/StoryReplyBroadcastOptions.java b/app/src/main/java/awais/instagrabber/repositories/requests/directmessages/StoryReplyBroadcastOptions.java
index 3ab57d14..7fe3f8d0 100644
--- a/app/src/main/java/awais/instagrabber/repositories/requests/directmessages/StoryReplyBroadcastOptions.java
+++ b/app/src/main/java/awais/instagrabber/repositories/requests/directmessages/StoryReplyBroadcastOptions.java
@@ -17,7 +17,7 @@ public class StoryReplyBroadcastOptions extends BroadcastOptions {
final String reelId)
throws UnsupportedEncodingException {
super(clientContext, threadIdOrUserIds, BroadcastItemType.REELSHARE);
- this.text = TextUtils.encode(text);
+ this.text = text;
this.mediaId = mediaId;
this.reelId = reelId; // or user id, usually same
}
diff --git a/app/src/main/java/awais/instagrabber/utils/TextUtils.java b/app/src/main/java/awais/instagrabber/utils/TextUtils.java
index 95e82599..e26bd8cf 100644
--- a/app/src/main/java/awais/instagrabber/utils/TextUtils.java
+++ b/app/src/main/java/awais/instagrabber/utils/TextUtils.java
@@ -104,18 +104,6 @@ public final class TextUtils {
return (int) ((d2 - d1) / DateUtils.DAY_IN_MILLIS);
}
- @NonNull
- public static String encode(final String text) throws UnsupportedEncodingException {
- return URLEncoder.encode(text, "UTF-8")
- .replaceAll("\\+", "%20")
- .replaceAll("%21", "!")
- .replaceAll("%27", "'")
- .replaceAll("%28", "(")
- .replaceAll("%29", ")")
- .replaceAll("%7E", "~")
- .replaceAll("%0A", "\n");
- }
-
public static List extractUrls(final String text) {
if (isEmpty(text)) return Collections.emptyList();
final Matcher matcher = Patterns.WEB_URL.matcher(text);
diff --git a/app/src/main/java/awais/instagrabber/utils/UserAgentUtils.java b/app/src/main/java/awais/instagrabber/utils/UserAgentUtils.java
index 63c1f0a1..b2d69683 100644
--- a/app/src/main/java/awais/instagrabber/utils/UserAgentUtils.java
+++ b/app/src/main/java/awais/instagrabber/utils/UserAgentUtils.java
@@ -18,8 +18,8 @@ public class UserAgentUtils {
"Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.2 Safari/605.1.15"
};
// use APKpure, assume x86
- private static final String igVersion = "175.1.0.25.119";
- private static final String igVersionCode = "273907115";
+ private static final String igVersion = "177.0.0.30.119";
+ private static final String igVersionCode = "276028050";
// only pick the ones that has width 1440 for maximum download quality
public static final String[] devices = {
// https://github.com/dilame/instagram-private-api/blob/master/src/samples/devices.json
diff --git a/app/src/main/java/awais/instagrabber/webservices/NewsService.java b/app/src/main/java/awais/instagrabber/webservices/NewsService.java
index d8c83313..2eca1769 100644
--- a/app/src/main/java/awais/instagrabber/webservices/NewsService.java
+++ b/app/src/main/java/awais/instagrabber/webservices/NewsService.java
@@ -131,7 +131,7 @@ public class NewsService extends BaseService {
user.getLong("id"),
user.getString("username"),
user.getString("profile_pic_url"),
- data.has("media") ? data.getJSONObject("media").getLong("id") : 0,
+ !data.isNull("media") ? Long.valueOf(data.getJSONObject("media").getString("id").split("_")[0]) : 0,
data.has("media") ? data.getJSONObject("media").getString("thumbnail_src") : null,
notificationType));
}
diff --git a/app/src/main/res/layout/item_notification.xml b/app/src/main/res/layout/item_notification.xml
index 1ec1c187..f17f2c6c 100644
--- a/app/src/main/res/layout/item_notification.xml
+++ b/app/src/main/res/layout/item_notification.xml
@@ -45,11 +45,11 @@
app:layout_constraintTop_toTopOf="parent"
tools:text="username" />
-
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index dd7decc5..664e8045 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -12,8 +12,7 @@
Error copying text
Copied to clipboard!
Report
- Password (Max 32 chars)
- Set a password (max 32 chars)
+ Protect file with password
Password
OK
Yes
@@ -319,9 +318,9 @@
Locations
Unknown
Removed from Favourites
- Backup & Restore User Settings
- Back up app settings, account login information, and/or favorites data to a plain text or encrypted backup file for later restoration.
- If you\'re backing up login info, treat the file as confidential: Keep them somewhere safe!
+ Backup & Restore
+ Backup Barinsta app settings, account login data, and/or favorites to a plain text or encrypted backup file for later restoration.
+ If you\'re backing up account login data, treat the file as confidential and keep it somewhere safe!
Create new backup file
Restore from existing backup file
File: