Merge branch 'master' into dm-notifications-enhancements

This commit is contained in:
Ammar Githam 2021-03-03 20:06:51 +09:00
commit 605f15ee3a
18 changed files with 47 additions and 310 deletions

View File

@ -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"

View File

@ -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-BADGE:START - Do not remove or modify this section -->
[![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)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
Instagram client; previously known as InstaGrabber.
@ -57,51 +57,52 @@ Prominent contributors are listed here in the [all-contributors](https://allcont
<td align="center"><a href="https://austinhuang.me"><img src="https://avatars1.githubusercontent.com/u/16656689?s=100" width="100px;" alt=""/><br /><sub><b>Austin Huang</b></sub></a><br /><a href="https://github.com/austinhuang0131/barinsta/commits?author=austinhuang0131" title="Code">💻</a> <a href="https://github.com/austinhuang0131/barinsta/commits?author=austinhuang0131" title="Documentation">📖</a> <a href="#question-austinhuang0131" title="Answering Questions">💬</a> <a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a> <a href="#ideas-austinhuang0131" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center"><a href="https://github.com/ammargitham"><img src="https://avatars0.githubusercontent.com/u/8017365?s=100" width="100px;" alt=""/><br /><sub><b>Ammar Githam</b></sub></a><br /><a href="https://github.com/austinhuang0131/barinsta/commits?author=ammargitham" title="Code">💻</a> <a href="#design-ammargitham" title="Design">🎨</a> <a href="#ideas-ammargitham" title="Ideas, Planning, & Feedback">🤔</a> <a href="#maintenance-ammargitham" title="Maintenance">🚧</a> <a href="#question-ammargitham" title="Answering Questions">💬</a></td>
<td align="center"><a href="https://github.com/andersonvom"><img src="https://avatars3.githubusercontent.com/u/69922?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Anderson Mesquita</b></sub></a><br /><a href="https://github.com/austinhuang0131/barinsta/commits?author=andersonvom" title="Code">💻</a> <a href="https://github.com/austinhuang0131/barinsta/issues?q=author%3Aandersonvom" title="Bug reports">🐛</a></td>
<td align="center"><a href="https://github.com/MeLlamoPablo"><img src="https://avatars.githubusercontent.com/u/11708035?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pablo Rodríguez</b></sub></a><br /><a href="https://github.com/austinhuang0131/barinsta/commits?author=MeLlamoPablo" title="Code">💻</a></td>
<td align="center"><a href="http://rerolledgeek.blogspot.com/"><img src="https://avatars3.githubusercontent.com/u/5278488?s=100" width="100px;" alt=""/><br /><sub><b>AWAiS</b></sub></a><br /><a href="https://github.com/austinhuang0131/barinsta/commits?author=AwaisKing" title="Code">💻</a></td>
<td align="center"><a href="https://stefannajdovski.com/"><img src="https://avatars2.githubusercontent.com/u/42580385?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Stefan Najdovski</b></sub></a><br /><a href="#design-snajdovski" title="Design">🎨</a> <a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/CrazyMarvin"><img src="https://avatars3.githubusercontent.com/u/15004217?v=4?s=100" width="100px;" alt=""/><br /><sub><b>CrazyMarvin</b></sub></a><br /><a href="#financial-CrazyMarvin" title="Financial">💵</a></td>
<td align="center"><a href="https://snajdovski.github.io"><img src="https://avatars2.githubusercontent.com/u/42580385?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Stefan Najdovski</b></sub></a><br /><a href="#design-snajdovski" title="Design">🎨</a> <a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/CrazyMarvin"><img src="https://avatars3.githubusercontent.com/u/15004217?v=4?s=100" width="100px;" alt=""/><br /><sub><b>CrazyMarvin</b></sub></a><br /><a href="#financial-CrazyMarvin" title="Financial">💵</a></td>
<td align="center"><a href="http://kevinthomas.dev"><img src="https://avatars2.githubusercontent.com/u/15370181?s=100" width="100px;" alt=""/><br /><sub><b>Kevin Thomas</b></sub></a><br /><a href="#financial-KevinNThomas" title="Financial">💵</a></td>
<td align="center"><a href="https://github.com/Shadowspear123"><img src="https://avatars1.githubusercontent.com/u/50462281?s=100" width="100px;" alt=""/><br /><sub><b>Shadowspear123</b></sub></a><br /><a href="#blog-Shadowspear123" title="Blogposts">📝</a> <a href="https://github.com/austinhuang0131/barinsta/issues?q=author%3AShadowspear123" title="Bug reports">🐛</a> <a href="#ideas-Shadowspear123" title="Ideas, Planning, & Feedback">🤔</a> <a href="#question-Shadowspear123" title="Answering Questions">💬</a></td>
<td align="center"><a href="https://github.com/RickyM7"><img src="https://avatars3.githubusercontent.com/u/24703825?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ricardo</b></sub></a><br /><a href="https://github.com/austinhuang0131/barinsta/issues?q=author%3ARickyM7" title="Bug reports">🐛</a> <a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://airikr.me/"><img src="https://avatars0.githubusercontent.com/u/53869451?s=100" width="100px;" alt=""/><br /><sub><b>Airikr</b></sub></a><br /><a href="#ideas-e-edgren" title="Ideas, Planning, & Feedback">🤔</a> <a href="#question-e-edgren" title="Answering Questions">💬</a></td>
<td align="center"><a href="https://github.com/Akrai"><img src="https://avatars1.githubusercontent.com/u/5624597?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Akrai</b></sub></a><br /><a href="#ideas-Akrai" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/avtkal"><img src="https://avatars.githubusercontent.com/u/63205014?v=4?s=100" width="100px;" alt=""/><br /><sub><b>avtkal</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/avtkal"><img src="https://avatars.githubusercontent.com/u/63205014?v=4?s=100" width="100px;" alt=""/><br /><sub><b>avtkal</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/cizordj"><img src="https://avatars2.githubusercontent.com/u/32869222?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Cézar Augusto</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/dimitrist19"><img src="https://avatars.githubusercontent.com/u/56406468?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dimitris T</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/farzadx"><img src="https://avatars2.githubusercontent.com/u/70059397?v=4?s=100" width="100px;" alt=""/><br /><sub><b>farzadx</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/faydin"><img src="https://avatars2.githubusercontent.com/u/22706676?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fatih Aydın</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/fouze555"><img src="https://avatars3.githubusercontent.com/u/71935341?v=4?s=100" width="100px;" alt=""/><br /><sub><b>fouze555</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/Galang23"><img src="https://avatars3.githubusercontent.com/u/13700948?s=100" width="100px;" alt=""/><br /><sub><b>Galang23</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/Galang23"><img src="https://avatars3.githubusercontent.com/u/13700948?s=100" width="100px;" alt=""/><br /><sub><b>Galang23</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/initdebugs"><img src="https://avatars0.githubusercontent.com/u/75781464?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Initdebugs</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://janek.xyz/"><img src="https://avatars3.githubusercontent.com/u/8365659?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jakub Janek</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/GenosseFlosse"><img src="https://avatars.githubusercontent.com/u/59205524?v=4?s=100" width="100px;" alt=""/><br /><sub><b>GenosseFlosse</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://becauseofprog.fr/"><img src="https://avatars3.githubusercontent.com/u/24623168?s=100" width="100px;" alt=""/><br /><sub><b>kernoeb</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/MoaufmKlo"><img src="https://avatars1.githubusercontent.com/u/45636897?s=100" width="100px;" alt=""/><br /><sub><b>MoaufmKlo</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/nalinalini"><img src="https://avatars0.githubusercontent.com/u/65640431?v=4?s=100" width="100px;" alt=""/><br /><sub><b>nalinalini</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/nalinalini"><img src="https://avatars0.githubusercontent.com/u/65640431?v=4?s=100" width="100px;" alt=""/><br /><sub><b>nalinalini</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/peterge1998"><img src="https://avatars2.githubusercontent.com/u/47355238?s=100" width="100px;" alt=""/><br /><sub><b>peterge1998</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/PierreM0"><img src="https://avatars3.githubusercontent.com/u/71077853?v=4?s=100" width="100px;" alt=""/><br /><sub><b>PierreM0</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/RAMAR-RAR"><img src="https://avatars3.githubusercontent.com/u/47423745?s=100" width="100px;" alt=""/><br /><sub><b>RAMAR-RAR</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/rohang02"><img src="https://avatars3.githubusercontent.com/u/47921164?v=4?s=100" width="100px;" alt=""/><br /><sub><b>rohang02</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/retiolus"><img src="https://avatars1.githubusercontent.com/u/65604466?v=4?s=100" width="100px;" alt=""/><br /><sub><b>retiolus</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/rikishi0071"><img src="https://avatars3.githubusercontent.com/u/18183855?v=4?s=100" width="100px;" alt=""/><br /><sub><b>rikishi0071</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/rikishi0071"><img src="https://avatars3.githubusercontent.com/u/18183855?v=4?s=100" width="100px;" alt=""/><br /><sub><b>rikishi0071</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://gitlab.com/sandboiii"><img src="https://avatars.githubusercontent.com/u/17468894?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alexey Peschany</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://stillu.cc/"><img src="https://avatars2.githubusercontent.com/u/5843208?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Still Hsu</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/Lego8486"><img src="https://avatars1.githubusercontent.com/u/47414485?s=100" width="100px;" alt=""/><br /><sub><b>Ten_Lego</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/wagnim"><img src="https://avatars0.githubusercontent.com/u/30241419?s=100" width="100px;" alt=""/><br /><sub><b>wagnim</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/wokija"><img src="https://avatars.githubusercontent.com/u/14982166?v=4?s=100" width="100px;" alt=""/><br /><sub><b>wokija</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/ysakamoto"><img src="https://avatars3.githubusercontent.com/u/1331642?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ysakamoto</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/ysakamoto"><img src="https://avatars3.githubusercontent.com/u/1331642?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ysakamoto</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/ZDVokoun"><img src="https://avatars.githubusercontent.com/u/76393152?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ZDVokoun</b></sub></a><br /><a href="https://crowdin.com/project/instagrabber" title="Translation">🌍</a></td>
</tr>
</table>
@ -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 <https://www.gnu.org/licenses/>.
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)

View File

@ -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

View File

@ -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<NotificationModel, NotificationViewHolder> {
private final OnNotificationClickListener notificationClickListener;
private final MentionClickListener mentionClickListener;
private static final DiffUtil.ItemCallback<NotificationModel> DIFF_CALLBACK = new DiffUtil.ItemCallback<NotificationModel>() {
@Override
@ -34,11 +32,9 @@ public final class NotificationsAdapter extends ListAdapter<NotificationModel, N
}
};
public NotificationsAdapter(final OnNotificationClickListener notificationClickListener,
final MentionClickListener mentionClickListener) {
public NotificationsAdapter(final OnNotificationClickListener notificationClickListener) {
super(DIFF_CALLBACK);
this.notificationClickListener = notificationClickListener;
this.mentionClickListener = mentionClickListener;
}
@NonNull

View File

@ -32,7 +32,7 @@ public final class NotificationViewHolder extends RecyclerView.ViewHolder {
text = R.string.comment_notif;
subtext = model.getText();
break;
case MENTION:
case COMMENT_MENTION:
text = R.string.mention_notif;
subtext = model.getText();
break;

View File

@ -1,205 +0,0 @@
package awais.instagrabber.customviews;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.RectF;
import android.os.Handler;
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.BackgroundColorSpan;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatTextView;
import awais.instagrabber.R;
import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.utils.TextUtils;
@Deprecated
public final class RamboTextView extends AppCompatTextView {
private static final String TAG = "RamboTextView";
private static final int highlightBackgroundSpanKey = R.id.tvComment;
private static final RectF touchedLineBounds = new RectF();
private ClickableSpan clickableSpanUnderTouchOnActionDown;
private MentionClickListener mentionClickListener;
private boolean isUrlHighlighted;
private boolean isExpanded;
private OnLongClickListener longClickListener;
private final Handler handler = new Handler();
private final Runnable longPressRunnable = () -> {
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;
}
}

View File

@ -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<Media>() {
@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<FriendshipChangeResponse>() {
@ -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);

View File

@ -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);

View File

@ -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;
});
}

