1
0
Fork 0
mirror of https://github.com/KokaKiwi/BarInsta synced 2026-03-05 03:51:36 +00:00

add suggested users feature

This commit is contained in:
Austin Huang 2020-12-30 13:26:16 -05:00
parent 3242fdc7ef
commit 975654961f
No known key found for this signature in database
GPG key ID: 84C23AA04587A91F
14 changed files with 176 additions and 24 deletions

View file

@ -53,18 +53,22 @@ public final class NotificationViewHolder extends RecyclerView.ViewHolder {
case RESPONDED_STORY:
subtext = model.getText();
break;
case AYML:
subtext = model.getPostId();
break;
}
binding.tvSubComment.setText(model.getType() == NotificationType.AYML ? model.getText() : subtext);
if (text == -1 && subtext != null) {
binding.tvComment.setText(subtext);
binding.tvSubComment.setVisibility(View.GONE);
binding.tvComment.setVisibility(TextUtils.isEmpty(subtext) ? View.GONE : View.VISIBLE);
binding.tvSubComment.setVisibility(model.getType() == NotificationType.AYML ? View.VISIBLE : View.GONE);
}
else if (text != -1) {
binding.tvComment.setText(text);
binding.tvSubComment.setText(subtext);
binding.tvSubComment.setVisibility(subtext == null ? View.GONE : View.VISIBLE);
}
if (model.getType() != NotificationType.REQUEST) {
if (model.getType() != NotificationType.REQUEST && model.getType() != NotificationType.AYML) {
binding.tvDate.setText(model.getDateTime());
}

View file

@ -26,6 +26,8 @@ import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import java.util.List;
import awais.instagrabber.R;
import awais.instagrabber.adapters.NotificationsAdapter;
import awais.instagrabber.adapters.NotificationsAdapter.OnNotificationClickListener;
@ -46,6 +48,7 @@ import awais.instagrabber.utils.Utils;
import awais.instagrabber.viewmodels.NotificationViewModel;
import awais.instagrabber.webservices.FriendshipService;
import awais.instagrabber.webservices.MediaService;
import awais.instagrabber.webservices.NewsService;
import awais.instagrabber.webservices.ServiceCallback;
import static awais.instagrabber.utils.Utils.settingsHelper;
@ -59,8 +62,8 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
private NotificationViewModel notificationViewModel;
private FriendshipService friendshipService;
private MediaService mediaService;
private String userId;
private String csrfToken;
private NewsService newsService;
private String userId, csrfToken, type;
private Context context;
private final OnNotificationClickListener clickListener = new OnNotificationClickListener() {
@ -96,7 +99,7 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
public void onNotificationClick(final NotificationModel model) {
if (model == null) return;
final String username = model.getUsername();
if (model.getType() == NotificationType.FOLLOW) {
if (model.getType() == NotificationType.FOLLOW || model.getType() == NotificationType.AYML) {
openProfile(username);
}
else {
@ -242,6 +245,8 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
}
private void init() {
final NotificationsViewerFragmentArgs fragmentArgs = NotificationsViewerFragmentArgs.fromBundle(getArguments());
type = fragmentArgs.getType();
final Context context = getContext();
CookieUtils.setupCookies(settingsHelper.getString(Constants.COOKIE));
binding.swipeRefreshLayout.setOnRefreshListener(this);
@ -256,10 +261,30 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
@Override
public void onRefresh() {
binding.swipeRefreshLayout.setRefreshing(true);
new NotificationsFetcher(true, notificationModels -> {
binding.swipeRefreshLayout.setRefreshing(false);
notificationViewModel.getList().postValue(notificationModels);
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
switch (type) {
case "notif":
new NotificationsFetcher(true, notificationModels -> {
binding.swipeRefreshLayout.setRefreshing(false);
notificationViewModel.getList().postValue(notificationModels);
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
break;
case "ayml":
newsService = NewsService.getInstance();
newsService.fetchSuggestions(csrfToken, new ServiceCallback<List<NotificationModel>>() {
@Override
public void onSuccess(final List<NotificationModel> notificationModels) {
binding.swipeRefreshLayout.setRefreshing(false);
notificationViewModel.getList().postValue(notificationModels);
}
@Override
public void onFailure(final Throwable t) {
binding.swipeRefreshLayout.setRefreshing(false);
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
}
});
break;
}
}
private void openProfile(final String username) {

View file

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

View file

@ -15,8 +15,10 @@ public enum NotificationType implements Serializable {
COMMENT_LIKE("13"),
TAGGED_COMMENT("14"),
RESPONDED_STORY("213"),
// efr
REQUEST("REQUEST");
// efr - random value
REQUEST("REQUEST"),
// ayml - random value
AYML("AYML");
private final String itemType;
private static final Map<String, NotificationType> map = new HashMap<>();

View file

@ -21,4 +21,9 @@ public interface NewsRepository {
@Headers("User-Agent: " + Constants.I_USER_AGENT)
@GET("/api/v1/news/inbox/")
Call<String> appInbox(@Query(value = "mark_as_seen", encoded = true) boolean markAsSeen);
@FormUrlEncoded
@Headers("User-Agent: " + Constants.I_USER_AGENT)
@POST("/api/v1/discover/ayml/")
Call<String> getAyml(@FieldMap final Map<String, String> form);
}

View file

@ -12,14 +12,15 @@ import java.util.ArrayList;
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 awais.instagrabber.BuildConfig;
import awais.instagrabber.models.NotificationModel;
import awais.instagrabber.models.enums.NotificationType;
import awais.instagrabber.repositories.NewsRepository;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.NetworkUtils;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
@ -89,7 +90,6 @@ public class NewsService extends BaseService {
public void fetchWebInbox(final boolean markAsSeen,
final ServiceCallback<List<NotificationModel>> callback) {
final List<NotificationModel> result = new ArrayList<>();
final Call<String> request = repository.webInbox();
request.enqueue(new Callback<String>() {
@Override
@ -100,6 +100,7 @@ public class NewsService extends BaseService {
return;
}
try {
final List<NotificationModel> result = new ArrayList<>();
final JSONObject page = new JSONObject(body)
.getJSONObject("graphql")
.getJSONObject("user");
@ -168,7 +169,7 @@ public class NewsService extends BaseService {
final String type = itemJson.getString("story_type");
final NotificationType notificationType = NotificationType.valueOfType(type);
if (notificationType == null) {
Log.d("austin_debug", "unhandled news type: "+itemJson);
if (BuildConfig.DEBUG) Log.d("austin_debug", "unhandled news type: "+itemJson);
return null;
}
final JSONObject data = itemJson.getJSONObject("args");
@ -194,4 +195,67 @@ public class NewsService extends BaseService {
}
return result;
}
public void fetchSuggestions(final String csrfToken,
final ServiceCallback<List<NotificationModel>> callback) {
final Map<String, String> form = new HashMap<>();
form.put("_uuid", UUID.randomUUID().toString());
form.put("_csrftoken", csrfToken);
form.put("phone_id", UUID.randomUUID().toString());
form.put("device_id", UUID.randomUUID().toString());
form.put("module", "discover_people");
form.put("paginate", "false");
final Call<String> request = repository.getAyml(form);
request.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
final String 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");
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);
}
}
@Override
public void onFailure(@NonNull final Call<String> 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.getString("pk"),
data.getString("username"),
data.getString("profile_pic_url"),
data.getString("full_name"), // just borrowing this field
null,
NotificationType.AYML);
}
}