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.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import awais.instagrabber.adapters.viewholder.NotificationViewHolder;
|
||||
import awais.instagrabber.databinding.ItemNotificationBinding;
|
||||
import awais.instagrabber.models.NotificationModel;
|
||||
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 static final DiffUtil.ItemCallback<NotificationModel> DIFF_CALLBACK = new DiffUtil.ItemCallback<NotificationModel>() {
|
||||
private static final DiffUtil.ItemCallback<Notification> DIFF_CALLBACK = new DiffUtil.ItemCallback<Notification>() {
|
||||
@Override
|
||||
public boolean areItemsTheSame(@NonNull final NotificationModel oldItem, @NonNull final NotificationModel newItem) {
|
||||
return oldItem.getId().equals(newItem.getId());
|
||||
public boolean areItemsTheSame(@NonNull final Notification oldItem, @NonNull final Notification newItem) {
|
||||
return oldItem.getPk().equals(newItem.getPk());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(@NonNull final NotificationModel oldItem, @NonNull final NotificationModel newItem) {
|
||||
return oldItem.getId().equals(newItem.getId());
|
||||
public boolean areContentsTheSame(@NonNull final Notification oldItem, @NonNull final Notification newItem) {
|
||||
return oldItem.getPk().equals(newItem.getPk());
|
||||
}
|
||||
};
|
||||
|
||||
@ -47,12 +48,12 @@ public final class NotificationsAdapter extends ListAdapter<NotificationModel, N
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final NotificationViewHolder holder, final int position) {
|
||||
final NotificationModel notificationModel = getItem(position);
|
||||
holder.bind(notificationModel, notificationClickListener);
|
||||
final Notification Notification = getItem(position);
|
||||
holder.bind(Notification, notificationClickListener);
|
||||
}
|
||||
|
||||
@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) {
|
||||
super.submitList(null, commitCallback);
|
||||
return;
|
||||
@ -61,7 +62,7 @@ public final class NotificationsAdapter extends ListAdapter<NotificationModel, N
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitList(@Nullable final List<NotificationModel> list) {
|
||||
public void submitList(@Nullable final List<Notification> list) {
|
||||
if (list == null) {
|
||||
super.submitList(null);
|
||||
return;
|
||||
@ -69,8 +70,10 @@ public final class NotificationsAdapter extends ListAdapter<NotificationModel, N
|
||||
super.submitList(sort(list));
|
||||
}
|
||||
|
||||
private List<NotificationModel> sort(final List<NotificationModel> list) {
|
||||
final List<NotificationModel> listCopy = new ArrayList<>(list);
|
||||
private List<Notification> sort(final List<Notification> list) {
|
||||
final List<Notification> listCopy = new ArrayList<>(list).stream()
|
||||
.filter(i -> i.getType() != null)
|
||||
.collect(Collectors.toList());
|
||||
Collections.sort(listCopy, (o1, o2) -> {
|
||||
// keep requests at top
|
||||
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 (o2.getType() == NotificationType.REQUEST) return 1;
|
||||
// timestamp
|
||||
return Long.compare(o2.getTimestamp(), o1.getTimestamp());
|
||||
return Double.compare(o2.getArgs().getTimestamp(), o1.getArgs().getTimestamp());
|
||||
});
|
||||
return listCopy;
|
||||
}
|
||||
|
||||
public interface OnNotificationClickListener {
|
||||
void onNotificationClick(final NotificationModel model);
|
||||
void onNotificationClick(final Notification model);
|
||||
|
||||
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.adapters.NotificationsAdapter.OnNotificationClickListener;
|
||||
import awais.instagrabber.databinding.ItemNotificationBinding;
|
||||
import awais.instagrabber.models.NotificationModel;
|
||||
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 {
|
||||
private final ItemNotificationBinding binding;
|
||||
@ -19,22 +20,23 @@ public final class NotificationViewHolder extends RecyclerView.ViewHolder {
|
||||
this.binding = binding;
|
||||
}
|
||||
|
||||
public void bind(final NotificationModel model,
|
||||
public void bind(final Notification model,
|
||||
final OnNotificationClickListener notificationClickListener) {
|
||||
if (model == null) return;
|
||||
int text = -1;
|
||||
CharSequence subtext = null;
|
||||
final NotificationArgs args = model.getArgs();
|
||||
switch (model.getType()) {
|
||||
case LIKE:
|
||||
text = R.string.liked_notif;
|
||||
break;
|
||||
case COMMENT:
|
||||
text = R.string.comment_notif;
|
||||
subtext = model.getText();
|
||||
subtext = args.getText();
|
||||
break;
|
||||
case COMMENT_MENTION:
|
||||
text = R.string.mention_notif;
|
||||
subtext = model.getText();
|
||||
subtext = args.getText();
|
||||
break;
|
||||
case TAGGED:
|
||||
text = R.string.tagged_notif;
|
||||
@ -44,18 +46,18 @@ public final class NotificationViewHolder extends RecyclerView.ViewHolder {
|
||||
break;
|
||||
case REQUEST:
|
||||
text = R.string.request_notif;
|
||||
subtext = model.getText();
|
||||
subtext = args.getText();
|
||||
break;
|
||||
case COMMENT_LIKE:
|
||||
case TAGGED_COMMENT:
|
||||
case RESPONDED_STORY:
|
||||
subtext = model.getText();
|
||||
subtext = args.getText();
|
||||
break;
|
||||
case AYML:
|
||||
subtext = model.getPreviewPic();
|
||||
subtext = args.getFullName();
|
||||
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) {
|
||||
binding.tvComment.setText(subtext);
|
||||
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.tvDate.setVisibility(model.getType() == NotificationType.AYML ? View.GONE : View.VISIBLE);
|
||||
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.ivProfilePic.setImageURI(model.getProfilePic());
|
||||
binding.tvUsername.setText(args.getUsername());
|
||||
binding.ivProfilePic.setImageURI(args.getProfilePic());
|
||||
binding.ivProfilePic.setOnClickListener(v -> {
|
||||
if (notificationClickListener == null) return;
|
||||
notificationClickListener.onProfileClick(model.getUsername());
|
||||
notificationClickListener.onProfileClick(args.getUsername());
|
||||
});
|
||||
|
||||
if (model.getType() == NotificationType.AYML) {
|
||||
binding.ivPreviewPic.setVisibility(View.GONE);
|
||||
} else if (TextUtils.isEmpty(model.getPreviewPic())) {
|
||||
} else if (args.getMedia() == null) {
|
||||
binding.ivPreviewPic.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
binding.ivPreviewPic.setVisibility(View.VISIBLE);
|
||||
binding.ivPreviewPic.setImageURI(model.getPreviewPic());
|
||||
binding.ivPreviewPic.setImageURI(args.getMedia().get(0).getImage());
|
||||
binding.ivPreviewPic.setOnClickListener(v -> {
|
||||
if (notificationClickListener == null) return;
|
||||
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.interfaces.FetchListener;
|
||||
import awais.instagrabber.models.NotificationModel;
|
||||
import awais.instagrabber.repositories.responses.Notification;
|
||||
import awais.instagrabber.webservices.NewsService;
|
||||
import awais.instagrabber.webservices.ServiceCallback;
|
||||
import awaisomereport.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 final FetchListener<List<NotificationModel>> fetchListener;
|
||||
private final FetchListener<List<Notification>> fetchListener;
|
||||
private final NewsService newsService;
|
||||
private final boolean markAsSeen;
|
||||
private boolean fetchedWeb = false;
|
||||
|
||||
public NotificationsFetcher(final boolean markAsSeen,
|
||||
final FetchListener<List<NotificationModel>> fetchListener) {
|
||||
final FetchListener<List<Notification>> fetchListener) {
|
||||
this.markAsSeen = markAsSeen;
|
||||
this.fetchListener = fetchListener;
|
||||
newsService = NewsService.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<NotificationModel> doInBackground(final Void... voids) {
|
||||
List<NotificationModel> notificationModels = new ArrayList<>();
|
||||
protected List<Notification> doInBackground(final Void... voids) {
|
||||
List<Notification> notificationModels = new ArrayList<>();
|
||||
|
||||
newsService.fetchAppInbox(markAsSeen, new ServiceCallback<List<NotificationModel>>() {
|
||||
newsService.fetchAppInbox(markAsSeen, new ServiceCallback<List<Notification>>() {
|
||||
@Override
|
||||
public void onSuccess(final List<NotificationModel> result) {
|
||||
public void onSuccess(final List<Notification> result) {
|
||||
if (result == null) return;
|
||||
notificationModels.addAll(result);
|
||||
if (fetchedWeb) {
|
||||
@ -44,7 +44,7 @@ public final class NotificationsFetcher extends AsyncTask<Void, Void, List<Notif
|
||||
}
|
||||
else {
|
||||
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.fragments.settings.MorePreferencesFragmentDirections;
|
||||
import awais.instagrabber.interfaces.FetchListener;
|
||||
import awais.instagrabber.models.NotificationModel;
|
||||
import awais.instagrabber.models.enums.NotificationType;
|
||||
import awais.instagrabber.repositories.requests.StoryViewerOptions;
|
||||
import awais.instagrabber.repositories.responses.FriendshipChangeResponse;
|
||||
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.CookieUtils;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
@ -70,14 +72,18 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
||||
}
|
||||
|
||||
@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) {
|
||||
final NavDirections action = NotificationsViewerFragmentDirections
|
||||
.actionNotificationsViewerFragmentToStoryViewerFragment(StoryViewerOptions.forStory(model.getPostId(),
|
||||
model.getUsername()));
|
||||
.actionNotificationsViewerFragmentToStoryViewerFragment(
|
||||
StoryViewerOptions.forStory(
|
||||
mediaId,
|
||||
model.getArgs().getUsername()));
|
||||
NavHostFragment.findNavController(NotificationsViewerFragment.this).navigate(action);
|
||||
} else {
|
||||
mediaService.fetch(model.getPostId(), new ServiceCallback<Media>() {
|
||||
mediaService.fetch(mediaId, new ServiceCallback<Media>() {
|
||||
@Override
|
||||
public void onSuccess(final Media feedModel) {
|
||||
final PostViewV2Fragment fragment = PostViewV2Fragment
|
||||
@ -95,13 +101,14 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotificationClick(final NotificationModel model) {
|
||||
public void onNotificationClick(final Notification model) {
|
||||
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) {
|
||||
openProfile(username);
|
||||
} 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);
|
||||
|
||||
String[] commentDialogList;
|
||||
@ -110,7 +117,7 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
||||
getString(R.string.open_profile),
|
||||
getString(R.string.view_story)
|
||||
};
|
||||
} else if (model.getPostId() > 0) {
|
||||
} else if (args.getMedia() != null) {
|
||||
commentDialogList = new String[]{
|
||||
getString(R.string.open_profile),
|
||||
getString(R.string.view_post)
|
||||
@ -131,7 +138,7 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
||||
break;
|
||||
case 1:
|
||||
if (model.getType() == NotificationType.REQUEST) {
|
||||
friendshipService.approve(model.getUserId(), new ServiceCallback<FriendshipChangeResponse>() {
|
||||
friendshipService.approve(args.getUserId(), new ServiceCallback<FriendshipChangeResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipChangeResponse result) {
|
||||
onRefresh();
|
||||
@ -148,7 +155,7 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
||||
clickListener.onPreviewClick(model);
|
||||
break;
|
||||
case 2:
|
||||
friendshipService.ignore(model.getUserId(), new ServiceCallback<FriendshipChangeResponse>() {
|
||||
friendshipService.ignore(args.getUserId(), new ServiceCallback<FriendshipChangeResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipChangeResponse result) {
|
||||
onRefresh();
|
||||
@ -226,9 +233,9 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
||||
binding.swipeRefreshLayout.setRefreshing(true);
|
||||
switch (type) {
|
||||
case "notif":
|
||||
new NotificationsFetcher(true, new FetchListener<List<NotificationModel>>() {
|
||||
new NotificationsFetcher(true, new FetchListener<List<Notification>>() {
|
||||
@Override
|
||||
public void onResult(final List<NotificationModel> notificationModels) {
|
||||
public void onResult(final List<Notification> notificationModels) {
|
||||
binding.swipeRefreshLayout.setRefreshing(false);
|
||||
notificationViewModel.getList().postValue(notificationModels);
|
||||
}
|
||||
@ -245,9 +252,9 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
||||
break;
|
||||
case "ayml":
|
||||
final NewsService newsService = NewsService.getInstance();
|
||||
newsService.fetchSuggestions(csrfToken, new ServiceCallback<List<NotificationModel>>() {
|
||||
newsService.fetchSuggestions(csrfToken, new ServiceCallback<List<Notification>>() {
|
||||
@Override
|
||||
public void onSuccess(final List<NotificationModel> notificationModels) {
|
||||
public void onSuccess(final List<Notification> notificationModels) {
|
||||
binding.swipeRefreshLayout.setRefreshing(false);
|
||||
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 awais.instagrabber.repositories.responses.AymlResponse;
|
||||
import awais.instagrabber.repositories.responses.NewsInboxResponse;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.FieldMap;
|
||||
import retrofit2.http.FormUrlEncoded;
|
||||
@ -16,9 +18,9 @@ public interface NewsRepository {
|
||||
Call<String> webInbox(@Header("User-Agent") String userAgent);
|
||||
|
||||
@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
|
||||
@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.activities.MainActivity;
|
||||
import awais.instagrabber.asyncs.GetActivityAsyncTask.NotificationCounts;
|
||||
import awais.instagrabber.asyncs.GetActivityAsyncTask.OnTaskCompleteListener;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
@ -30,7 +28,7 @@ public class ActivityCheckerService extends Service {
|
||||
private static final int DELAY_MILLIS = 60000;
|
||||
|
||||
private Handler handler;
|
||||
private OnTaskCompleteListener onTaskCompleteListener;
|
||||
// private OnTaskCompleteListener onTaskCompleteListener;
|
||||
private NotificationManagerCompat notificationManager;
|
||||
|
||||
private final IBinder binder = new LocalBinder();
|
||||
@ -50,6 +48,7 @@ public class ActivityCheckerService extends Service {
|
||||
public void onCreate() {
|
||||
notificationManager = NotificationManagerCompat.from(getApplicationContext());
|
||||
handler = new Handler();
|
||||
/*
|
||||
onTaskCompleteListener = result -> {
|
||||
// Log.d(TAG, "onTaskCompleteListener: result: " + result);
|
||||
try {
|
||||
@ -62,20 +61,12 @@ public class ActivityCheckerService extends Service {
|
||||
handler.postDelayed(runnable, DELAY_MILLIS);
|
||||
}
|
||||
};
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
startChecking();
|
||||
// Uncomment to test notifications
|
||||
// final String notificationString = getNotificationString(new NotificationCounts(
|
||||
// 1,
|
||||
// 2,
|
||||
// 3,
|
||||
// 4,
|
||||
// 5
|
||||
// ));
|
||||
// showNotification(notificationString);
|
||||
return binder;
|
||||
}
|
||||
|
||||
@ -93,6 +84,7 @@ public class ActivityCheckerService extends Service {
|
||||
handler.removeCallbacks(runnable);
|
||||
}
|
||||
|
||||
/*
|
||||
private String getNotificationString(final NotificationCounts result) {
|
||||
final List<String> list = new ArrayList<>();
|
||||
if (result.getRelationshipsCount() != 0) {
|
||||
@ -113,6 +105,7 @@ public class ActivityCheckerService extends Service {
|
||||
if (list.isEmpty()) return null;
|
||||
return TextUtils.join(", ", list);
|
||||
}
|
||||
*/
|
||||
|
||||
private void showNotification(final String notificationString) {
|
||||
final Notification notification = new NotificationCompat.Builder(this, Constants.ACTIVITY_CHANNEL_ID)
|
||||
|
@ -5,12 +5,12 @@ import androidx.lifecycle.ViewModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import awais.instagrabber.models.NotificationModel;
|
||||
import awais.instagrabber.repositories.responses.Notification;
|
||||
|
||||
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) {
|
||||
list = new MutableLiveData<>();
|
||||
}
|
||||
|
@ -9,17 +9,23 @@ import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import awais.instagrabber.BuildConfig;
|
||||
import awais.instagrabber.models.NotificationModel;
|
||||
import awais.instagrabber.models.enums.NotificationType;
|
||||
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.Utils;
|
||||
import retrofit2.Call;
|
||||
@ -52,48 +58,31 @@ public class NewsService extends BaseService {
|
||||
}
|
||||
|
||||
public void fetchAppInbox(final boolean markAsSeen,
|
||||
final ServiceCallback<List<NotificationModel>> callback) {
|
||||
final List<NotificationModel> result = new ArrayList<>();
|
||||
final Call<String> request = repository.appInbox(appUa, markAsSeen);
|
||||
request.enqueue(new Callback<String>() {
|
||||
final ServiceCallback<List<Notification>> callback) {
|
||||
final Call<NewsInboxResponse> request = repository.appInbox(appUa, markAsSeen);
|
||||
request.enqueue(new Callback<NewsInboxResponse>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
final String body = response.body();
|
||||
public void onResponse(@NonNull final Call<NewsInboxResponse> call, @NonNull final Response<NewsInboxResponse> response) {
|
||||
final NewsInboxResponse body = response.body();
|
||||
if (body == null) {
|
||||
callback.onSuccess(null);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final JSONObject jsonObject = new JSONObject(body);
|
||||
final JSONArray oldStories = jsonObject.getJSONArray("old_stories"),
|
||||
newStories = jsonObject.getJSONArray("new_stories");
|
||||
|
||||
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);
|
||||
}
|
||||
final List<Notification> result = new ArrayList<>();
|
||||
result.addAll(body.getNewStories());
|
||||
result.addAll(body.getOldStories());
|
||||
callback.onSuccess(result);
|
||||
}
|
||||
|
||||
@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);
|
||||
// Log.e(TAG, "onFailure: ", t);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void fetchWebInbox(final boolean markAsSeen,
|
||||
final ServiceCallback<List<NotificationModel>> callback) {
|
||||
public void fetchWebInbox(final ServiceCallback<List<Notification>> callback) {
|
||||
final Call<String> request = repository.webInbox(browserUa);
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
@ -104,7 +93,7 @@ public class NewsService extends BaseService {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final List<NotificationModel> result = new ArrayList<>();
|
||||
final List<Notification> result = new ArrayList<>();
|
||||
final JSONObject page = new JSONObject(body)
|
||||
.getJSONObject("graphql")
|
||||
.getJSONObject("user");
|
||||
@ -124,16 +113,24 @@ public class NewsService extends BaseService {
|
||||
final NotificationType notificationType = NotificationType.valueOfType(type);
|
||||
if (notificationType == null) continue;
|
||||
final JSONObject user = data.getJSONObject("user");
|
||||
result.add(new NotificationModel(
|
||||
data.getString(Constants.EXTRAS_ID),
|
||||
data.optString("text"), // comments or mentions
|
||||
data.getLong("timestamp"),
|
||||
user.getLong("id"),
|
||||
user.getString("username"),
|
||||
user.getString("profile_pic_url"),
|
||||
!data.isNull("media") ? Long.valueOf(data.getJSONObject("media").getString("id").split("_")[0]) : 0,
|
||||
data.has("media") ? data.getJSONObject("media").getString("thumbnail_src") : null,
|
||||
notificationType));
|
||||
|
||||
result.add(new Notification(
|
||||
new NotificationArgs(
|
||||
data.optString("text"),
|
||||
null,
|
||||
user.getLong(Constants.EXTRAS_ID),
|
||||
user.getString("profile_pic_url"),
|
||||
data.isNull("media") ? null : Collections.singletonList(new NotificationImage(
|
||||
data.getJSONObject("media").getString("id"),
|
||||
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) {
|
||||
data = media.optJSONObject(i).optJSONObject("node");
|
||||
if (data == null) continue;
|
||||
result.add(new NotificationModel(
|
||||
data.getString(Constants.EXTRAS_ID),
|
||||
data.optString("full_name"),
|
||||
0L,
|
||||
data.getLong(Constants.EXTRAS_ID),
|
||||
data.getString("username"),
|
||||
data.getString("profile_pic_url"),
|
||||
0,
|
||||
null, NotificationType.REQUEST));
|
||||
result.add(new Notification(
|
||||
new NotificationArgs(
|
||||
null,
|
||||
null,
|
||||
data.getLong(Constants.EXTRAS_ID),
|
||||
data.getString("profile_pic_url"),
|
||||
null,
|
||||
0L,
|
||||
data.getString("username"),
|
||||
data.optString("full_name")
|
||||
),
|
||||
"REQUEST",
|
||||
data.getString(Constants.EXTRAS_ID)
|
||||
));
|
||||
}
|
||||
}
|
||||
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,
|
||||
final ServiceCallback<List<NotificationModel>> callback) {
|
||||
final ServiceCallback<List<Notification>> callback) {
|
||||
final Map<String, String> form = new HashMap<>();
|
||||
form.put("_uuid", UUID.randomUUID().toString());
|
||||
form.put("_csrftoken", csrfToken);
|
||||
@ -210,57 +180,46 @@ public class NewsService extends BaseService {
|
||||
form.put("device_id", UUID.randomUUID().toString());
|
||||
form.put("module", "discover_people");
|
||||
form.put("paginate", "false");
|
||||
final Call<String> request = repository.getAyml(appUa, form);
|
||||
request.enqueue(new Callback<String>() {
|
||||
final Call<AymlResponse> request = repository.getAyml(appUa, form);
|
||||
request.enqueue(new Callback<AymlResponse>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
final String body = response.body();
|
||||
public void onResponse(@NonNull final Call<AymlResponse> call, @NonNull final Response<AymlResponse> response) {
|
||||
final AymlResponse body = response.body();
|
||||
if (body == null) {
|
||||
callback.onSuccess(null);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final List<NotificationModel> result = new ArrayList<>();
|
||||
final JSONObject jsonObject = new JSONObject(body);
|
||||
final JSONArray oldStories = jsonObject.getJSONObject("suggested_users").getJSONArray("suggestions"),
|
||||
newStories = jsonObject.getJSONObject("new_suggested_users").getJSONArray("suggestions");
|
||||
final List<AymlUser> aymlUsers = new ArrayList<>();
|
||||
aymlUsers.addAll(body.getNewSuggestedUsers().getSuggestions());
|
||||
aymlUsers.addAll(body.getSuggestedUsers().getSuggestions());
|
||||
|
||||
for (int j = 0; j < newStories.length(); ++j) {
|
||||
final NotificationModel newsItem = parseAymlItem(newStories.getJSONObject(j));
|
||||
if (newsItem != null) result.add(newsItem);
|
||||
}
|
||||
|
||||
for (int i = 0; i < oldStories.length(); ++i) {
|
||||
final NotificationModel newsItem = parseAymlItem(oldStories.getJSONObject(i));
|
||||
if (newsItem != null) result.add(newsItem);
|
||||
}
|
||||
|
||||
callback.onSuccess(result);
|
||||
} catch (JSONException e) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
final List<Notification> newsItems = aymlUsers.stream()
|
||||
.map(i -> {
|
||||
final User u = i.getUser();
|
||||
return new Notification(
|
||||
new NotificationArgs(
|
||||
i.getSocialContext(),
|
||||
i.getAlgorithm(),
|
||||
u.getPk(),
|
||||
u.getProfilePicUrl(),
|
||||
null,
|
||||
0L,
|
||||
u.getUsername(),
|
||||
u.getFullName()
|
||||
),
|
||||
"AYML",
|
||||
i.getUuid()
|
||||
);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
callback.onSuccess(newsItems);
|
||||
}
|
||||
|
||||
@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);
|
||||
// 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