add suggestion chaining

This commit is contained in:
Austin Huang 2021-03-05 14:06:27 -05:00
parent 508a80be53
commit 8105462acb
No known key found for this signature in database
GPG Key ID: 84C23AA04587A91F
21 changed files with 194 additions and 52 deletions

View File

@ -59,8 +59,10 @@ public final class NotificationViewHolder extends RecyclerView.ViewHolder {
} }
binding.tvSubComment.setText(model.getType() == NotificationType.AYML ? args.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(args.getText());
binding.tvComment.setVisibility(TextUtils.isEmpty(subtext) ? View.GONE : View.VISIBLE); binding.tvComment.setVisibility(TextUtils.isEmpty(args.getText()) || args.getText().equals(args.getFullName())
? View.GONE : View.VISIBLE);
binding.tvSubComment.setText(subtext);
binding.tvSubComment.setVisibility(model.getType() == NotificationType.AYML ? View.VISIBLE : View.GONE); binding.tvSubComment.setVisibility(model.getType() == NotificationType.AYML ? View.VISIBLE : View.GONE);
} else if (text != -1) { } else if (text != -1) {
binding.tvComment.setText(text); binding.tvComment.setText(text);
@ -72,6 +74,8 @@ public final class NotificationViewHolder extends RecyclerView.ViewHolder {
binding.tvDate.setText(args.getDateTime()); binding.tvDate.setText(args.getDateTime());
} }
binding.isVerified.setVisibility(args.isVerified() ? View.VISIBLE : View.GONE);
binding.tvUsername.setText(args.getUsername()); binding.tvUsername.setText(args.getUsername());
binding.ivProfilePic.setImageURI(args.getProfilePic()); binding.ivProfilePic.setImageURI(args.getProfilePic());
binding.ivProfilePic.setOnClickListener(v -> { binding.ivProfilePic.setOnClickListener(v -> {

View File

@ -115,7 +115,8 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, List<CommentMod
owner.getString("profile_pic_url"), owner.getString("profile_pic_url"),
null, null,
new FriendshipStatus(false, false, false, false, false, false, false, false, false, false), new FriendshipStatus(false, false, false, false, false, false, false, false, false, false),
false, false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0, null, null, null, null); false, false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0, null, null, null,
null, null);
final JSONObject likedBy = childComment.optJSONObject("edge_liked_by"); final JSONObject likedBy = childComment.optJSONObject("edge_liked_by");
commentModels.add(new CommentModel(childComment.getString(Constants.EXTRAS_ID), commentModels.add(new CommentModel(childComment.getString(Constants.EXTRAS_ID),
childComment.getString("text"), childComment.getString("text"),
@ -193,7 +194,8 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, List<CommentMod
null, null,
new FriendshipStatus(false, false, false, false, false, false, false, false, false, false), new FriendshipStatus(false, false, false, false, false, false, false, false, false, false),
owner.optBoolean("is_verified"), owner.optBoolean("is_verified"),
false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0, null, null, null, null); false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0, null, null, null, null,
null);
final JSONObject likedBy = comment.optJSONObject("edge_liked_by"); final JSONObject likedBy = comment.optJSONObject("edge_liked_by");
final String commentId = comment.getString(Constants.EXTRAS_ID); final String commentId = comment.getString(Constants.EXTRAS_ID);
final CommentModel commentModel = new CommentModel(commentId, final CommentModel commentModel = new CommentModel(commentId,
@ -235,7 +237,7 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, List<CommentMod
null, null,
new FriendshipStatus(false, false, false, false, false, false, false, false, false, false), new FriendshipStatus(false, false, false, false, false, false, false, false, false, false),
tempJsonObject.optBoolean("is_verified"), false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0, tempJsonObject.optBoolean("is_verified"), false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0,
null, null, null, null); null, null, null, null, null);
tempJsonObject = childComment.optJSONObject("edge_liked_by"); tempJsonObject = childComment.optJSONObject("edge_liked_by");
childCommentModels.add(new CommentModel(childComment.getString(Constants.EXTRAS_ID), childCommentModels.add(new CommentModel(childComment.getString(Constants.EXTRAS_ID),

View File

@ -15,7 +15,9 @@ import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationManagerCompat; import androidx.core.app.NotificationManagerCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@ -55,16 +57,36 @@ import static awais.instagrabber.utils.Utils.settingsHelper;
public final class NotificationsViewerFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener { public final class NotificationsViewerFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private static final String TAG = "NotificationsViewer"; private static final String TAG = "NotificationsViewer";
private AppCompatActivity fragmentActivity;
private FragmentNotificationsViewerBinding binding; private FragmentNotificationsViewerBinding binding;
private SwipeRefreshLayout root; private SwipeRefreshLayout root;
private boolean shouldRefresh = true; private boolean shouldRefresh = true;
private NotificationViewModel notificationViewModel; private NotificationViewModel notificationViewModel;
private FriendshipService friendshipService; private FriendshipService friendshipService;
private MediaService mediaService; private MediaService mediaService;
private String csrfToken; private NewsService newsService;
private String csrfToken, deviceUuid;
private String type; private String type;
private long targetId;
private Context context; private Context context;
private final ServiceCallback<List<Notification>> cb = new ServiceCallback<List<Notification>>() {
@Override
public void onSuccess(final List<Notification> notificationModels) {
binding.swipeRefreshLayout.setRefreshing(false);
notificationViewModel.getList().postValue(notificationModels);
}
@Override
public void onFailure(final Throwable t) {
try {
binding.swipeRefreshLayout.setRefreshing(false);
Toast.makeText(getContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
catch(Throwable e) {}
}
};
private final OnNotificationClickListener clickListener = new OnNotificationClickListener() { private final OnNotificationClickListener clickListener = new OnNotificationClickListener() {
@Override @Override
public void onProfileClick(final String username) { public void onProfileClick(final String username) {
@ -181,6 +203,7 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
@Override @Override
public void onCreate(@Nullable final Bundle savedInstanceState) { public void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
fragmentActivity = (AppCompatActivity) requireActivity();
context = getContext(); context = getContext();
if (context == null) return; if (context == null) return;
NotificationManagerCompat.from(context.getApplicationContext()).cancel(Constants.ACTIVITY_NOTIFICATION_ID); NotificationManagerCompat.from(context.getApplicationContext()).cancel(Constants.ACTIVITY_NOTIFICATION_ID);
@ -190,9 +213,10 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
} }
mediaService = MediaService.getInstance(null, null, 0); mediaService = MediaService.getInstance(null, null, 0);
final long userId = CookieUtils.getUserIdFromCookie(cookie); final long userId = CookieUtils.getUserIdFromCookie(cookie);
final String deviceUuid = Utils.settingsHelper.getString(Constants.DEVICE_UUID); deviceUuid = Utils.settingsHelper.getString(Constants.DEVICE_UUID);
csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie); csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
friendshipService = FriendshipService.getInstance(deviceUuid, csrfToken, userId); friendshipService = FriendshipService.getInstance(deviceUuid, csrfToken, userId);
newsService = NewsService.getInstance();
} }
@NonNull @NonNull
@ -217,6 +241,7 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
private void init() { private void init() {
final NotificationsViewerFragmentArgs fragmentArgs = NotificationsViewerFragmentArgs.fromBundle(getArguments()); final NotificationsViewerFragmentArgs fragmentArgs = NotificationsViewerFragmentArgs.fromBundle(getArguments());
type = fragmentArgs.getType(); type = fragmentArgs.getType();
targetId = fragmentArgs.getTargetId();
final Context context = getContext(); final Context context = getContext();
CookieUtils.setupCookies(settingsHelper.getString(Constants.COOKIE)); CookieUtils.setupCookies(settingsHelper.getString(Constants.COOKIE));
binding.swipeRefreshLayout.setOnRefreshListener(this); binding.swipeRefreshLayout.setOnRefreshListener(this);
@ -231,8 +256,10 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
@Override @Override
public void onRefresh() { public void onRefresh() {
binding.swipeRefreshLayout.setRefreshing(true); binding.swipeRefreshLayout.setRefreshing(true);
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
switch (type) { switch (type) {
case "notif": case "notif":
if (actionBar != null) actionBar.setTitle(R.string.action_notif);
new NotificationsFetcher(true, new FetchListener<List<Notification>>() { new NotificationsFetcher(true, new FetchListener<List<Notification>>() {
@Override @Override
public void onResult(final List<Notification> notificationModels) { public void onResult(final List<Notification> notificationModels) {
@ -251,23 +278,12 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
break; break;
case "ayml": case "ayml":
final NewsService newsService = NewsService.getInstance(); if (actionBar != null) actionBar.setTitle(R.string.action_ayml);
newsService.fetchSuggestions(csrfToken, new ServiceCallback<List<Notification>>() { newsService.fetchSuggestions(csrfToken, deviceUuid, cb);
@Override break;
public void onSuccess(final List<Notification> notificationModels) { case "chaining":
binding.swipeRefreshLayout.setRefreshing(false); if (actionBar != null) actionBar.setTitle(R.string.action_ayml);
notificationViewModel.getList().postValue(notificationModels); newsService.fetchChaining(targetId, cb);
}
@Override
public void onFailure(final Throwable t) {
try {
binding.swipeRefreshLayout.setRefreshing(false);
Toast.makeText(getContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
catch(Throwable e) {}
}
});
break; break;
} }
} }

View File

@ -56,7 +56,6 @@ import awais.instagrabber.R;
import awais.instagrabber.activities.MainActivity; import awais.instagrabber.activities.MainActivity;
import awais.instagrabber.adapters.FeedAdapterV2; import awais.instagrabber.adapters.FeedAdapterV2;
import awais.instagrabber.adapters.HighlightsAdapter; import awais.instagrabber.adapters.HighlightsAdapter;
import awais.instagrabber.asyncs.CreateThreadAction;
import awais.instagrabber.asyncs.ProfileFetcher; import awais.instagrabber.asyncs.ProfileFetcher;
import awais.instagrabber.asyncs.ProfilePostFetchService; import awais.instagrabber.asyncs.ProfilePostFetchService;
import awais.instagrabber.asyncs.UsernameFetcher; import awais.instagrabber.asyncs.UsernameFetcher;
@ -125,6 +124,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
private HighlightsViewModel highlightsViewModel; private HighlightsViewModel highlightsViewModel;
private MenuItem blockMenuItem; private MenuItem blockMenuItem;
private MenuItem restrictMenuItem; private MenuItem restrictMenuItem;
private MenuItem chainingMenuItem;
private boolean highlightsFetching; private boolean highlightsFetching;
private boolean postsSetupDone = false; private boolean postsSetupDone = false;
private Set<Media> selectedFeedModels; private Set<Media> selectedFeedModels;
@ -364,11 +364,31 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
inflater.inflate(R.menu.profile_menu, menu); inflater.inflate(R.menu.profile_menu, menu);
blockMenuItem = menu.findItem(R.id.block); blockMenuItem = menu.findItem(R.id.block);
if (blockMenuItem != null) { if (blockMenuItem != null) {
blockMenuItem.setVisible(false); if (profileModel != null) {
blockMenuItem.setVisible(!Objects.equals(profileModel.getPk(), CookieUtils.getUserIdFromCookie(cookie)));
blockMenuItem.setTitle(profileModel.getFriendshipStatus().isBlocking() ? R.string.unblock : R.string.block);
} else {
blockMenuItem.setVisible(false);
}
} }
restrictMenuItem = menu.findItem(R.id.restrict); restrictMenuItem = menu.findItem(R.id.restrict);
if (restrictMenuItem != null) { if (restrictMenuItem != null) {
restrictMenuItem.setVisible(false); if (profileModel != null) {
restrictMenuItem.setVisible(!Objects.equals(profileModel.getPk(), CookieUtils.getUserIdFromCookie(cookie)));
restrictMenuItem.setTitle(profileModel.getFriendshipStatus().isRestricted() ? R.string.unrestrict : R.string.restrict);
}
else {
restrictMenuItem.setVisible(false);
}
}
chainingMenuItem = menu.findItem(R.id.chaining);
if (chainingMenuItem != null) {
if (profileModel != null) {
chainingMenuItem.setVisible(!Objects.equals(profileModel.getPk(), CookieUtils.getUserIdFromCookie(cookie)));
}
else {
chainingMenuItem.setVisible(false);
}
} }
} }
@ -433,6 +453,12 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
}); });
return true; return true;
} }
if (item.getItemId() == R.id.chaining) {
if (!isLoggedIn) return false;
final NavDirections navDirections = ProfileFragmentDirections.actionGlobalNotificationsViewerFragment("chaining", profileModel.getPk());
NavHostFragment.findNavController(this).navigate(navDirections);
return true;
}
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@ -884,15 +910,10 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
blockMenuItem.setTitle(R.string.block); blockMenuItem.setTitle(R.string.block);
} }
} }
return; if (chainingMenuItem != null && !Objects.equals(profileId, myId)) {
} chainingMenuItem.setVisible(true);
if (!isReallyPrivate() && restrictMenuItem != null) {
restrictMenuItem.setVisible(true);
if (profileModel.getFriendshipStatus().isRestricted()) {
restrictMenuItem.setTitle(R.string.unrestrict);
} else {
restrictMenuItem.setTitle(R.string.restrict);
} }
return;
} }
} }

View File

@ -134,12 +134,12 @@ public class MorePreferencesFragment extends BasePreferencesFragment {
screen.addPreference(getDivider(context)); screen.addPreference(getDivider(context));
if (isLoggedIn) { if (isLoggedIn) {
screen.addPreference(getPreference(R.string.action_notif, R.drawable.ic_not_liked, preference -> { screen.addPreference(getPreference(R.string.action_notif, R.drawable.ic_not_liked, preference -> {
final NavDirections navDirections = MorePreferencesFragmentDirections.actionGlobalNotificationsViewerFragment("notif"); final NavDirections navDirections = MorePreferencesFragmentDirections.actionGlobalNotificationsViewerFragment("notif", 0l);
NavHostFragment.findNavController(this).navigate(navDirections); NavHostFragment.findNavController(this).navigate(navDirections);
return true; return true;
})); }));
screen.addPreference(getPreference(R.string.action_ayml, R.drawable.ic_suggested_users, preference -> { screen.addPreference(getPreference(R.string.action_ayml, R.drawable.ic_suggested_users, preference -> {
final NavDirections navDirections = MorePreferencesFragmentDirections.actionGlobalNotificationsViewerFragment("ayml"); final NavDirections navDirections = MorePreferencesFragmentDirections.actionGlobalNotificationsViewerFragment("ayml", 0l);
NavHostFragment.findNavController(this).navigate(navDirections); NavHostFragment.findNavController(this).navigate(navDirections);
return true; return true;
})); }));

View File

@ -4,6 +4,7 @@ import java.util.Map;
import awais.instagrabber.repositories.responses.AymlResponse; import awais.instagrabber.repositories.responses.AymlResponse;
import awais.instagrabber.repositories.responses.NewsInboxResponse; import awais.instagrabber.repositories.responses.NewsInboxResponse;
import awais.instagrabber.repositories.responses.UserSearchResponse;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.http.FieldMap; import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded; import retrofit2.http.FormUrlEncoded;
@ -23,4 +24,7 @@ public interface NewsRepository {
@FormUrlEncoded @FormUrlEncoded
@POST("/api/v1/discover/ayml/") @POST("/api/v1/discover/ayml/")
Call<AymlResponse> 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);
@GET("/api/v1/discover/chaining/")
Call<UserSearchResponse> getChaining(@Header("User-Agent") String userAgent, @Query(value = "target_id") long targetId);
} }

View File

@ -20,6 +20,7 @@ public class NotificationArgs {
private final double timestamp; private final double timestamp;
private final String profileName; private final String profileName;
private final String fullName; // for AYML, not naturally generated private final String fullName; // for AYML, not naturally generated
private final boolean isVerified; // mostly for AYML, not sure about notif
public NotificationArgs(final String text, public NotificationArgs(final String text,
final String richText, // for AYML, this is the algorithm final String richText, // for AYML, this is the algorithm
@ -28,7 +29,8 @@ public class NotificationArgs {
final List<NotificationImage> media, final List<NotificationImage> media,
final double timestamp, final double timestamp,
final String profileName, final String profileName,
final String fullName) { final String fullName,
final boolean isVerified) {
this.text = text; this.text = text;
this.richText = richText; this.richText = richText;
this.profileId = profileId; this.profileId = profileId;
@ -37,6 +39,7 @@ public class NotificationArgs {
this.timestamp = timestamp; this.timestamp = timestamp;
this.profileName = profileName; this.profileName = profileName;
this.fullName = fullName; this.fullName = fullName;
this.isVerified = isVerified;
} }
public String getText() { public String getText() {
@ -67,6 +70,10 @@ public class NotificationArgs {
return timestamp; return timestamp;
} }
public boolean isVerified() {
return isVerified;
}
@NonNull @NonNull
public String getDateTime() { public String getDateTime() {
return Utils.datetimeParser.format(new Date(Math.round(timestamp * 1000))); return Utils.datetimeParser.format(new Date(Math.round(timestamp * 1000)));

View File

@ -30,6 +30,7 @@ public class User implements Serializable {
private final HdProfilePicUrlInfo hdProfilePicUrlInfo; private final HdProfilePicUrlInfo hdProfilePicUrlInfo;
private final String profileContext; private final String profileContext;
private final List<UserProfileContextLink> profileContextLinksWithUserIds; private final List<UserProfileContextLink> profileContextLinksWithUserIds;
private final String socialContext;
public User(final long pk, public User(final long pk,
final String username, final String username,
@ -55,7 +56,8 @@ public class User implements Serializable {
final String publicEmail, final String publicEmail,
final HdProfilePicUrlInfo hdProfilePicUrlInfo, final HdProfilePicUrlInfo hdProfilePicUrlInfo,
final String profileContext, final String profileContext,
final List<UserProfileContextLink> profileContextLinksWithUserIds) { final List<UserProfileContextLink> profileContextLinksWithUserIds,
final String socialContext) {
this.pk = pk; this.pk = pk;
this.username = username; this.username = username;
this.fullName = fullName; this.fullName = fullName;
@ -81,6 +83,7 @@ public class User implements Serializable {
this.hdProfilePicUrlInfo = hdProfilePicUrlInfo; this.hdProfilePicUrlInfo = hdProfilePicUrlInfo;
this.profileContext = profileContext; this.profileContext = profileContext;
this.profileContextLinksWithUserIds = profileContextLinksWithUserIds; this.profileContextLinksWithUserIds = profileContextLinksWithUserIds;
this.socialContext = socialContext;
} }
public long getPk() { public long getPk() {
@ -183,6 +186,10 @@ public class User implements Serializable {
return profileContext; return profileContext;
} }
public String getSocialContext() {
return socialContext;
}
public List<UserProfileContextLink> getProfileContextLinks() { public List<UserProfileContextLink> getProfileContextLinks() {
return profileContextLinksWithUserIds; return profileContextLinksWithUserIds;
} }

View File

@ -782,7 +782,8 @@ public final class ResponseBodyUtils {
null, null,
friendshipStatus, friendshipStatus,
owner.optBoolean("is_verified"), owner.optBoolean("is_verified"),
false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0, null, null, null, null); false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0, null, null,
null, null, null);
} }
final String id = feedItem.getString(Constants.EXTRAS_ID); final String id = feedItem.getString(Constants.EXTRAS_ID);
final ImageVersions2 imageVersions2 = new ImageVersions2( final ImageVersions2 imageVersions2 = new ImageVersions2(

View File

@ -245,6 +245,7 @@ public class GraphQLService extends BaseService {
null, null,
null, null,
null, null,
null,
null null
)); ));
// userModels.add(new ProfileModel(userObject.optBoolean("is_private"), // userModels.add(new ProfileModel(userObject.optBoolean("is_private"),
@ -338,6 +339,7 @@ public class GraphQLService extends BaseService {
null, null,
null, null,
null, null,
null,
null)); null));
} catch (JSONException e) { } catch (JSONException e) {
Log.e(TAG, "onResponse", e); Log.e(TAG, "onResponse", e);

View File

@ -21,6 +21,7 @@ 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.AymlResponse;
import awais.instagrabber.repositories.responses.AymlUser; import awais.instagrabber.repositories.responses.AymlUser;
import awais.instagrabber.repositories.responses.UserSearchResponse;
import awais.instagrabber.repositories.responses.NewsInboxResponse; import awais.instagrabber.repositories.responses.NewsInboxResponse;
import awais.instagrabber.repositories.responses.Notification; import awais.instagrabber.repositories.responses.Notification;
import awais.instagrabber.repositories.responses.NotificationArgs; import awais.instagrabber.repositories.responses.NotificationArgs;
@ -126,7 +127,8 @@ public class NewsService extends BaseService {
)), )),
data.getLong("timestamp"), data.getLong("timestamp"),
user.getString("username"), user.getString("username"),
null null,
false
), ),
type, type,
data.getString(Constants.EXTRAS_ID) data.getString(Constants.EXTRAS_ID)
@ -150,7 +152,8 @@ public class NewsService extends BaseService {
null, null,
0L, 0L,
data.getString("username"), data.getString("username"),
data.optString("full_name") data.optString("full_name"),
data.optBoolean("is_verified")
), ),
"REQUEST", "REQUEST",
data.getString(Constants.EXTRAS_ID) data.getString(Constants.EXTRAS_ID)
@ -172,6 +175,7 @@ public class NewsService extends BaseService {
} }
public void fetchSuggestions(final String csrfToken, public void fetchSuggestions(final String csrfToken,
final String deviceUuid,
final ServiceCallback<List<Notification>> 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());
@ -205,7 +209,8 @@ public class NewsService extends BaseService {
null, null,
0L, 0L,
u.getUsername(), u.getUsername(),
u.getFullName() u.getFullName(),
u.isVerified()
), ),
"AYML", "AYML",
i.getUuid() i.getUuid()
@ -222,4 +227,45 @@ public class NewsService extends BaseService {
} }
}); });
} }
public void fetchChaining(final long targetId, final ServiceCallback<List<Notification>> callback) {
final Call<UserSearchResponse> request = repository.getChaining(appUa, targetId);
request.enqueue(new Callback<UserSearchResponse>() {
@Override
public void onResponse(@NonNull final Call<UserSearchResponse> call, @NonNull final Response<UserSearchResponse> response) {
final UserSearchResponse body = response.body();
if (body == null) {
callback.onSuccess(null);
return;
}
final List<Notification> newsItems = body.getUsers().stream()
.map(u -> {
return new Notification(
new NotificationArgs(
u.getSocialContext(),
null,
u.getPk(),
u.getProfilePicUrl(),
null,
0L,
u.getUsername(),
u.getFullName(),
u.isVerified()
),
"AYML",
u.getProfilePicId() // placeholder
);
})
.collect(Collectors.toList());
callback.onSuccess(newsItems);
}
@Override
public void onFailure(@NonNull final Call<UserSearchResponse> call, @NonNull final Throwable t) {
callback.onFailure(t);
// Log.e(TAG, "onFailure: ", t);
}
});
}
} }

