mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-22 22:57:29 +00:00
notification backend revamp
This commit is contained in:
parent
5421bb4592
commit
7acd5faefd
@ -11,24 +11,25 @@ import androidx.recyclerview.widget.ListAdapter;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import awais.instagrabber.adapters.viewholder.NotificationViewHolder;
|
import awais.instagrabber.adapters.viewholder.NotificationViewHolder;
|
||||||
import awais.instagrabber.databinding.ItemNotificationBinding;
|
import awais.instagrabber.databinding.ItemNotificationBinding;
|
||||||
import awais.instagrabber.models.NotificationModel;
|
|
||||||
import awais.instagrabber.models.enums.NotificationType;
|
import awais.instagrabber.models.enums.NotificationType;
|
||||||
|
import awais.instagrabber.repositories.responses.Notification;
|
||||||
|
|
||||||
public final class NotificationsAdapter extends ListAdapter<NotificationModel, NotificationViewHolder> {
|
public final class NotificationsAdapter extends ListAdapter<Notification, NotificationViewHolder> {
|
||||||
private final OnNotificationClickListener notificationClickListener;
|
private final OnNotificationClickListener notificationClickListener;
|
||||||
|
|
||||||
private static final DiffUtil.ItemCallback<NotificationModel> DIFF_CALLBACK = new DiffUtil.ItemCallback<NotificationModel>() {
|
private static final DiffUtil.ItemCallback<Notification> DIFF_CALLBACK = new DiffUtil.ItemCallback<Notification>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean areItemsTheSame(@NonNull final NotificationModel oldItem, @NonNull final NotificationModel newItem) {
|
public boolean areItemsTheSame(@NonNull final Notification oldItem, @NonNull final Notification newItem) {
|
||||||
return oldItem.getId().equals(newItem.getId());
|
return oldItem.getPk().equals(newItem.getPk());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean areContentsTheSame(@NonNull final NotificationModel oldItem, @NonNull final NotificationModel newItem) {
|
public boolean areContentsTheSame(@NonNull final Notification oldItem, @NonNull final Notification newItem) {
|
||||||
return oldItem.getId().equals(newItem.getId());
|
return oldItem.getPk().equals(newItem.getPk());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -47,12 +48,12 @@ public final class NotificationsAdapter extends ListAdapter<NotificationModel, N
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull final NotificationViewHolder holder, final int position) {
|
public void onBindViewHolder(@NonNull final NotificationViewHolder holder, final int position) {
|
||||||
final NotificationModel notificationModel = getItem(position);
|
final Notification Notification = getItem(position);
|
||||||
holder.bind(notificationModel, notificationClickListener);
|
holder.bind(Notification, notificationClickListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void submitList(@Nullable final List<NotificationModel> list, @Nullable final Runnable commitCallback) {
|
public void submitList(@Nullable final List<Notification> list, @Nullable final Runnable commitCallback) {
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
super.submitList(null, commitCallback);
|
super.submitList(null, commitCallback);
|
||||||
return;
|
return;
|
||||||
@ -61,7 +62,7 @@ public final class NotificationsAdapter extends ListAdapter<NotificationModel, N
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void submitList(@Nullable final List<NotificationModel> list) {
|
public void submitList(@Nullable final List<Notification> list) {
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
super.submitList(null);
|
super.submitList(null);
|
||||||
return;
|
return;
|
||||||
@ -69,8 +70,10 @@ public final class NotificationsAdapter extends ListAdapter<NotificationModel, N
|
|||||||
super.submitList(sort(list));
|
super.submitList(sort(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<NotificationModel> sort(final List<NotificationModel> list) {
|
private List<Notification> sort(final List<Notification> list) {
|
||||||
final List<NotificationModel> listCopy = new ArrayList<>(list);
|
final List<Notification> listCopy = new ArrayList<>(list).stream()
|
||||||
|
.filter(i -> i.getType() != null)
|
||||||
|
.collect(Collectors.toList());
|
||||||
Collections.sort(listCopy, (o1, o2) -> {
|
Collections.sort(listCopy, (o1, o2) -> {
|
||||||
// keep requests at top
|
// keep requests at top
|
||||||
if (o1.getType() == o2.getType()
|
if (o1.getType() == o2.getType()
|
||||||
@ -79,16 +82,16 @@ public final class NotificationsAdapter extends ListAdapter<NotificationModel, N
|
|||||||
else if (o1.getType() == NotificationType.REQUEST) return -1;
|
else if (o1.getType() == NotificationType.REQUEST) return -1;
|
||||||
else if (o2.getType() == NotificationType.REQUEST) return 1;
|
else if (o2.getType() == NotificationType.REQUEST) return 1;
|
||||||
// timestamp
|
// timestamp
|
||||||
return Long.compare(o2.getTimestamp(), o1.getTimestamp());
|
return Double.compare(o2.getArgs().getTimestamp(), o1.getArgs().getTimestamp());
|
||||||
});
|
});
|
||||||
return listCopy;
|
return listCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface OnNotificationClickListener {
|
public interface OnNotificationClickListener {
|
||||||
void onNotificationClick(final NotificationModel model);
|
void onNotificationClick(final Notification model);
|
||||||
|
|
||||||
void onProfileClick(final String username);
|
void onProfileClick(final String username);
|
||||||
|
|
||||||
void onPreviewClick(final NotificationModel model);
|
void onPreviewClick(final Notification model);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,8 +8,9 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||||||
import awais.instagrabber.R;
|
import awais.instagrabber.R;
|
||||||
import awais.instagrabber.adapters.NotificationsAdapter.OnNotificationClickListener;
|
import awais.instagrabber.adapters.NotificationsAdapter.OnNotificationClickListener;
|
||||||
import awais.instagrabber.databinding.ItemNotificationBinding;
|
import awais.instagrabber.databinding.ItemNotificationBinding;
|
||||||
import awais.instagrabber.models.NotificationModel;
|
|
||||||
import awais.instagrabber.models.enums.NotificationType;
|
import awais.instagrabber.models.enums.NotificationType;
|
||||||
|
import awais.instagrabber.repositories.responses.Notification;
|
||||||
|
import awais.instagrabber.repositories.responses.NotificationArgs;
|
||||||
|
|
||||||
public final class NotificationViewHolder extends RecyclerView.ViewHolder {
|
public final class NotificationViewHolder extends RecyclerView.ViewHolder {
|
||||||
private final ItemNotificationBinding binding;
|
private final ItemNotificationBinding binding;
|
||||||
@ -19,22 +20,23 @@ public final class NotificationViewHolder extends RecyclerView.ViewHolder {
|
|||||||
this.binding = binding;
|
this.binding = binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(final NotificationModel model,
|
public void bind(final Notification model,
|
||||||
final OnNotificationClickListener notificationClickListener) {
|
final OnNotificationClickListener notificationClickListener) {
|
||||||
if (model == null) return;
|
if (model == null) return;
|
||||||
int text = -1;
|
int text = -1;
|
||||||
CharSequence subtext = null;
|
CharSequence subtext = null;
|
||||||
|
final NotificationArgs args = model.getArgs();
|
||||||
switch (model.getType()) {
|
switch (model.getType()) {
|
||||||
case LIKE:
|
case LIKE:
|
||||||
text = R.string.liked_notif;
|
text = R.string.liked_notif;
|
||||||
break;
|
break;
|
||||||
case COMMENT:
|
case COMMENT:
|
||||||
text = R.string.comment_notif;
|
text = R.string.comment_notif;
|
||||||
subtext = model.getText();
|
subtext = args.getText();
|
||||||
break;
|
break;
|
||||||
case COMMENT_MENTION:
|
case COMMENT_MENTION:
|
||||||
text = R.string.mention_notif;
|
text = R.string.mention_notif;
|
||||||
subtext = model.getText();
|
subtext = args.getText();
|
||||||
break;
|
break;
|
||||||
case TAGGED:
|
case TAGGED:
|
||||||
text = R.string.tagged_notif;
|
text = R.string.tagged_notif;
|
||||||
@ -44,18 +46,18 @@ public final class NotificationViewHolder extends RecyclerView.ViewHolder {
|
|||||||
break;
|
break;
|
||||||
case REQUEST:
|
case REQUEST:
|
||||||
text = R.string.request_notif;
|
text = R.string.request_notif;
|
||||||
subtext = model.getText();
|
subtext = args.getText();
|
||||||
break;
|
break;
|
||||||
case COMMENT_LIKE:
|
case COMMENT_LIKE:
|
||||||
case TAGGED_COMMENT:
|
case TAGGED_COMMENT:
|
||||||
case RESPONDED_STORY:
|
case RESPONDED_STORY:
|
||||||
subtext = model.getText();
|
subtext = args.getText();
|
||||||
break;
|
break;
|
||||||
case AYML:
|
case AYML:
|
||||||
subtext = model.getPreviewPic();
|
subtext = args.getFullName();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
binding.tvSubComment.setText(model.getType() == NotificationType.AYML ? model.getText() : subtext);
|
binding.tvSubComment.setText(model.getType() == NotificationType.AYML ? args.getText() : subtext);
|
||||||
if (text == -1 && subtext != null) {
|
if (text == -1 && subtext != null) {
|
||||||
binding.tvComment.setText(subtext);
|
binding.tvComment.setText(subtext);
|
||||||
binding.tvComment.setVisibility(TextUtils.isEmpty(subtext) ? View.GONE : View.VISIBLE);
|
binding.tvComment.setVisibility(TextUtils.isEmpty(subtext) ? View.GONE : View.VISIBLE);
|
||||||
@ -65,24 +67,25 @@ public final class NotificationViewHolder extends RecyclerView.ViewHolder {
|
|||||||
binding.tvSubComment.setVisibility(subtext == null ? View.GONE : View.VISIBLE);
|
binding.tvSubComment.setVisibility(subtext == null ? View.GONE : View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.tvDate.setVisibility(model.getType() == NotificationType.AYML ? View.GONE : View.VISIBLE);
|
||||||
if (model.getType() != NotificationType.REQUEST && model.getType() != NotificationType.AYML) {
|
if (model.getType() != NotificationType.REQUEST && model.getType() != NotificationType.AYML) {
|
||||||
binding.tvDate.setText(model.getDateTime());
|
binding.tvDate.setText(args.getDateTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.tvUsername.setText(model.getUsername());
|
binding.tvUsername.setText(args.getUsername());
|
||||||
binding.ivProfilePic.setImageURI(model.getProfilePic());
|
binding.ivProfilePic.setImageURI(args.getProfilePic());
|
||||||
binding.ivProfilePic.setOnClickListener(v -> {
|
binding.ivProfilePic.setOnClickListener(v -> {
|
||||||
if (notificationClickListener == null) return;
|
if (notificationClickListener == null) return;
|
||||||
notificationClickListener.onProfileClick(model.getUsername());
|
notificationClickListener.onProfileClick(args.getUsername());
|
||||||
});
|
});
|
||||||
|
|
||||||
if (model.getType() == NotificationType.AYML) {
|
if (model.getType() == NotificationType.AYML) {
|
||||||
binding.ivPreviewPic.setVisibility(View.GONE);
|
binding.ivPreviewPic.setVisibility(View.GONE);
|
||||||
} else if (TextUtils.isEmpty(model.getPreviewPic())) {
|
} else if (args.getMedia() == null) {
|
||||||
binding.ivPreviewPic.setVisibility(View.INVISIBLE);
|
binding.ivPreviewPic.setVisibility(View.INVISIBLE);
|
||||||
} else {
|
} else {
|
||||||
binding.ivPreviewPic.setVisibility(View.VISIBLE);
|
binding.ivPreviewPic.setVisibility(View.VISIBLE);
|
||||||
binding.ivPreviewPic.setImageURI(model.getPreviewPic());
|
binding.ivPreviewPic.setImageURI(args.getMedia().get(0).getImage());
|
||||||
binding.ivPreviewPic.setOnClickListener(v -> {
|
binding.ivPreviewPic.setOnClickListener(v -> {
|
||||||
if (notificationClickListener == null) return;
|
if (notificationClickListener == null) return;
|
||||||
notificationClickListener.onPreviewClick(model);
|
notificationClickListener.onPreviewClick(model);
|
||||||
|
@ -1,139 +0,0 @@
|
|||||||
package awais.instagrabber.asyncs;
|
|
||||||
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
import awais.instagrabber.utils.Constants;
|
|
||||||
import awais.instagrabber.utils.CookieUtils;
|
|
||||||
import awais.instagrabber.utils.NetworkUtils;
|
|
||||||
import awais.instagrabber.utils.TextUtils;
|
|
||||||
import awais.instagrabber.utils.Utils;
|
|
||||||
|
|
||||||
public class GetActivityAsyncTask extends AsyncTask<String, Void, GetActivityAsyncTask.NotificationCounts> {
|
|
||||||
private static final String TAG = "GetActivityAsyncTask";
|
|
||||||
|
|
||||||
private final OnTaskCompleteListener onTaskCompleteListener;
|
|
||||||
|
|
||||||
public GetActivityAsyncTask(final OnTaskCompleteListener onTaskCompleteListener) {
|
|
||||||
this.onTaskCompleteListener = onTaskCompleteListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
This needs to be redone to fetch i inbox instead
|
|
||||||
Within inbox, data is (body JSON => counts)
|
|
||||||
Then we have these counts:
|
|
||||||
new_posts, activity_feed_dot_badge, relationships, campaign_notification
|
|
||||||
usertags, likes, comment_likes, shopping_notification, comments
|
|
||||||
photos_of_you (not sure about difference to usertags), requests
|
|
||||||
*/
|
|
||||||
|
|
||||||
protected NotificationCounts doInBackground(final String... cookiesArray) {
|
|
||||||
if (cookiesArray == null) return null;
|
|
||||||
final String cookie = cookiesArray[0];
|
|
||||||
if (TextUtils.isEmpty(cookie)) return null;
|
|
||||||
final long uid = CookieUtils.getUserIdFromCookie(cookie);
|
|
||||||
final String url = "https://www.instagram.com/graphql/query/?query_hash=0f318e8cfff9cc9ef09f88479ff571fb"
|
|
||||||
+ "&variables={\"id\":\"" + uid + "\"}";
|
|
||||||
HttpURLConnection urlConnection = null;
|
|
||||||
try {
|
|
||||||
urlConnection = (HttpURLConnection) new URL(url).openConnection();
|
|
||||||
urlConnection.setUseCaches(false);
|
|
||||||
urlConnection.setRequestProperty("User-Agent", Utils.settingsHelper.getString(Constants.BROWSER_UA));
|
|
||||||
urlConnection.setRequestProperty("x-csrftoken", cookie.split("csrftoken=")[1].split(";")[0]);
|
|
||||||
urlConnection.connect();
|
|
||||||
if (urlConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final JSONObject data = new JSONObject(NetworkUtils.readFromConnection(urlConnection))
|
|
||||||
.getJSONObject("data")
|
|
||||||
.getJSONObject("user")
|
|
||||||
.getJSONObject("edge_activity_count")
|
|
||||||
.getJSONArray("edges")
|
|
||||||
.getJSONObject(0)
|
|
||||||
.getJSONObject("node");
|
|
||||||
return new NotificationCounts(
|
|
||||||
data.getInt("relationships"),
|
|
||||||
data.getInt("usertags"),
|
|
||||||
data.getInt("comments"),
|
|
||||||
data.getInt("comment_likes"),
|
|
||||||
data.getInt("likes")
|
|
||||||
);
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
Log.e(TAG, "Error", ex);
|
|
||||||
} finally {
|
|
||||||
if (urlConnection != null) {
|
|
||||||
urlConnection.disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(final NotificationCounts result) {
|
|
||||||
if (onTaskCompleteListener == null) return;
|
|
||||||
onTaskCompleteListener.onTaskComplete(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class NotificationCounts {
|
|
||||||
private final int relationshipsCount;
|
|
||||||
private final int userTagsCount;
|
|
||||||
private final int commentsCount;
|
|
||||||
private final int commentLikesCount;
|
|
||||||
private final int likesCount;
|
|
||||||
|
|
||||||
public NotificationCounts(final int relationshipsCount,
|
|
||||||
final int userTagsCount,
|
|
||||||
final int commentsCount,
|
|
||||||
final int commentLikesCount,
|
|
||||||
final int likesCount) {
|
|
||||||
this.relationshipsCount = relationshipsCount;
|
|
||||||
this.userTagsCount = userTagsCount;
|
|
||||||
this.commentsCount = commentsCount;
|
|
||||||
this.commentLikesCount = commentLikesCount;
|
|
||||||
this.likesCount = likesCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRelationshipsCount() {
|
|
||||||
return relationshipsCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getUserTagsCount() {
|
|
||||||
return userTagsCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCommentsCount() {
|
|
||||||
return commentsCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCommentLikesCount() {
|
|
||||||
return commentLikesCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLikesCount() {
|
|
||||||
return likesCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "NotificationCounts{" +
|
|
||||||
"relationshipsCount=" + relationshipsCount +
|
|
||||||
", userTagsCount=" + userTagsCount +
|
|
||||||
", commentsCount=" + commentsCount +
|
|
||||||
", commentLikesCount=" + commentLikesCount +
|
|
||||||
", likesCount=" + likesCount +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface OnTaskCompleteListener {
|
|
||||||
void onTaskComplete(final NotificationCounts result);
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,35 +8,35 @@ import java.util.List;
|
|||||||
|
|
||||||
import awais.instagrabber.BuildConfig;
|
import awais.instagrabber.BuildConfig;
|
||||||
import awais.instagrabber.interfaces.FetchListener;
|
import awais.instagrabber.interfaces.FetchListener;
|
||||||
import awais.instagrabber.models.NotificationModel;
|
import awais.instagrabber.repositories.responses.Notification;
|
||||||
import awais.instagrabber.webservices.NewsService;
|
import awais.instagrabber.webservices.NewsService;
|
||||||
import awais.instagrabber.webservices.ServiceCallback;
|
import awais.instagrabber.webservices.ServiceCallback;
|
||||||
import awaisomereport.LogCollector;
|
import awaisomereport.LogCollector;
|
||||||
|
|
||||||
import static awais.instagrabber.utils.Utils.logCollector;
|
import static awais.instagrabber.utils.Utils.logCollector;
|
||||||
|
|
||||||
public final class NotificationsFetcher extends AsyncTask<Void, Void, List<NotificationModel>> {
|
public final class NotificationsFetcher extends AsyncTask<Void, Void, List<Notification>> {
|
||||||
private static final String TAG = "NotificationsFetcher";
|
private static final String TAG = "NotificationsFetcher";
|
||||||
|
|
||||||
private final FetchListener<List<NotificationModel>> fetchListener;
|
private final FetchListener<List<Notification>> fetchListener;
|
||||||
private final NewsService newsService;
|
private final NewsService newsService;
|
||||||
private final boolean markAsSeen;
|
private final boolean markAsSeen;
|
||||||
private boolean fetchedWeb = false;
|
private boolean fetchedWeb = false;
|
||||||
|
|
||||||
public NotificationsFetcher(final boolean markAsSeen,
|
public NotificationsFetcher(final boolean markAsSeen,
|
||||||
final FetchListener<List<NotificationModel>> fetchListener) {
|
final FetchListener<List<Notification>> fetchListener) {
|
||||||
this.markAsSeen = markAsSeen;
|
this.markAsSeen = markAsSeen;
|
||||||
this.fetchListener = fetchListener;
|
this.fetchListener = fetchListener;
|
||||||
newsService = NewsService.getInstance();
|
newsService = NewsService.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<NotificationModel> doInBackground(final Void... voids) {
|
protected List<Notification> doInBackground(final Void... voids) {
|
||||||
List<NotificationModel> notificationModels = new ArrayList<>();
|
List<Notification> notificationModels = new ArrayList<>();
|
||||||
|
|
||||||
newsService.fetchAppInbox(markAsSeen, new ServiceCallback<List<NotificationModel>>() {
|
newsService.fetchAppInbox(markAsSeen, new ServiceCallback<List<Notification>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final List<NotificationModel> result) {
|
public void onSuccess(final List<Notification> result) {
|
||||||
if (result == null) return;
|
if (result == null) return;
|
||||||
notificationModels.addAll(result);
|
notificationModels.addAll(result);
|
||||||
if (fetchedWeb) {
|
if (fetchedWeb) {
|
||||||
@ -44,7 +44,7 @@ public final class NotificationsFetcher extends AsyncTask<Void, Void, List<Notif
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fetchedWeb = true;
|
fetchedWeb = true;
|
||||||
newsService.fetchWebInbox(markAsSeen, this);
|
newsService.fetchWebInbox(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,11 +33,13 @@ import awais.instagrabber.asyncs.NotificationsFetcher;
|
|||||||
import awais.instagrabber.databinding.FragmentNotificationsViewerBinding;
|
import awais.instagrabber.databinding.FragmentNotificationsViewerBinding;
|
||||||
import awais.instagrabber.fragments.settings.MorePreferencesFragmentDirections;
|
import awais.instagrabber.fragments.settings.MorePreferencesFragmentDirections;
|
||||||
import awais.instagrabber.interfaces.FetchListener;
|
import awais.instagrabber.interfaces.FetchListener;
|
||||||
import awais.instagrabber.models.NotificationModel;
|
|
||||||
import awais.instagrabber.models.enums.NotificationType;
|
import awais.instagrabber.models.enums.NotificationType;
|
||||||
import awais.instagrabber.repositories.requests.StoryViewerOptions;
|
import awais.instagrabber.repositories.requests.StoryViewerOptions;
|
||||||
import awais.instagrabber.repositories.responses.FriendshipChangeResponse;
|
import awais.instagrabber.repositories.responses.FriendshipChangeResponse;
|
||||||
import awais.instagrabber.repositories.responses.Media;
|
import awais.instagrabber.repositories.responses.Media;
|
||||||
|
import awais.instagrabber.repositories.responses.Notification;
|
||||||
|
import awais.instagrabber.repositories.responses.NotificationArgs;
|
||||||
|
import awais.instagrabber.repositories.responses.NotificationImage;
|
||||||
import awais.instagrabber.utils.Constants;
|
import awais.instagrabber.utils.Constants;
|
||||||
import awais.instagrabber.utils.CookieUtils;
|
import awais.instagrabber.utils.CookieUtils;
|
||||||
import awais.instagrabber.utils.TextUtils;
|
import awais.instagrabber.utils.TextUtils;
|
||||||
@ -70,14 +72,18 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPreviewClick(final NotificationModel model) {
|
public void onPreviewClick(final Notification model) {
|
||||||
|
final NotificationImage notificationImage = model.getArgs().getMedia().get(0);
|
||||||
|
final long mediaId = Long.valueOf(notificationImage.getId().split("_")[0]);
|
||||||
if (model.getType() == NotificationType.RESPONDED_STORY) {
|
if (model.getType() == NotificationType.RESPONDED_STORY) {
|
||||||
final NavDirections action = NotificationsViewerFragmentDirections
|
final NavDirections action = NotificationsViewerFragmentDirections
|
||||||
.actionNotificationsViewerFragmentToStoryViewerFragment(StoryViewerOptions.forStory(model.getPostId(),
|
.actionNotificationsViewerFragmentToStoryViewerFragment(
|
||||||
model.getUsername()));
|
StoryViewerOptions.forStory(
|
||||||
|
mediaId,
|
||||||
|
model.getArgs().getUsername()));
|
||||||
NavHostFragment.findNavController(NotificationsViewerFragment.this).navigate(action);
|
NavHostFragment.findNavController(NotificationsViewerFragment.this).navigate(action);
|
||||||
} else {
|
} else {
|
||||||
mediaService.fetch(model.getPostId(), new ServiceCallback<Media>() {
|
mediaService.fetch(mediaId, new ServiceCallback<Media>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final Media feedModel) {
|
public void onSuccess(final Media feedModel) {
|
||||||
final PostViewV2Fragment fragment = PostViewV2Fragment
|
final PostViewV2Fragment fragment = PostViewV2Fragment
|
||||||
@ -95,13 +101,14 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNotificationClick(final NotificationModel model) {
|
public void onNotificationClick(final Notification model) {
|
||||||
if (model == null) return;
|
if (model == null) return;
|
||||||
final String username = model.getUsername();
|
final NotificationArgs args = model.getArgs();
|
||||||
|
final String username = args.getUsername();
|
||||||
if (model.getType() == NotificationType.FOLLOW || model.getType() == NotificationType.AYML) {
|
if (model.getType() == NotificationType.FOLLOW || model.getType() == NotificationType.AYML) {
|
||||||
openProfile(username);
|
openProfile(username);
|
||||||
} else {
|
} else {
|
||||||
final SpannableString title = new SpannableString(username + (TextUtils.isEmpty(model.getText()) ? "" : (":\n" + model.getText())));
|
final SpannableString title = new SpannableString(username + (TextUtils.isEmpty(args.getText()) ? "" : (":\n" + args.getText())));
|
||||||
title.setSpan(new RelativeSizeSpan(1.23f), 0, username.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
title.setSpan(new RelativeSizeSpan(1.23f), 0, username.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
||||||
|
|
||||||
String[] commentDialogList;
|
String[] commentDialogList;
|
||||||
@ -110,7 +117,7 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
|||||||
getString(R.string.open_profile),
|
getString(R.string.open_profile),
|
||||||
getString(R.string.view_story)
|
getString(R.string.view_story)
|
||||||
};
|
};
|
||||||
} else if (model.getPostId() > 0) {
|
} else if (args.getMedia() != null) {
|
||||||
commentDialogList = new String[]{
|
commentDialogList = new String[]{
|
||||||
getString(R.string.open_profile),
|
getString(R.string.open_profile),
|
||||||
getString(R.string.view_post)
|
getString(R.string.view_post)
|
||||||
@ -131,7 +138,7 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
|||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (model.getType() == NotificationType.REQUEST) {
|
if (model.getType() == NotificationType.REQUEST) {
|
||||||
friendshipService.approve(model.getUserId(), new ServiceCallback<FriendshipChangeResponse>() {
|
friendshipService.approve(args.getUserId(), new ServiceCallback<FriendshipChangeResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final FriendshipChangeResponse result) {
|
public void onSuccess(final FriendshipChangeResponse result) {
|
||||||
onRefresh();
|
onRefresh();
|
||||||
@ -148,7 +155,7 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
|||||||
clickListener.onPreviewClick(model);
|
clickListener.onPreviewClick(model);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
friendshipService.ignore(model.getUserId(), new ServiceCallback<FriendshipChangeResponse>() {
|
friendshipService.ignore(args.getUserId(), new ServiceCallback<FriendshipChangeResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final FriendshipChangeResponse result) {
|
public void onSuccess(final FriendshipChangeResponse result) {
|
||||||
onRefresh();
|
onRefresh();
|
||||||
@ -226,9 +233,9 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
|||||||
binding.swipeRefreshLayout.setRefreshing(true);
|
binding.swipeRefreshLayout.setRefreshing(true);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "notif":
|
case "notif":
|
||||||
new NotificationsFetcher(true, new FetchListener<List<NotificationModel>>() {
|
new NotificationsFetcher(true, new FetchListener<List<Notification>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(final List<NotificationModel> notificationModels) {
|
public void onResult(final List<Notification> notificationModels) {
|
||||||
binding.swipeRefreshLayout.setRefreshing(false);
|
binding.swipeRefreshLayout.setRefreshing(false);
|
||||||
notificationViewModel.getList().postValue(notificationModels);
|
notificationViewModel.getList().postValue(notificationModels);
|
||||||
}
|
}
|
||||||
@ -245,9 +252,9 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
|||||||
break;
|
break;
|
||||||
case "ayml":
|
case "ayml":
|
||||||
final NewsService newsService = NewsService.getInstance();
|
final NewsService newsService = NewsService.getInstance();
|
||||||
newsService.fetchSuggestions(csrfToken, new ServiceCallback<List<NotificationModel>>() {
|
newsService.fetchSuggestions(csrfToken, new ServiceCallback<List<Notification>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final List<NotificationModel> notificationModels) {
|
public void onSuccess(final List<Notification> notificationModels) {
|
||||||
binding.swipeRefreshLayout.setRefreshing(false);
|
binding.swipeRefreshLayout.setRefreshing(false);
|
||||||
notificationViewModel.getList().postValue(notificationModels);
|
notificationViewModel.getList().postValue(notificationModels);
|
||||||
}
|
}
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
package awais.instagrabber.models;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import awais.instagrabber.models.enums.NotificationType;
|
|
||||||
import awais.instagrabber.utils.Utils;
|
|
||||||
|
|
||||||
public final class NotificationModel {
|
|
||||||
private final String id;
|
|
||||||
private final long userId;
|
|
||||||
private final String username;
|
|
||||||
private final String profilePicUrl;
|
|
||||||
private final long postId;
|
|
||||||
private final String previewUrl;
|
|
||||||
private final NotificationType type;
|
|
||||||
private final CharSequence text;
|
|
||||||
private final long timestamp;
|
|
||||||
|
|
||||||
public NotificationModel(final String id,
|
|
||||||
final String text,
|
|
||||||
final long timestamp,
|
|
||||||
final long userId,
|
|
||||||
final String username,
|
|
||||||
final String profilePicUrl,
|
|
||||||
final long postId,
|
|
||||||
final String previewUrl,
|
|
||||||
final NotificationType type) {
|
|
||||||
this.id = id;
|
|
||||||
this.text = text;
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
this.userId = userId;
|
|
||||||
this.username = username;
|
|
||||||
this.profilePicUrl = profilePicUrl;
|
|
||||||
this.postId = postId;
|
|
||||||
this.previewUrl = previewUrl;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CharSequence getText() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTimestamp() {
|
|
||||||
return timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public String getDateTime() {
|
|
||||||
return Utils.datetimeParser.format(new Date(timestamp * 1000L));
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getUserId() {
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProfilePic() {
|
|
||||||
return profilePicUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getPostId() {
|
|
||||||
return postId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPreviewPic() {
|
|
||||||
return previewUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NotificationType getType() { return type; }
|
|
||||||
}
|
|
@ -2,6 +2,8 @@ package awais.instagrabber.repositories;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import awais.instagrabber.repositories.responses.AymlResponse;
|
||||||
|
import awais.instagrabber.repositories.responses.NewsInboxResponse;
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.http.FieldMap;
|
import retrofit2.http.FieldMap;
|
||||||
import retrofit2.http.FormUrlEncoded;
|
import retrofit2.http.FormUrlEncoded;
|
||||||
@ -16,9 +18,9 @@ public interface NewsRepository {
|
|||||||
Call<String> webInbox(@Header("User-Agent") String userAgent);
|
Call<String> webInbox(@Header("User-Agent") String userAgent);
|
||||||
|
|
||||||
@GET("/api/v1/news/inbox/")
|
@GET("/api/v1/news/inbox/")
|
||||||
Call<String> appInbox(@Header("User-Agent") String userAgent, @Query(value = "mark_as_seen", encoded = true) boolean markAsSeen);
|
Call<NewsInboxResponse> appInbox(@Header("User-Agent") String userAgent, @Query(value = "mark_as_seen", encoded = true) boolean markAsSeen);
|
||||||
|
|
||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
@POST("/api/v1/discover/ayml/")
|
@POST("/api/v1/discover/ayml/")
|
||||||
Call<String> getAyml(@Header("User-Agent") String userAgent, @FieldMap final Map<String, String> form);
|
Call<AymlResponse> getAyml(@Header("User-Agent") String userAgent, @FieldMap final Map<String, String> form);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package awais.instagrabber.repositories.responses;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AymlResponse {
|
||||||
|
private final AymlUserList newSuggestedUsers;
|
||||||
|
private final AymlUserList suggestedUsers;
|
||||||
|
|
||||||
|
public AymlResponse(final AymlUserList newSuggestedUsers,
|
||||||
|
final AymlUserList suggestedUsers) {
|
||||||
|
this.newSuggestedUsers = newSuggestedUsers;
|
||||||
|
this.suggestedUsers = suggestedUsers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AymlUserList getNewSuggestedUsers() {
|
||||||
|
return newSuggestedUsers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AymlUserList getSuggestedUsers() {
|
||||||
|
return suggestedUsers;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package awais.instagrabber.repositories.responses;
|
||||||
|
|
||||||
|
public class AymlUser {
|
||||||
|
private final User user;
|
||||||
|
private final String algorithm;
|
||||||
|
private final String socialContext;
|
||||||
|
private final String uuid;
|
||||||
|
|
||||||
|
public AymlUser(final User user,
|
||||||
|
final String algorithm,
|
||||||
|
final String socialContext,
|
||||||
|
final String uuid) {
|
||||||
|
this.user = user;
|
||||||
|
this.algorithm = algorithm;
|
||||||
|
this.socialContext = socialContext;
|
||||||
|
this.uuid = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlgorithm() {
|
||||||
|
return algorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSocialContext() {
|
||||||
|
return socialContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUuid() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package awais.instagrabber.repositories.responses;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AymlUserList {
|
||||||
|
private final List<AymlUser> suggestions;
|
||||||
|
|
||||||
|
public AymlUserList(final List<AymlUser> suggestions) {
|
||||||
|
this.suggestions = suggestions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AymlUser> getSuggestions() {
|
||||||
|
return suggestions;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package awais.instagrabber.repositories.responses;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class NewsInboxResponse {
|
||||||
|
private final NotificationCounts counts;
|
||||||
|
private final List<Notification> newStories;
|
||||||
|
private final List<Notification> oldStories;
|
||||||
|
|
||||||
|
public NewsInboxResponse(final NotificationCounts counts,
|
||||||
|
final List<Notification> newStories,
|
||||||
|
final List<Notification> oldStories) {
|
||||||
|
this.counts = counts;
|
||||||
|
this.newStories = newStories;
|
||||||
|
this.oldStories = oldStories;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotificationCounts getCounts() {
|
||||||
|
return counts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Notification> getNewStories() {
|
||||||
|
return newStories;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Notification> getOldStories() {
|
||||||
|
return oldStories;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package awais.instagrabber.repositories.responses;
|
||||||
|
|
||||||
|
import awais.instagrabber.models.enums.NotificationType;
|
||||||
|
|
||||||
|
public class Notification {
|
||||||
|
private final NotificationArgs args;
|
||||||
|
private final String storyType;
|
||||||
|
private final String pk;
|
||||||
|
|
||||||
|
public Notification(final NotificationArgs args,
|
||||||
|
final String storyType,
|
||||||
|
final String pk) {
|
||||||
|
this.args = args;
|
||||||
|
this.storyType = storyType;
|
||||||
|
this.pk = pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotificationArgs getArgs() {
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotificationType getType() {
|
||||||
|
return NotificationType.valueOfType(storyType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPk() {
|
||||||
|
return pk;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package awais.instagrabber.repositories.responses;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import awais.instagrabber.utils.Utils;
|
||||||
|
|
||||||
|
public class NotificationArgs {
|
||||||
|
private final String text;
|
||||||
|
private final String richText;
|
||||||
|
private final long profileId;
|
||||||
|
private final String profileImage;
|
||||||
|
private final List<NotificationImage> media;
|
||||||
|
private final double timestamp;
|
||||||
|
private final String profileName;
|
||||||
|
private final String fullName; // for AYML, not naturally generated
|
||||||
|
|
||||||
|
public NotificationArgs(final String text,
|
||||||
|
final String richText, // for AYML, this is the algorithm
|
||||||
|
final long profileId,
|
||||||
|
final String profileImage,
|
||||||
|
final List<NotificationImage> media,
|
||||||
|
final double timestamp,
|
||||||
|
final String profileName,
|
||||||
|
final String fullName) {
|
||||||
|
this.text = text;
|
||||||
|
this.richText = richText;
|
||||||
|
this.profileId = profileId;
|
||||||
|
this.profileImage = profileImage;
|
||||||
|
this.media = media;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
this.profileName = profileName;
|
||||||
|
this.fullName = fullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text == null ? cleanRichText(richText) : text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getUserId() {
|
||||||
|
return profileId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProfilePic() {
|
||||||
|
return profileImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return profileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFullName() {
|
||||||
|
return fullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<NotificationImage> getMedia() {
|
||||||
|
return media;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String getDateTime() {
|
||||||
|
return Utils.datetimeParser.format(new Date(Math.round(timestamp * 1000)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String cleanRichText(final String raw) {
|
||||||
|
if (raw == null) return null;
|
||||||
|
final Matcher matcher = Pattern.compile("\\{[\\p{L}\\d._]+\\|000000\\|1\\|user\\?id=\\d+\\}").matcher(raw);
|
||||||
|
String result = raw;
|
||||||
|
while (matcher.find()) {
|
||||||
|
final String richObject = raw.substring(matcher.start(), matcher.end());
|
||||||
|
final String username = richObject.split("\\|")[0].substring(1);
|
||||||
|
result = result.replace(richObject, username);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package awais.instagrabber.repositories.responses;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
public class NotificationCounts {
|
||||||
|
private final int commentLikes;
|
||||||
|
private final int usertags;
|
||||||
|
private final int likes;
|
||||||
|
private final int comments;
|
||||||
|
private final int relationships;
|
||||||
|
private final int photosOfYou;
|
||||||
|
private final int requests;
|
||||||
|
|
||||||
|
public NotificationCounts(final int commentLikes,
|
||||||
|
final int usertags,
|
||||||
|
final int likes,
|
||||||
|
final int comments,
|
||||||
|
final int relationships,
|
||||||
|
final int photosOfYou,
|
||||||
|
final int requests) {
|
||||||
|
this.commentLikes = commentLikes;
|
||||||
|
this.usertags = usertags;
|
||||||
|
this.likes = likes;
|
||||||
|
this.comments = comments;
|
||||||
|
this.relationships = relationships;
|
||||||
|
this.photosOfYou = photosOfYou;
|
||||||
|
this.requests = requests;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRelationshipsCount() {
|
||||||
|
return relationships;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUserTagsCount() {
|
||||||
|
return usertags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCommentsCount() {
|
||||||
|
return comments;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCommentLikesCount() {
|
||||||
|
return commentLikes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLikesCount() {
|
||||||
|
return likes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPOYCount() {
|
||||||
|
return photosOfYou;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRequestsCount() {
|
||||||
|
return requests;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package awais.instagrabber.repositories.responses;
|
||||||
|
|
||||||
|
public class NotificationImage {
|
||||||
|
private final String id;
|
||||||
|
private final String image;
|
||||||
|
|
||||||
|
public NotificationImage(final String id, final String image) {
|
||||||
|
this.id = id;
|
||||||
|
this.image = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getImage() {
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
}
|
@ -1,49 +0,0 @@
|
|||||||
package awais.instagrabber.repositories.responses;
|
|
||||||
|
|
||||||
public class UserInfo {
|
|
||||||
private final long pk;
|
|
||||||
private final String username, fullName, profilePicUrl, hdProfilePicUrl;
|
|
||||||
|
|
||||||
public UserInfo(final long pk,
|
|
||||||
final String username,
|
|
||||||
final String fullName,
|
|
||||||
final String profilePicUrl,
|
|
||||||
final String hdProfilePicUrl) {
|
|
||||||
this.pk = pk;
|
|
||||||
this.username = username;
|
|
||||||
this.fullName = fullName;
|
|
||||||
this.profilePicUrl = profilePicUrl;
|
|
||||||
this.hdProfilePicUrl = hdProfilePicUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getPk() {
|
|
||||||
return pk;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFullName() {
|
|
||||||
return fullName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProfilePicUrl() {
|
|
||||||
return profilePicUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHDProfilePicUrl() {
|
|
||||||
return hdProfilePicUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "UserInfo{" +
|
|
||||||
"uid='" + pk + '\'' +
|
|
||||||
", username='" + username + '\'' +
|
|
||||||
", fullName='" + fullName + '\'' +
|
|
||||||
", profilePicUrl='" + profilePicUrl + '\'' +
|
|
||||||
", hdProfilePicUrl='" + hdProfilePicUrl + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,8 +18,6 @@ import java.util.List;
|
|||||||
|
|
||||||
import awais.instagrabber.R;
|
import awais.instagrabber.R;
|
||||||
import awais.instagrabber.activities.MainActivity;
|
import awais.instagrabber.activities.MainActivity;
|
||||||
import awais.instagrabber.asyncs.GetActivityAsyncTask.NotificationCounts;
|
|
||||||
import awais.instagrabber.asyncs.GetActivityAsyncTask.OnTaskCompleteListener;
|
|
||||||
import awais.instagrabber.utils.Constants;
|
import awais.instagrabber.utils.Constants;
|
||||||
|
|
||||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||||
@ -30,7 +28,7 @@ public class ActivityCheckerService extends Service {
|
|||||||
private static final int DELAY_MILLIS = 60000;
|
private static final int DELAY_MILLIS = 60000;
|
||||||
|
|
||||||
private Handler handler;
|
private Handler handler;
|
||||||
private OnTaskCompleteListener onTaskCompleteListener;
|
// private OnTaskCompleteListener onTaskCompleteListener;
|
||||||
private NotificationManagerCompat notificationManager;
|
private NotificationManagerCompat notificationManager;
|
||||||
|
|
||||||
private final IBinder binder = new LocalBinder();
|
private final IBinder binder = new LocalBinder();
|
||||||
@ -50,6 +48,7 @@ public class ActivityCheckerService extends Service {
|
|||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
notificationManager = NotificationManagerCompat.from(getApplicationContext());
|
notificationManager = NotificationManagerCompat.from(getApplicationContext());
|
||||||
handler = new Handler();
|
handler = new Handler();
|
||||||
|
/*
|
||||||
onTaskCompleteListener = result -> {
|
onTaskCompleteListener = result -> {
|
||||||
// Log.d(TAG, "onTaskCompleteListener: result: " + result);
|
// Log.d(TAG, "onTaskCompleteListener: result: " + result);
|
||||||
try {
|
try {
|
||||||
@ -62,20 +61,12 @@ public class ActivityCheckerService extends Service {
|
|||||||
handler.postDelayed(runnable, DELAY_MILLIS);
|
handler.postDelayed(runnable, DELAY_MILLIS);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
startChecking();
|
startChecking();
|
||||||
// Uncomment to test notifications
|
|
||||||
// final String notificationString = getNotificationString(new NotificationCounts(
|
|
||||||
// 1,
|
|
||||||
// 2,
|
|
||||||
// 3,
|
|
||||||
// 4,
|
|
||||||
// 5
|
|
||||||
// ));
|
|
||||||
// showNotification(notificationString);
|
|
||||||
return binder;
|
return binder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +84,7 @@ public class ActivityCheckerService extends Service {
|
|||||||
handler.removeCallbacks(runnable);
|
handler.removeCallbacks(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
private String getNotificationString(final NotificationCounts result) {
|
private String getNotificationString(final NotificationCounts result) {
|
||||||
final List<String> list = new ArrayList<>();
|
final List<String> list = new ArrayList<>();
|
||||||
if (result.getRelationshipsCount() != 0) {
|
if (result.getRelationshipsCount() != 0) {
|
||||||
@ -113,6 +105,7 @@ public class ActivityCheckerService extends Service {
|
|||||||
if (list.isEmpty()) return null;
|
if (list.isEmpty()) return null;
|
||||||
return TextUtils.join(", ", list);
|
return TextUtils.join(", ", list);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
private void showNotification(final String notificationString) {
|
private void showNotification(final String notificationString) {
|
||||||
final Notification notification = new NotificationCompat.Builder(this, Constants.ACTIVITY_CHANNEL_ID)
|
final Notification notification = new NotificationCompat.Builder(this, Constants.ACTIVITY_CHANNEL_ID)
|
||||||
|
@ -5,12 +5,12 @@ import androidx.lifecycle.ViewModel;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import awais.instagrabber.models.NotificationModel;
|
import awais.instagrabber.repositories.responses.Notification;
|
||||||
|
|
||||||
public class NotificationViewModel extends ViewModel {
|
public class NotificationViewModel extends ViewModel {
|
||||||
private MutableLiveData<List<NotificationModel>> list;
|
private MutableLiveData<List<Notification>> list;
|
||||||
|
|
||||||
public MutableLiveData<List<NotificationModel>> getList() {
|
public MutableLiveData<List<Notification>> getList() {
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
list = new MutableLiveData<>();
|
list = new MutableLiveData<>();
|
||||||
}
|
}
|
||||||
|
@ -9,17 +9,23 @@ import org.json.JSONException;
|
|||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.regex.Matcher;
|
import java.util.stream.Collectors;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import awais.instagrabber.BuildConfig;
|
import awais.instagrabber.BuildConfig;
|
||||||
import awais.instagrabber.models.NotificationModel;
|
|
||||||
import awais.instagrabber.models.enums.NotificationType;
|
import awais.instagrabber.models.enums.NotificationType;
|
||||||
import awais.instagrabber.repositories.NewsRepository;
|
import awais.instagrabber.repositories.NewsRepository;
|
||||||
|
import awais.instagrabber.repositories.responses.AymlResponse;
|
||||||
|
import awais.instagrabber.repositories.responses.AymlUser;
|
||||||
|
import awais.instagrabber.repositories.responses.NewsInboxResponse;
|
||||||
|
import awais.instagrabber.repositories.responses.Notification;
|
||||||
|
import awais.instagrabber.repositories.responses.NotificationArgs;
|
||||||
|
import awais.instagrabber.repositories.responses.NotificationImage;
|
||||||
|
import awais.instagrabber.repositories.responses.User;
|
||||||
import awais.instagrabber.utils.Constants;
|
import awais.instagrabber.utils.Constants;
|
||||||
import awais.instagrabber.utils.Utils;
|
import awais.instagrabber.utils.Utils;
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
@ -52,48 +58,31 @@ public class NewsService extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void fetchAppInbox(final boolean markAsSeen,
|
public void fetchAppInbox(final boolean markAsSeen,
|
||||||
final ServiceCallback<List<NotificationModel>> callback) {
|
final ServiceCallback<List<Notification>> callback) {
|
||||||
final List<NotificationModel> result = new ArrayList<>();
|
final Call<NewsInboxResponse> request = repository.appInbox(appUa, markAsSeen);
|
||||||
final Call<String> request = repository.appInbox(appUa, markAsSeen);
|
request.enqueue(new Callback<NewsInboxResponse>() {
|
||||||
request.enqueue(new Callback<String>() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
public void onResponse(@NonNull final Call<NewsInboxResponse> call, @NonNull final Response<NewsInboxResponse> response) {
|
||||||
final String body = response.body();
|
final NewsInboxResponse body = response.body();
|
||||||
if (body == null) {
|
if (body == null) {
|
||||||
callback.onSuccess(null);
|
callback.onSuccess(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
final List<Notification> result = new ArrayList<>();
|
||||||
final JSONObject jsonObject = new JSONObject(body);
|
result.addAll(body.getNewStories());
|
||||||
final JSONArray oldStories = jsonObject.getJSONArray("old_stories"),
|
result.addAll(body.getOldStories());
|
||||||
newStories = jsonObject.getJSONArray("new_stories");
|
callback.onSuccess(result);
|
||||||
|
|
||||||
for (int j = 0; j < newStories.length(); ++j) {
|
|
||||||
final NotificationModel newsItem = parseNewsItem(newStories.getJSONObject(j));
|
|
||||||
if (newsItem != null) result.add(newsItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < oldStories.length(); ++i) {
|
|
||||||
final NotificationModel newsItem = parseNewsItem(oldStories.getJSONObject(i));
|
|
||||||
if (newsItem != null) result.add(newsItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback.onSuccess(result);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
callback.onFailure(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
public void onFailure(@NonNull final Call<NewsInboxResponse> call, @NonNull final Throwable t) {
|
||||||
callback.onFailure(t);
|
callback.onFailure(t);
|
||||||
// Log.e(TAG, "onFailure: ", t);
|
// Log.e(TAG, "onFailure: ", t);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fetchWebInbox(final boolean markAsSeen,
|
public void fetchWebInbox(final ServiceCallback<List<Notification>> callback) {
|
||||||
final ServiceCallback<List<NotificationModel>> callback) {
|
|
||||||
final Call<String> request = repository.webInbox(browserUa);
|
final Call<String> request = repository.webInbox(browserUa);
|
||||||
request.enqueue(new Callback<String>() {
|
request.enqueue(new Callback<String>() {
|
||||||
@Override
|
@Override
|
||||||
@ -104,7 +93,7 @@ public class NewsService extends BaseService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final List<NotificationModel> result = new ArrayList<>();
|
final List<Notification> result = new ArrayList<>();
|
||||||
final JSONObject page = new JSONObject(body)
|
final JSONObject page = new JSONObject(body)
|
||||||
.getJSONObject("graphql")
|
.getJSONObject("graphql")
|
||||||
.getJSONObject("user");
|
.getJSONObject("user");
|
||||||
@ -124,16 +113,24 @@ public class NewsService extends BaseService {
|
|||||||
final NotificationType notificationType = NotificationType.valueOfType(type);
|
final NotificationType notificationType = NotificationType.valueOfType(type);
|
||||||
if (notificationType == null) continue;
|
if (notificationType == null) continue;
|
||||||
final JSONObject user = data.getJSONObject("user");
|
final JSONObject user = data.getJSONObject("user");
|
||||||
result.add(new NotificationModel(
|
|
||||||
data.getString(Constants.EXTRAS_ID),
|
result.add(new Notification(
|
||||||
data.optString("text"), // comments or mentions
|
new NotificationArgs(
|
||||||
data.getLong("timestamp"),
|
data.optString("text"),
|
||||||
user.getLong("id"),
|
null,
|
||||||
user.getString("username"),
|
user.getLong(Constants.EXTRAS_ID),
|
||||||
user.getString("profile_pic_url"),
|
user.getString("profile_pic_url"),
|
||||||
!data.isNull("media") ? Long.valueOf(data.getJSONObject("media").getString("id").split("_")[0]) : 0,
|
data.isNull("media") ? null : Collections.singletonList(new NotificationImage(
|
||||||
data.has("media") ? data.getJSONObject("media").getString("thumbnail_src") : null,
|
data.getJSONObject("media").getString("id"),
|
||||||
notificationType));
|
data.getJSONObject("media").getString("thumbnail_src")
|
||||||
|
)),
|
||||||
|
data.getLong("timestamp"),
|
||||||
|
user.getString("username"),
|
||||||
|
null
|
||||||
|
),
|
||||||
|
type,
|
||||||
|
data.getString(Constants.EXTRAS_ID)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,15 +141,20 @@ public class NewsService extends BaseService {
|
|||||||
for (int i = 0; i < media.length(); ++i) {
|
for (int i = 0; i < media.length(); ++i) {
|
||||||
data = media.optJSONObject(i).optJSONObject("node");
|
data = media.optJSONObject(i).optJSONObject("node");
|
||||||
if (data == null) continue;
|
if (data == null) continue;
|
||||||
result.add(new NotificationModel(
|
result.add(new Notification(
|
||||||
data.getString(Constants.EXTRAS_ID),
|
new NotificationArgs(
|
||||||
data.optString("full_name"),
|
null,
|
||||||
0L,
|
null,
|
||||||
data.getLong(Constants.EXTRAS_ID),
|
data.getLong(Constants.EXTRAS_ID),
|
||||||
data.getString("username"),
|
data.getString("profile_pic_url"),
|
||||||
data.getString("profile_pic_url"),
|
null,
|
||||||
0,
|
0L,
|
||||||
null, NotificationType.REQUEST));
|
data.getString("username"),
|
||||||
|
data.optString("full_name")
|
||||||
|
),
|
||||||
|
"REQUEST",
|
||||||
|
data.getString(Constants.EXTRAS_ID)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
callback.onSuccess(result);
|
callback.onSuccess(result);
|
||||||
@ -169,40 +171,8 @@ public class NewsService extends BaseService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private NotificationModel parseNewsItem(final JSONObject itemJson) throws JSONException {
|
|
||||||
if (itemJson == null) return null;
|
|
||||||
final String type = itemJson.getString("story_type");
|
|
||||||
final NotificationType notificationType = NotificationType.valueOfType(type);
|
|
||||||
if (notificationType == null) {
|
|
||||||
if (BuildConfig.DEBUG) Log.d("austin_debug", "unhandled news type: " + itemJson);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final JSONObject data = itemJson.getJSONObject("args");
|
|
||||||
return new NotificationModel(
|
|
||||||
data.getString("tuuid"),
|
|
||||||
data.has("text") ? data.getString("text") : cleanRichText(data.optString("rich_text", "")),
|
|
||||||
data.getLong("timestamp"),
|
|
||||||
data.getLong("profile_id"),
|
|
||||||
data.getString("profile_name"),
|
|
||||||
data.getString("profile_image"),
|
|
||||||
!data.isNull("media") ? Long.valueOf(data.getJSONArray("media").getJSONObject(0).getString("id").split("_")[0]) : 0,
|
|
||||||
!data.isNull("media") ? data.getJSONArray("media").getJSONObject(0).getString("image") : null,
|
|
||||||
notificationType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String cleanRichText(final String raw) {
|
|
||||||
final Matcher matcher = Pattern.compile("\\{[\\p{L}\\d._]+\\|000000\\|1\\|user\\?id=\\d+\\}").matcher(raw);
|
|
||||||
String result = raw;
|
|
||||||
while (matcher.find()) {
|
|
||||||
final String richObject = raw.substring(matcher.start(), matcher.end());
|
|
||||||
final String username = richObject.split("\\|")[0].substring(1);
|
|
||||||
result = result.replace(richObject, username);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fetchSuggestions(final String csrfToken,
|
public void fetchSuggestions(final String csrfToken,
|
||||||
final ServiceCallback<List<NotificationModel>> callback) {
|
final ServiceCallback<List<Notification>> callback) {
|
||||||
final Map<String, String> form = new HashMap<>();
|
final Map<String, String> form = new HashMap<>();
|
||||||
form.put("_uuid", UUID.randomUUID().toString());
|
form.put("_uuid", UUID.randomUUID().toString());
|
||||||
form.put("_csrftoken", csrfToken);
|
form.put("_csrftoken", csrfToken);
|
||||||
@ -210,57 +180,46 @@ public class NewsService extends BaseService {
|
|||||||
form.put("device_id", UUID.randomUUID().toString());
|
form.put("device_id", UUID.randomUUID().toString());
|
||||||
form.put("module", "discover_people");
|
form.put("module", "discover_people");
|
||||||
form.put("paginate", "false");
|
form.put("paginate", "false");
|
||||||
final Call<String> request = repository.getAyml(appUa, form);
|
final Call<AymlResponse> request = repository.getAyml(appUa, form);
|
||||||
request.enqueue(new Callback<String>() {
|
request.enqueue(new Callback<AymlResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
public void onResponse(@NonNull final Call<AymlResponse> call, @NonNull final Response<AymlResponse> response) {
|
||||||
final String body = response.body();
|
final AymlResponse body = response.body();
|
||||||
if (body == null) {
|
if (body == null) {
|
||||||
callback.onSuccess(null);
|
callback.onSuccess(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
final List<AymlUser> aymlUsers = new ArrayList<>();
|
||||||
final List<NotificationModel> result = new ArrayList<>();
|
aymlUsers.addAll(body.getNewSuggestedUsers().getSuggestions());
|
||||||
final JSONObject jsonObject = new JSONObject(body);
|
aymlUsers.addAll(body.getSuggestedUsers().getSuggestions());
|
||||||
final JSONArray oldStories = jsonObject.getJSONObject("suggested_users").getJSONArray("suggestions"),
|
|
||||||
newStories = jsonObject.getJSONObject("new_suggested_users").getJSONArray("suggestions");
|
|
||||||
|
|
||||||
for (int j = 0; j < newStories.length(); ++j) {
|
final List<Notification> newsItems = aymlUsers.stream()
|
||||||
final NotificationModel newsItem = parseAymlItem(newStories.getJSONObject(j));
|
.map(i -> {
|
||||||
if (newsItem != null) result.add(newsItem);
|
final User u = i.getUser();
|
||||||
}
|
return new Notification(
|
||||||
|
new NotificationArgs(
|
||||||
for (int i = 0; i < oldStories.length(); ++i) {
|
i.getSocialContext(),
|
||||||
final NotificationModel newsItem = parseAymlItem(oldStories.getJSONObject(i));
|
i.getAlgorithm(),
|
||||||
if (newsItem != null) result.add(newsItem);
|
u.getPk(),
|
||||||
}
|
u.getProfilePicUrl(),
|
||||||
|
null,
|
||||||
callback.onSuccess(result);
|
0L,
|
||||||
} catch (JSONException e) {
|
u.getUsername(),
|
||||||
callback.onFailure(e);
|
u.getFullName()
|
||||||
}
|
),
|
||||||
|
"AYML",
|
||||||
|
i.getUuid()
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
callback.onSuccess(newsItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
public void onFailure(@NonNull final Call<AymlResponse> call, @NonNull final Throwable t) {
|
||||||
callback.onFailure(t);
|
callback.onFailure(t);
|
||||||
// Log.e(TAG, "onFailure: ", t);
|
// Log.e(TAG, "onFailure: ", t);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private NotificationModel parseAymlItem(final JSONObject itemJson) throws JSONException {
|
|
||||||
if (itemJson == null) return null;
|
|
||||||
final JSONObject data = itemJson.getJSONObject("user");
|
|
||||||
return new NotificationModel(
|
|
||||||
itemJson.getString("uuid"),
|
|
||||||
itemJson.getString("social_context"),
|
|
||||||
0L,
|
|
||||||
data.getLong("pk"),
|
|
||||||
data.getString("username"),
|
|
||||||
data.getString("profile_pic_url"),
|
|
||||||
0,
|
|
||||||
data.getString("full_name"), // just borrowing this field
|
|
||||||
NotificationType.AYML);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user