View File

@ -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);
}

View File

@ -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"),

View File

@ -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
}

View File

@ -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<String> extractUrls(final String text) {
if (isEmpty(text)) return Collections.emptyList();
final Matcher matcher = Patterns.WEB_URL.matcher(text);

View File

@ -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

View File

@ -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));
}

View File

@ -45,11 +45,11 @@
app:layout_constraintTop_toTopOf="parent"
tools:text="username" />
<awais.instagrabber.customviews.RamboTextView
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvComment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:linksClickable="true"
android:linksClickable="false"
android:paddingStart="16dp"
android:paddingLeft="16dp"
android:paddingEnd="16dp"
@ -62,13 +62,13 @@
app:layout_constraintTop_toBottomOf="@id/tvUsername"
tools:text="comment comment comment comment comment comment comment comment comment comment comment comment comment " />
<awais.instagrabber.customviews.RamboTextView
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvSubComment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:autoLink="web|email"
android:ellipsize="end"
android:linksClickable="true"
android:linksClickable="false"
android:paddingStart="16dp"
android:paddingLeft="16dp"
android:paddingEnd="8dp"

View File

@ -96,16 +96,13 @@
app:layout_constraintTop_toBottomOf="@id/locationFullName"
tools:text="IN THE MIDDLE OF OUR STREET" />
<awais.instagrabber.customviews.RamboTextView
<awais.instagrabber.customviews.RamboTextViewV2
android:id="@+id/locationUrl"
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/locationBiography"
android:layout_below="@id/mainBiography"
android:ellipsize="marquee"
android:paddingStart="8dp"
android:paddingLeft="8dp"
android:paddingEnd="8dp"
android:paddingRight="8dp"
android:padding="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
@ -113,5 +110,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/locationBiography"
tools:text="https://austinhuang.me/"
tools:textColor="@android:color/holo_blue_dark"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -12,8 +12,7 @@
<string name="clipboard_error">Error copying text</string>
<string name="clipboard_copied">Copied to clipboard!</string>
<string name="report">Report</string>
<string name="password">Password (Max 32 chars)</string>
<string name="set_password">Set a password (max 32 chars)</string>
<string name="set_password">Protect file with password</string>
<string name="password_no_max">Password</string>
<string name="ok">OK</string>
<string name="yes">Yes</string>
@ -319,9 +318,9 @@
<string name="locations">Locations</string>
<string name="unknown">Unknown</string>
<string name="removed_from_favs">Removed from Favourites</string>
<string name="backup_and_restore">Backup &amp; Restore User Settings</string>
<string name="backup_summary">Back up app settings, account login information, and/or favorites data to a plain text or encrypted backup file for later restoration.</string>
<string name="backup_warning">If you\'re backing up login info, treat the file as confidential: Keep them somewhere safe!</string>
<string name="backup_and_restore">Backup &amp; Restore</string>
<string name="backup_summary">Backup Barinsta app settings, account login data, and/or favorites to a plain text or encrypted backup file for later restoration.</string>
<string name="backup_warning">If you\'re backing up account login data, treat the file as confidential and keep it somewhere safe!</string>
<string name="create_backup">Create new backup file</string>
<string name="restore_backup">Restore from existing backup file</string>
<string name="file_chosen_label">File:</string>