View File

@ -174,6 +174,7 @@ public class StoriesService extends BaseService {
null, null,
null, null,
null, null,
null,
null null
); );
final String id = node.getString("id"); final String id = node.getString("id");
@ -235,6 +236,7 @@ public class StoriesService extends BaseService {
null, null,
null, null,
null, null,
null,
null null
); );
final String id = node.getString("id"); final String id = node.getString("id");

View File

@ -45,6 +45,21 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:text="username" /> tools:text="username" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/isVerified"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:paddingEnd="16dp"
android:paddingRight="16dp"
android:adjustViewBounds="true"
android:scaleType="fitStart"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/tvComment"
app:layout_constraintEnd_toStartOf="@id/ivPreviewPic"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/verified"
tools:visibility="visible" />
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvComment" android:id="@+id/tvComment"
android:layout_width="0dp" android:layout_width="0dp"

View File

@ -20,4 +20,10 @@
android:title="@string/restrict" android:title="@string/restrict"
android:visible="false" android:visible="false"
app:showAsAction="never" /> app:showAsAction="never" />
<item
android:id="@+id/chaining"
android:title="@string/action_ayml"
android:visible="false"
app:showAsAction="never" />
</menu> </menu>

View File

@ -41,6 +41,9 @@
android:name="type" android:name="type"
app:argType="string" app:argType="string"
app:nullable="false" /> app:nullable="false" />
<argument
android:name="targetId"
app:argType="long" />
</action> </action>
<include app:graph="@navigation/comments_nav_graph" /> <include app:graph="@navigation/comments_nav_graph" />

View File

@ -89,6 +89,9 @@
android:name="type" android:name="type"
app:argType="string" app:argType="string"
app:nullable="false" /> app:nullable="false" />
<argument
android:name="targetId"
app:argType="long" />
</action> </action>
<fragment <fragment

View File

@ -89,6 +89,9 @@
android:name="type" android:name="type"
app:argType="string" app:argType="string"
app:nullable="false" /> app:nullable="false" />
<argument
android:name="targetId"
app:argType="long" />
</action> </action>
<include app:graph="@navigation/story_list_nav_graph" /> <include app:graph="@navigation/story_list_nav_graph" />

View File

@ -54,6 +54,9 @@
android:name="type" android:name="type"
app:argType="string" app:argType="string"
app:nullable="false" /> app:nullable="false" />
<argument
android:name="targetId"
app:argType="long" />
</action> </action>
<fragment <fragment

View File

@ -14,6 +14,9 @@
android:name="type" android:name="type"
app:argType="string" app:argType="string"
app:nullable="false" /> app:nullable="false" />
<argument
android:name="targetId"
app:argType="long" />
<action <action
android:id="@+id/action_notificationsViewerFragment_to_storyViewerFragment" android:id="@+id/action_notificationsViewerFragment_to_storyViewerFragment"
app:destination="@id/storyViewerFragment" /> app:destination="@id/storyViewerFragment" />

View File

@ -80,6 +80,9 @@
android:name="type" android:name="type"
app:argType="string" app:argType="string"
app:nullable="false" /> app:nullable="false" />
<argument
android:name="targetId"
app:argType="long" />
</action> </action>
<include app:graph="@navigation/saved_nav_graph" /> <include app:graph="@navigation/saved_nav_graph" />

View File

@ -64,15 +64,6 @@
app:nullable="false" /> app:nullable="false" />
</action> </action>
<action
android:id="@+id/action_global_notificationsViewerFragment"
app:destination="@id/notification_viewer_nav_graph">
<argument
android:name="type"
app:argType="string"
app:nullable="false" />
</action>
<fragment <fragment
android:id="@+id/savedCollectionsFragment" android:id="@+id/savedCollectionsFragment"
android:name="awais.instagrabber.fragments.SavedCollectionsFragment" android:name="awais.instagrabber.fragments.SavedCollectionsFragment"