mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-22 22:57:29 +00:00
profile viewer improvement
1. restore tagged posts access for anons 2. chip-ify profile viewer, bring it to consistency with tag/loc viewers 3. add a following/er status chip 4. pluralize "post(s)" and "follower(s)" 5. correct favourited string
This commit is contained in:
parent
8240829fa8
commit
4d6ac5d293
@ -122,6 +122,7 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, List<CommentMod
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
final JSONObject likedBy = childComment.optJSONObject("edge_liked_by");
|
final JSONObject likedBy = childComment.optJSONObject("edge_liked_by");
|
||||||
@ -207,6 +208,7 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, List<CommentMod
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
final JSONObject likedBy = comment.optJSONObject("edge_liked_by");
|
final JSONObject likedBy = comment.optJSONObject("edge_liked_by");
|
||||||
@ -256,6 +258,7 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, List<CommentMod
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
tempJsonObject = childComment.optJSONObject("edge_liked_by");
|
tempJsonObject = childComment.optJSONObject("edge_liked_by");
|
||||||
|
@ -65,6 +65,7 @@ public final class PostFetcher extends AsyncTask<Void, Void, FeedModel> {
|
|||||||
owner.optInt("edge_followed_by"),
|
owner.optInt("edge_followed_by"),
|
||||||
-1,
|
-1,
|
||||||
owner.optBoolean("followed_by_viewer"),
|
owner.optBoolean("followed_by_viewer"),
|
||||||
|
false,
|
||||||
owner.optBoolean("restricted_by_viewer"),
|
owner.optBoolean("restricted_by_viewer"),
|
||||||
owner.optBoolean("blocked_by_viewer"),
|
owner.optBoolean("blocked_by_viewer"),
|
||||||
owner.optBoolean("requested_by_viewer")
|
owner.optBoolean("requested_by_viewer")
|
||||||
|
@ -72,6 +72,7 @@ public final class ProfileFetcher extends AsyncTask<Void, Void, ProfileModel> {
|
|||||||
user.getJSONObject("edge_followed_by").getLong("count"),
|
user.getJSONObject("edge_followed_by").getLong("count"),
|
||||||
user.getJSONObject("edge_follow").getLong("count"),
|
user.getJSONObject("edge_follow").getLong("count"),
|
||||||
user.optBoolean("followed_by_viewer"),
|
user.optBoolean("followed_by_viewer"),
|
||||||
|
user.optBoolean("follows_viewer"),
|
||||||
user.optBoolean("restricted_by_viewer"),
|
user.optBoolean("restricted_by_viewer"),
|
||||||
user.optBoolean("blocked_by_viewer"),
|
user.optBoolean("blocked_by_viewer"),
|
||||||
user.optBoolean("requested_by_viewer"));
|
user.optBoolean("requested_by_viewer"));
|
||||||
|
@ -50,7 +50,7 @@ public class SavedPostFetchService implements PostFetcher.PostFetchService {
|
|||||||
profileService.fetchLiked(nextMaxId, callback);
|
profileService.fetchLiked(nextMaxId, callback);
|
||||||
break;
|
break;
|
||||||
case TAGGED:
|
case TAGGED:
|
||||||
profileService.fetchTagged(profileId, nextMaxId, callback);
|
profileService.fetchTagged(profileId, 30, nextMaxId, callback);
|
||||||
break;
|
break;
|
||||||
case SAVED:
|
case SAVED:
|
||||||
default:
|
default:
|
||||||
|
@ -513,7 +513,9 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
}));
|
}));
|
||||||
hashtagDetailsBinding.mainHashtagImage.setImageURI(hashtagModel.getSdProfilePic());
|
hashtagDetailsBinding.mainHashtagImage.setImageURI(hashtagModel.getSdProfilePic());
|
||||||
final String postCount = String.valueOf(hashtagModel.getPostCount());
|
final String postCount = String.valueOf(hashtagModel.getPostCount());
|
||||||
final SpannableStringBuilder span = new SpannableStringBuilder(getString(R.string.main_posts_count_inline, postCount));
|
final SpannableStringBuilder span = new SpannableStringBuilder(getResources().getQuantityString(R.plurals.main_posts_count_inline,
|
||||||
|
hashtagModel.getPostCount() > 2000000000L ? 2000000000 : hashtagModel.getPostCount().intValue(),
|
||||||
|
postCount));
|
||||||
span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
|
span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
|
||||||
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
|
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
|
||||||
hashtagDetailsBinding.mainTagPostCount.setText(span);
|
hashtagDetailsBinding.mainTagPostCount.setText(span);
|
||||||
|
@ -400,7 +400,8 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
|
|||||||
// binding.swipeRefreshLayout.setRefreshing(true);
|
// binding.swipeRefreshLayout.setRefreshing(true);
|
||||||
locationDetailsBinding.mainLocationImage.setImageURI(locationModel.getSdProfilePic());
|
locationDetailsBinding.mainLocationImage.setImageURI(locationModel.getSdProfilePic());
|
||||||
final String postCount = String.valueOf(locationModel.getPostCount());
|
final String postCount = String.valueOf(locationModel.getPostCount());
|
||||||
final SpannableStringBuilder span = new SpannableStringBuilder(getString(R.string.main_posts_count_inline,
|
final SpannableStringBuilder span = new SpannableStringBuilder(getResources().getQuantityString(R.plurals.main_posts_count_inline,
|
||||||
|
locationModel.getPostCount() > 2000000000L ? 2000000000 : locationModel.getPostCount().intValue(),
|
||||||
postCount));
|
postCount));
|
||||||
span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
|
span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
|
||||||
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
|
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
|
||||||
|
@ -370,10 +370,10 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
}
|
}
|
||||||
if (item.getItemId() == R.id.restrict) {
|
if (item.getItemId() == R.id.restrict) {
|
||||||
if (!isLoggedIn) return false;
|
if (!isLoggedIn) return false;
|
||||||
final String action = profileModel.getRestricted() ? "Unrestrict" : "Restrict";
|
final String action = profileModel.isRestricted() ? "Unrestrict" : "Restrict";
|
||||||
friendshipService.toggleRestrict(
|
friendshipService.toggleRestrict(
|
||||||
profileModel.getId(),
|
profileModel.getId(),
|
||||||
!profileModel.getRestricted(),
|
!profileModel.isRestricted(),
|
||||||
CookieUtils.getCsrfTokenFromCookie(cookie),
|
CookieUtils.getCsrfTokenFromCookie(cookie),
|
||||||
new ServiceCallback<FriendshipRepoRestrictRootResponse>() {
|
new ServiceCallback<FriendshipRepoRestrictRootResponse>() {
|
||||||
@Override
|
@Override
|
||||||
@ -392,7 +392,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
if (item.getItemId() == R.id.block) {
|
if (item.getItemId() == R.id.block) {
|
||||||
final String userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie);
|
final String userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie);
|
||||||
if (!isLoggedIn) return false;
|
if (!isLoggedIn) return false;
|
||||||
if (profileModel.getBlocked()) {
|
if (profileModel.isBlocked()) {
|
||||||
friendshipService.unblock(
|
friendshipService.unblock(
|
||||||
userIdFromCookie,
|
userIdFromCookie,
|
||||||
profileModel.getId(),
|
profileModel.getId(),
|
||||||
@ -571,44 +571,85 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
fetchStoryAndHighlights(profileId);
|
fetchStoryAndHighlights(profileId);
|
||||||
}
|
}
|
||||||
setupButtons(profileId, myId);
|
setupButtons(profileId, myId);
|
||||||
if (!profileId.equals(myId)) {
|
profileDetailsBinding.favChip.setVisibility(View.VISIBLE);
|
||||||
profileDetailsBinding.favCb.setVisibility(View.VISIBLE);
|
final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(getContext()));
|
||||||
favoriteRepository.getFavorite(username.substring(1), FavoriteType.USER, new RepositoryCallback<Favorite>() {
|
favoriteRepository.getFavorite(profileModel.getUsername(), FavoriteType.USER, new RepositoryCallback<Favorite>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final Favorite result) {
|
public void onSuccess(final Favorite result) {
|
||||||
profileDetailsBinding.favCb.setChecked(true);
|
profileDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24);
|
||||||
profileDetailsBinding.favCb.setButtonDrawable(R.drawable.ic_star_check_24);
|
profileDetailsBinding.favChip.setText(R.string.added_to_favs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDataNotAvailable() {
|
public void onDataNotAvailable() {
|
||||||
profileDetailsBinding.favCb.setChecked(false);
|
profileDetailsBinding.favChip.setChipIconResource(R.drawable.ic_outline_star_plus_24);
|
||||||
profileDetailsBinding.favCb.setButtonDrawable(R.drawable.ic_outline_star_plus_24);
|
profileDetailsBinding.favChip.setText(R.string.add_to_favorites);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
profileDetailsBinding.favChip.setOnClickListener(
|
||||||
profileDetailsBinding.favCb.setVisibility(View.GONE);
|
v -> favoriteRepository.getFavorite(profileModel.getUsername(), FavoriteType.USER, new RepositoryCallback<Favorite>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(final Favorite result) {
|
||||||
|
favoriteRepository.deleteFavorite(profileModel.getUsername(), FavoriteType.USER, new RepositoryCallback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(final Void result) {
|
||||||
|
profileDetailsBinding.favChip.setText(R.string.add_to_favorites);
|
||||||
|
profileDetailsBinding.favChip.setChipIconResource(R.drawable.ic_outline_star_plus_24);
|
||||||
|
showSnackbar(getString(R.string.removed_from_favs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDataNotAvailable() {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDataNotAvailable() {
|
||||||
|
final String finalUsername = username.startsWith("@") ? username.substring(1) : username;
|
||||||
|
favoriteRepository.insertOrUpdateFavorite(new Favorite(
|
||||||
|
-1,
|
||||||
|
finalUsername,
|
||||||
|
FavoriteType.USER,
|
||||||
|
profileModel.getName(),
|
||||||
|
profileModel.getSdProfilePic(),
|
||||||
|
new Date()
|
||||||
|
), new RepositoryCallback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(final Void result) {
|
||||||
|
profileDetailsBinding.favChip.setText(R.string.added_to_favs);
|
||||||
|
profileDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24);
|
||||||
|
showSnackbar(getString(R.string.added_to_favs));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDataNotAvailable() {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}));
|
||||||
profileDetailsBinding.mainProfileImage.setImageURI(profileModel.getHdProfilePic());
|
profileDetailsBinding.mainProfileImage.setImageURI(profileModel.getHdProfilePic());
|
||||||
|
|
||||||
final long followersCount = profileModel.getFollowersCount();
|
final Long followersCount = profileModel.getFollowersCount();
|
||||||
final long followingCount = profileModel.getFollowingCount();
|
final Long followingCount = profileModel.getFollowingCount();
|
||||||
|
|
||||||
final String postCount = String.valueOf(profileModel.getPostCount());
|
final String postCount = String.valueOf(profileModel.getPostCount());
|
||||||
|
|
||||||
SpannableStringBuilder span = new SpannableStringBuilder(getString(R.string.main_posts_count,
|
SpannableStringBuilder span = new SpannableStringBuilder(getResources().getQuantityString(R.plurals.main_posts_count_inline,
|
||||||
|
profileModel.getPostCount() > 2000000000L ? 2000000000 : profileModel.getPostCount().intValue(),
|
||||||
postCount));
|
postCount));
|
||||||
span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
|
span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
|
||||||
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
|
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
|
||||||
profileDetailsBinding.mainPostCount.setText(span);
|
profileDetailsBinding.mainPostCount.setText(span);
|
||||||
|
profileDetailsBinding.mainPostCount.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
final String followersCountStr = String.valueOf(followersCount);
|
final String followersCountStr = String.valueOf(followersCount);
|
||||||
final int followersCountStrLen = followersCountStr.length();
|
final int followersCountStrLen = followersCountStr.length();
|
||||||
span = new SpannableStringBuilder(getString(R.string.main_posts_followers,
|
span = new SpannableStringBuilder(getResources().getQuantityString(R.plurals.main_posts_followers,
|
||||||
|
followersCount > 2000000000L ? 2000000000 : followersCount.intValue(),
|
||||||
followersCountStr));
|
followersCountStr));
|
||||||
span.setSpan(new RelativeSizeSpan(1.2f), 0, followersCountStrLen, 0);
|
span.setSpan(new RelativeSizeSpan(1.2f), 0, followersCountStrLen, 0);
|
||||||
span.setSpan(new StyleSpan(Typeface.BOLD), 0, followersCountStrLen, 0);
|
span.setSpan(new StyleSpan(Typeface.BOLD), 0, followersCountStrLen, 0);
|
||||||
profileDetailsBinding.mainFollowers.setText(span);
|
profileDetailsBinding.mainFollowers.setText(span);
|
||||||
|
profileDetailsBinding.mainFollowers.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
final String followingCountStr = String.valueOf(followingCount);
|
final String followingCountStr = String.valueOf(followingCount);
|
||||||
final int followingCountStrLen = followingCountStr.length();
|
final int followingCountStrLen = followingCountStr.length();
|
||||||
@ -617,6 +658,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
span.setSpan(new RelativeSizeSpan(1.2f), 0, followingCountStrLen, 0);
|
span.setSpan(new RelativeSizeSpan(1.2f), 0, followingCountStrLen, 0);
|
||||||
span.setSpan(new StyleSpan(Typeface.BOLD), 0, followingCountStrLen, 0);
|
span.setSpan(new StyleSpan(Typeface.BOLD), 0, followingCountStrLen, 0);
|
||||||
profileDetailsBinding.mainFollowing.setText(span);
|
profileDetailsBinding.mainFollowing.setText(span);
|
||||||
|
profileDetailsBinding.mainFollowing.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
profileDetailsBinding.mainFullName.setText(TextUtils.isEmpty(profileModel.getName()) ? profileModel.getUsername()
|
profileDetailsBinding.mainFullName.setText(TextUtils.isEmpty(profileModel.getName()) ? profileModel.getUsername()
|
||||||
: profileModel.getName());
|
: profileModel.getName());
|
||||||
@ -701,10 +743,25 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
profileDetailsBinding.btnLiked.setVisibility(View.GONE);
|
profileDetailsBinding.btnLiked.setVisibility(View.GONE);
|
||||||
profileDetailsBinding.btnDM.setVisibility(View.VISIBLE); // maybe there is a judgment mechanism?
|
profileDetailsBinding.btnDM.setVisibility(View.VISIBLE); // maybe there is a judgment mechanism?
|
||||||
profileDetailsBinding.btnFollow.setVisibility(View.VISIBLE);
|
profileDetailsBinding.btnFollow.setVisibility(View.VISIBLE);
|
||||||
if (profileModel.getFollowing()) {
|
if (profileModel.isFollowing() || profileModel.isFollower()) {
|
||||||
|
profileDetailsBinding.mainStatus.setVisibility(View.VISIBLE);
|
||||||
|
if (!profileModel.isFollowing()) {
|
||||||
|
profileDetailsBinding.mainStatus.setChipBackgroundColor(getResources().getColorStateList(R.color.blue_800));
|
||||||
|
profileDetailsBinding.mainStatus.setText(R.string.status_follower);
|
||||||
|
}
|
||||||
|
else if (!profileModel.isFollower()) {
|
||||||
|
profileDetailsBinding.mainStatus.setChipBackgroundColor(getResources().getColorStateList(R.color.deep_orange_800));
|
||||||
|
profileDetailsBinding.mainStatus.setText(R.string.status_following);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
profileDetailsBinding.mainStatus.setChipBackgroundColor(getResources().getColorStateList(R.color.green_800));
|
||||||
|
profileDetailsBinding.mainStatus.setText(R.string.status_mutual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (profileModel.isFollowing()) {
|
||||||
profileDetailsBinding.btnFollow.setText(R.string.unfollow);
|
profileDetailsBinding.btnFollow.setText(R.string.unfollow);
|
||||||
profileDetailsBinding.btnFollow.setIconResource(R.drawable.ic_outline_person_add_disabled_24);
|
profileDetailsBinding.btnFollow.setIconResource(R.drawable.ic_outline_person_add_disabled_24);
|
||||||
} else if (profileModel.getRequested()) {
|
} else if (profileModel.isRequested()) {
|
||||||
profileDetailsBinding.btnFollow.setText(R.string.cancel);
|
profileDetailsBinding.btnFollow.setText(R.string.cancel);
|
||||||
profileDetailsBinding.btnFollow.setIconResource(R.drawable.ic_outline_person_add_disabled_24);
|
profileDetailsBinding.btnFollow.setIconResource(R.drawable.ic_outline_person_add_disabled_24);
|
||||||
} else {
|
} else {
|
||||||
@ -713,7 +770,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
}
|
}
|
||||||
if (restrictMenuItem != null) {
|
if (restrictMenuItem != null) {
|
||||||
restrictMenuItem.setVisible(true);
|
restrictMenuItem.setVisible(true);
|
||||||
if (profileModel.getRestricted()) {
|
if (profileModel.isRestricted()) {
|
||||||
restrictMenuItem.setTitle(R.string.unrestrict);
|
restrictMenuItem.setTitle(R.string.unrestrict);
|
||||||
} else {
|
} else {
|
||||||
restrictMenuItem.setTitle(R.string.restrict);
|
restrictMenuItem.setTitle(R.string.restrict);
|
||||||
@ -722,7 +779,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
profileDetailsBinding.btnTagged.setVisibility(profileModel.isReallyPrivate() ? View.GONE : View.VISIBLE);
|
profileDetailsBinding.btnTagged.setVisibility(profileModel.isReallyPrivate() ? View.GONE : View.VISIBLE);
|
||||||
if (blockMenuItem != null) {
|
if (blockMenuItem != null) {
|
||||||
blockMenuItem.setVisible(true);
|
blockMenuItem.setVisible(true);
|
||||||
if (profileModel.getBlocked()) {
|
if (profileModel.isBlocked()) {
|
||||||
blockMenuItem.setTitle(R.string.unblock);
|
blockMenuItem.setTitle(R.string.unblock);
|
||||||
} else {
|
} else {
|
||||||
blockMenuItem.setTitle(R.string.block);
|
blockMenuItem.setTitle(R.string.block);
|
||||||
@ -732,7 +789,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
}
|
}
|
||||||
if (!profileModel.isReallyPrivate() && restrictMenuItem != null) {
|
if (!profileModel.isReallyPrivate() && restrictMenuItem != null) {
|
||||||
restrictMenuItem.setVisible(true);
|
restrictMenuItem.setVisible(true);
|
||||||
if (profileModel.getRestricted()) {
|
if (profileModel.isRestricted()) {
|
||||||
restrictMenuItem.setTitle(R.string.unrestrict);
|
restrictMenuItem.setTitle(R.string.unrestrict);
|
||||||
} else {
|
} else {
|
||||||
restrictMenuItem.setTitle(R.string.restrict);
|
restrictMenuItem.setTitle(R.string.restrict);
|
||||||
@ -771,9 +828,34 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setupCommonListeners() {
|
private void setupCommonListeners() {
|
||||||
|
final Context context = getContext();
|
||||||
final String userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie);
|
final String userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie);
|
||||||
profileDetailsBinding.btnFollow.setOnClickListener(v -> {
|
profileDetailsBinding.btnFollow.setOnClickListener(v -> {
|
||||||
if (profileModel.getFollowing() || profileModel.getRequested()) {
|
if (profileModel.isFollowing() && profileModel.isPrivate()) {
|
||||||
|
new AlertDialog.Builder(context)
|
||||||
|
.setTitle(R.string.priv_acc)
|
||||||
|
.setMessage(R.string.priv_acc_confirm)
|
||||||
|
.setPositiveButton(R.string.confirm, (d, w) ->
|
||||||
|
friendshipService.unfollow(
|
||||||
|
userIdFromCookie,
|
||||||
|
profileModel.getId(),
|
||||||
|
CookieUtils.getCsrfTokenFromCookie(cookie),
|
||||||
|
new ServiceCallback<FriendshipRepoChangeRootResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(final FriendshipRepoChangeRootResponse result) {
|
||||||
|
// Log.d(TAG, "Unfollow success: " + result);
|
||||||
|
onRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(final Throwable t) {
|
||||||
|
Log.e(TAG, "Error unfollowing", t);
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
else if (profileModel.isFollowing() || profileModel.isRequested()) {
|
||||||
friendshipService.unfollow(
|
friendshipService.unfollow(
|
||||||
userIdFromCookie,
|
userIdFromCookie,
|
||||||
profileModel.getId(),
|
profileModel.getId(),
|
||||||
@ -860,66 +942,12 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
}
|
}
|
||||||
showProfilePicDialog();
|
showProfilePicDialog();
|
||||||
};
|
};
|
||||||
final Context context = getContext();
|
|
||||||
if (context == null) return;
|
if (context == null) return;
|
||||||
new AlertDialog.Builder(context)
|
new AlertDialog.Builder(context)
|
||||||
.setItems(options, profileDialogListener)
|
.setItems(options, profileDialogListener)
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
.show();
|
.show();
|
||||||
});
|
});
|
||||||
profileDetailsBinding.favCb.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
|
||||||
// do not do anything if state matches the db, as listener is set before profile details are set
|
|
||||||
final Context context = getContext();
|
|
||||||
if (context == null) return;
|
|
||||||
final String finalUsername = username.startsWith("@") ? username.substring(1) : username;
|
|
||||||
favoriteRepository.getFavorite(finalUsername, FavoriteType.USER, new RepositoryCallback<Favorite>() {
|
|
||||||
@Override
|
|
||||||
public void onSuccess(final Favorite result) {
|
|
||||||
if (isChecked) return; // already a fav
|
|
||||||
buttonView.setVisibility(View.GONE);
|
|
||||||
profileDetailsBinding.favProgress.setVisibility(View.VISIBLE);
|
|
||||||
favoriteRepository.deleteFavorite(finalUsername, FavoriteType.USER, new RepositoryCallback<Void>() {
|
|
||||||
@Override
|
|
||||||
public void onSuccess(final Void result) {
|
|
||||||
profileDetailsBinding.favCb.setButtonDrawable(R.drawable.ic_outline_star_plus_24);
|
|
||||||
profileDetailsBinding.favProgress.setVisibility(View.GONE);
|
|
||||||
profileDetailsBinding.favCb.setVisibility(View.VISIBLE);
|
|
||||||
showSnackbar(getString(R.string.removed_from_favs));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDataNotAvailable() {}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDataNotAvailable() {
|
|
||||||
if (!isChecked) return; // not in fav already
|
|
||||||
buttonView.setVisibility(View.GONE);
|
|
||||||
profileDetailsBinding.favProgress.setVisibility(View.VISIBLE);
|
|
||||||
final Favorite model = new Favorite(
|
|
||||||
-1,
|
|
||||||
finalUsername,
|
|
||||||
FavoriteType.USER,
|
|
||||||
profileModel.getName(),
|
|
||||||
profileModel.getSdProfilePic(),
|
|
||||||
new Date()
|
|
||||||
);
|
|
||||||
favoriteRepository.insertOrUpdateFavorite(model, new RepositoryCallback<Void>() {
|
|
||||||
@Override
|
|
||||||
public void onSuccess(final Void result) {
|
|
||||||
profileDetailsBinding.favCb.setButtonDrawable(R.drawable.ic_star_check_24);
|
|
||||||
profileDetailsBinding.favProgress.setVisibility(View.GONE);
|
|
||||||
profileDetailsBinding.favCb.setVisibility(View.VISIBLE);
|
|
||||||
showSnackbar(getString(R.string.added_to_favs));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDataNotAvailable() {}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showSnackbar(final String message) {
|
private void showSnackbar(final String message) {
|
||||||
|
@ -29,7 +29,7 @@ public final class HashtagModel implements Serializable {
|
|||||||
return sdProfilePic;
|
return sdProfilePic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getPostCount() { return postCount; }
|
public Long getPostCount() { return postCount; }
|
||||||
|
|
||||||
public boolean getFollowing() { return following; }
|
public boolean getFollowing() { return following; }
|
||||||
}
|
}
|
@ -59,5 +59,5 @@ public final class LocationModel implements Serializable {
|
|||||||
return sdProfilePic;
|
return sdProfilePic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getPostCount() { return postCount; }
|
public Long getPostCount() { return postCount; }
|
||||||
}
|
}
|
@ -3,15 +3,15 @@ package awais.instagrabber.models;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
public final class ProfileModel implements Serializable {
|
public final class ProfileModel implements Serializable {
|
||||||
private final boolean isPrivate, reallyPrivate, isVerified, following, restricted, blocked, requested;
|
private final boolean isPrivate, reallyPrivate, isVerified, following, follower, restricted, blocked, requested;
|
||||||
private final long postCount, followersCount, followingCount;
|
private final long postCount, followersCount, followingCount;
|
||||||
private final String id, username, name, biography, url, sdProfilePic, hdProfilePic;
|
private final String id, username, name, biography, url, sdProfilePic, hdProfilePic;
|
||||||
|
|
||||||
public ProfileModel(final boolean isPrivate, final boolean reallyPrivate,
|
public ProfileModel(final boolean isPrivate, final boolean reallyPrivate,
|
||||||
final boolean isVerified, final String id, final String username, final String name, final String biography,
|
final boolean isVerified, final String id, final String username, final String name, final String biography,
|
||||||
final String url, final String sdProfilePic, final String hdProfilePic, final long postCount,
|
final String url, final String sdProfilePic, final String hdProfilePic, final long postCount,
|
||||||
final long followersCount, final long followingCount, final boolean following, final boolean restricted,
|
final long followersCount, final long followingCount, final boolean following, final boolean follower,
|
||||||
final boolean blocked, final boolean requested) {
|
final boolean restricted, final boolean blocked, final boolean requested) {
|
||||||
this.isPrivate = isPrivate;
|
this.isPrivate = isPrivate;
|
||||||
this.reallyPrivate = reallyPrivate;
|
this.reallyPrivate = reallyPrivate;
|
||||||
this.isVerified = isVerified;
|
this.isVerified = isVerified;
|
||||||
@ -26,21 +26,22 @@ public final class ProfileModel implements Serializable {
|
|||||||
this.followersCount = followersCount;
|
this.followersCount = followersCount;
|
||||||
this.followingCount = followingCount;
|
this.followingCount = followingCount;
|
||||||
this.following = following;
|
this.following = following;
|
||||||
|
this.follower = follower;
|
||||||
this.restricted = restricted;
|
this.restricted = restricted;
|
||||||
this.blocked = blocked;
|
this.blocked = blocked;
|
||||||
this.requested = requested;
|
this.requested = requested;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ProfileModel getDefaultProfileModel() {
|
public static ProfileModel getDefaultProfileModel() {
|
||||||
return new ProfileModel(false, false, false, null, null, null, null, null, null, null, 0, 0, 0, false, false, false, false);
|
return new ProfileModel(false, false, false, null, null, null, null, null, null, null, 0, 0, 0, false, false, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ProfileModel getDefaultProfileModel(final String userId) {
|
public static ProfileModel getDefaultProfileModel(final String userId) {
|
||||||
return new ProfileModel(false, false, false, userId, null, null, null, null, null, null, 0, 0, 0, false, false, false, false);
|
return new ProfileModel(false, false, false, userId, null, null, null, null, null, null, 0, 0, 0, false, false, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ProfileModel getDefaultProfileModel(final String userId, final String username) {
|
public static ProfileModel getDefaultProfileModel(final String userId, final String username) {
|
||||||
return new ProfileModel(false, false, false, userId, username, null, null, null, null, null, 0, 0, 0, false, false, false, false);
|
return new ProfileModel(false, false, false, userId, username, null, null, null, null, null, 0, 0, 0, false, false, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPrivate() {
|
public boolean isPrivate() {
|
||||||
@ -83,31 +84,35 @@ public final class ProfileModel implements Serializable {
|
|||||||
return hdProfilePic;
|
return hdProfilePic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getPostCount() {
|
public Long getPostCount() {
|
||||||
return postCount;
|
return postCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getFollowersCount() {
|
public Long getFollowersCount() {
|
||||||
return followersCount;
|
return followersCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getFollowingCount() {
|
public Long getFollowingCount() {
|
||||||
return followingCount;
|
return followingCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getFollowing() {
|
public boolean isFollowing() {
|
||||||
return following;
|
return following;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getRestricted() {
|
public boolean isFollower() {
|
||||||
|
return follower;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRestricted() {
|
||||||
return restricted;
|
return restricted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getBlocked() {
|
public boolean isBlocked() {
|
||||||
return blocked;
|
return blocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getRequested() {
|
public boolean isRequested() {
|
||||||
return requested;
|
return requested;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,7 +20,4 @@ public interface ProfileRepository {
|
|||||||
|
|
||||||
@GET("/api/v1/feed/liked/")
|
@GET("/api/v1/feed/liked/")
|
||||||
Call<String> fetchLiked(@QueryMap Map<String, String> queryParams);
|
Call<String> fetchLiked(@QueryMap Map<String, String> queryParams);
|
||||||
|
|
||||||
@GET("/api/v1/usertags/{profileId}/feed/")
|
|
||||||
Call<String> fetchTagged(@Path("profileId") final String profileId, @QueryMap Map<String, String> queryParams);
|
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ public final class ResponseBodyUtils {
|
|||||||
userObj.getString("full_name"),
|
userObj.getString("full_name"),
|
||||||
null, null,
|
null, null,
|
||||||
userObj.getString("profile_pic_url"),
|
userObj.getString("profile_pic_url"),
|
||||||
null, 0, 0, 0, false, false, false, false);
|
null, 0, 0, 0, false, false, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
final MediaItemType mediaType = getMediaItemType(mediaObj.optInt("media_type", -1));
|
final MediaItemType mediaType = getMediaItemType(mediaObj.optInt("media_type", -1));
|
||||||
@ -291,7 +291,7 @@ public final class ResponseBodyUtils {
|
|||||||
userObject.getString("full_name"),
|
userObject.getString("full_name"),
|
||||||
null, null,
|
null, null,
|
||||||
userObject.getString("profile_pic_url"),
|
userObject.getString("profile_pic_url"),
|
||||||
null, 0, 0, 0, false, false, false, false);
|
null, 0, 0, 0, false, false, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ProfileModel[] leftuserModels = new ProfileModel[leftusersLen];
|
final ProfileModel[] leftuserModels = new ProfileModel[leftusersLen];
|
||||||
@ -305,7 +305,7 @@ public final class ResponseBodyUtils {
|
|||||||
userObject.getString("full_name"),
|
userObject.getString("full_name"),
|
||||||
null, null,
|
null, null,
|
||||||
userObject.getString("profile_pic_url"),
|
userObject.getString("profile_pic_url"),
|
||||||
null, 0, 0, 0, false, false, false, false);
|
null, 0, 0, 0, false, false, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Long[] adminIDs = new Long[adminsLen];
|
final Long[] adminIDs = new Long[adminsLen];
|
||||||
@ -470,7 +470,7 @@ public final class ResponseBodyUtils {
|
|||||||
profile.getString("full_name"),
|
profile.getString("full_name"),
|
||||||
null, null,
|
null, null,
|
||||||
profile.getString("profile_pic_url"),
|
profile.getString("profile_pic_url"),
|
||||||
null, 0, 0, 0, false, false, false, false);
|
null, 0, 0, 0, false, false, false, false, false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -622,6 +622,7 @@ public final class ResponseBodyUtils {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
following,
|
following,
|
||||||
|
false,
|
||||||
restricted,
|
restricted,
|
||||||
false,
|
false,
|
||||||
requested);
|
requested);
|
||||||
@ -705,6 +706,7 @@ public final class ResponseBodyUtils {
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
JSONObject tempJsonObject = feedItem.optJSONObject("edge_media_preview_comment");
|
JSONObject tempJsonObject = feedItem.optJSONObject("edge_media_preview_comment");
|
||||||
|
@ -165,6 +165,7 @@ public class DiscoverService extends BaseService {
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
final String resourceUrl = ResponseBodyUtils.getHighQualityImage(coverMediaJson);
|
final String resourceUrl = ResponseBodyUtils.getHighQualityImage(coverMediaJson);
|
||||||
|
@ -89,7 +89,6 @@ public class ProfileService extends BaseService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void fetchPosts(final ProfileModel profileModel,
|
public void fetchPosts(final ProfileModel profileModel,
|
||||||
final int postsPerPage,
|
final int postsPerPage,
|
||||||
final String cursor,
|
final String cursor,
|
||||||
@ -156,135 +155,18 @@ public class ProfileService extends BaseService {
|
|||||||
}
|
}
|
||||||
final JSONArray edges = mediaPosts.getJSONArray("edges");
|
final JSONArray edges = mediaPosts.getJSONArray("edges");
|
||||||
for (int i = 0; i < edges.length(); ++i) {
|
for (int i = 0; i < edges.length(); ++i) {
|
||||||
final JSONObject mediaNode = edges.getJSONObject(i).getJSONObject("node");
|
final JSONObject itemJson = edges.optJSONObject(i);
|
||||||
final String mediaType = mediaNode.optString("__typename");
|
if (itemJson == null) {
|
||||||
if (mediaType.isEmpty() || "GraphSuggestedUserFeedUnit".equals(mediaType))
|
|
||||||
continue;
|
continue;
|
||||||
final boolean isVideo = mediaNode.getBoolean("is_video");
|
|
||||||
final long videoViews = mediaNode.optLong("video_view_count", 0);
|
|
||||||
|
|
||||||
final String displayUrl = mediaNode.optString("display_url");
|
|
||||||
if (TextUtils.isEmpty(displayUrl)) continue;
|
|
||||||
final String resourceUrl;
|
|
||||||
|
|
||||||
if (isVideo) {
|
|
||||||
resourceUrl = mediaNode.getString("video_url");
|
|
||||||
} else {
|
|
||||||
resourceUrl = mediaNode.has("display_resources") ? ResponseBodyUtils.getHighQualityImage(mediaNode) : displayUrl;
|
|
||||||
}
|
}
|
||||||
JSONObject tempJsonObject = mediaNode.optJSONObject("edge_media_to_comment");
|
final FeedModel feedModel = ResponseBodyUtils.parseGraphQLItem(itemJson);
|
||||||
final long commentsCount = tempJsonObject != null ? tempJsonObject.optLong("count") : 0;
|
if (feedModel != null) {
|
||||||
tempJsonObject = mediaNode.optJSONObject("edge_media_preview_like");
|
|
||||||
final long likesCount = tempJsonObject != null ? tempJsonObject.optLong("count") : 0;
|
|
||||||
tempJsonObject = mediaNode.optJSONObject("edge_media_to_caption");
|
|
||||||
final JSONArray captions = tempJsonObject != null ? tempJsonObject.getJSONArray("edges") : null;
|
|
||||||
String captionText = null;
|
|
||||||
if (captions != null && captions.length() > 0) {
|
|
||||||
if ((tempJsonObject = captions.optJSONObject(0)) != null &&
|
|
||||||
(tempJsonObject = tempJsonObject.optJSONObject("node")) != null) {
|
|
||||||
captionText = tempJsonObject.getString("text");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
final JSONObject location = mediaNode.optJSONObject("location");
|
|
||||||
// Log.d(TAG, "location: " + (location == null ? null : location.toString()));
|
|
||||||
String locationId = null;
|
|
||||||
String locationName = null;
|
|
||||||
if (location != null) {
|
|
||||||
locationName = location.optString("name");
|
|
||||||
if (location.has("id")) {
|
|
||||||
locationId = location.getString("id");
|
|
||||||
} else if (location.has("pk")) {
|
|
||||||
locationId = location.getString("pk");
|
|
||||||
}
|
|
||||||
// Log.d(TAG, "locationId: " + locationId);
|
|
||||||
}
|
|
||||||
int height = 0;
|
|
||||||
int width = 0;
|
|
||||||
final JSONObject dimensions = mediaNode.optJSONObject("dimensions");
|
|
||||||
if (dimensions != null) {
|
|
||||||
height = dimensions.optInt("height");
|
|
||||||
width = dimensions.optInt("width");
|
|
||||||
}
|
|
||||||
String thumbnailUrl = null;
|
|
||||||
try {
|
|
||||||
thumbnailUrl = mediaNode.getJSONArray("display_resources")
|
|
||||||
.getJSONObject(0)
|
|
||||||
.getString("src");
|
|
||||||
} catch (JSONException ignored) {}
|
|
||||||
final FeedModel.Builder builder = new FeedModel.Builder()
|
|
||||||
.setProfileModel(profileModel)
|
|
||||||
.setItemType(isVideo ? MediaItemType.MEDIA_TYPE_VIDEO
|
|
||||||
: MediaItemType.MEDIA_TYPE_IMAGE)
|
|
||||||
.setViewCount(videoViews)
|
|
||||||
.setPostId(mediaNode.getString(Constants.EXTRAS_ID))
|
|
||||||
.setDisplayUrl(resourceUrl)
|
|
||||||
.setThumbnailUrl(thumbnailUrl != null ? thumbnailUrl : displayUrl)
|
|
||||||
.setShortCode(mediaNode.getString(Constants.EXTRAS_SHORTCODE))
|
|
||||||
.setPostCaption(captionText)
|
|
||||||
.setCommentsCount(commentsCount)
|
|
||||||
.setTimestamp(mediaNode.optLong("taken_at_timestamp", -1))
|
|
||||||
.setLiked(mediaNode.getBoolean("viewer_has_liked"))
|
|
||||||
.setBookmarked(mediaNode.getBoolean("viewer_has_saved"))
|
|
||||||
.setLikesCount(likesCount)
|
|
||||||
.setLocationName(locationName)
|
|
||||||
.setLocationId(locationId)
|
|
||||||
.setImageHeight(height)
|
|
||||||
.setImageWidth(width);
|
|
||||||
final boolean isSlider = "GraphSidecar".equals(mediaType) && mediaNode.has("edge_sidecar_to_children");
|
|
||||||
if (isSlider) {
|
|
||||||
builder.setItemType(MediaItemType.MEDIA_TYPE_SLIDER);
|
|
||||||
final JSONObject sidecar = mediaNode.optJSONObject("edge_sidecar_to_children");
|
|
||||||
if (sidecar != null) {
|
|
||||||
final JSONArray children = sidecar.optJSONArray("edges");
|
|
||||||
if (children != null) {
|
|
||||||
final List<PostChild> sliderItems = getSliderItems(children);
|
|
||||||
builder.setSliderItems(sliderItems);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
final FeedModel feedModel = builder.build();
|
|
||||||
feedModels.add(feedModel);
|
feedModels.add(feedModel);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return new PostsFetchResponse(feedModels, hasNextPage, endCursor);
|
return new PostsFetchResponse(feedModels, hasNextPage, endCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private List<PostChild> getSliderItems(final JSONArray children) throws JSONException {
|
|
||||||
final List<PostChild> sliderItems = new ArrayList<>();
|
|
||||||
for (int j = 0; j < children.length(); ++j) {
|
|
||||||
final JSONObject childNode = children.optJSONObject(j).getJSONObject("node");
|
|
||||||
final boolean isChildVideo = childNode.optBoolean("is_video");
|
|
||||||
int height = 0;
|
|
||||||
int width = 0;
|
|
||||||
final JSONObject dimensions = childNode.optJSONObject("dimensions");
|
|
||||||
if (dimensions != null) {
|
|
||||||
height = dimensions.optInt("height");
|
|
||||||
width = dimensions.optInt("width");
|
|
||||||
}
|
|
||||||
String thumbnailUrl = null;
|
|
||||||
try {
|
|
||||||
thumbnailUrl = childNode.getJSONArray("display_resources")
|
|
||||||
.getJSONObject(0)
|
|
||||||
.getString("src");
|
|
||||||
} catch (JSONException ignored) {}
|
|
||||||
final PostChild sliderItem = new PostChild.Builder()
|
|
||||||
.setItemType(isChildVideo ? MediaItemType.MEDIA_TYPE_VIDEO
|
|
||||||
: MediaItemType.MEDIA_TYPE_IMAGE)
|
|
||||||
.setPostId(childNode.getString(Constants.EXTRAS_ID))
|
|
||||||
.setDisplayUrl(isChildVideo ? childNode.getString("video_url")
|
|
||||||
: childNode.getString("display_url"))
|
|
||||||
.setThumbnailUrl(thumbnailUrl != null ? thumbnailUrl
|
|
||||||
: childNode.getString("display_url"))
|
|
||||||
.setVideoViews(childNode.optLong("video_view_count", 0))
|
|
||||||
.setHeight(height)
|
|
||||||
.setWidth(width)
|
|
||||||
.build();
|
|
||||||
// Log.d(TAG, "getSliderItems: sliderItem: " + sliderItem);
|
|
||||||
sliderItems.add(sliderItem);
|
|
||||||
}
|
|
||||||
return sliderItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fetchSaved(final String maxId,
|
public void fetchSaved(final String maxId,
|
||||||
final ServiceCallback<SavedPostsFetchResponse> callback) {
|
final ServiceCallback<SavedPostsFetchResponse> callback) {
|
||||||
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
||||||
@ -358,13 +240,17 @@ public class ProfileService extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void fetchTagged(final String profileId,
|
public void fetchTagged(final String profileId,
|
||||||
final String maxId,
|
final int postsPerPage,
|
||||||
|
final String cursor,
|
||||||
final ServiceCallback<SavedPostsFetchResponse> callback) {
|
final ServiceCallback<SavedPostsFetchResponse> callback) {
|
||||||
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
final Map<String, String> queryMap = new HashMap<>();
|
||||||
if (!TextUtils.isEmpty(maxId)) {
|
queryMap.put("query_hash", "31fe64d9463cbbe58319dced405c6206");
|
||||||
builder.put("max_id", maxId);
|
queryMap.put("variables", "{" +
|
||||||
}
|
"\"id\":\"" + profileId + "\"," +
|
||||||
final Call<String> request = repository.fetchTagged(profileId, builder.build());
|
"\"first\":" + postsPerPage + "," +
|
||||||
|
"\"after\":\"" + (cursor == null ? "" : cursor) + "\"" +
|
||||||
|
"}");
|
||||||
|
final Call<String> request = wwwRepository.fetch(queryMap);
|
||||||
request.enqueue(new Callback<String>() {
|
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<String> call, @NonNull final Response<String> response) {
|
||||||
@ -377,7 +263,7 @@ public class ProfileService extends BaseService {
|
|||||||
callback.onSuccess(null);
|
callback.onSuccess(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final SavedPostsFetchResponse savedPostsFetchResponse = parseSavedPostsResponse(body, false);
|
final SavedPostsFetchResponse savedPostsFetchResponse = parseTaggedPostsResponse(body);
|
||||||
callback.onSuccess(savedPostsFetchResponse);
|
callback.onSuccess(savedPostsFetchResponse);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e(TAG, "onResponse", e);
|
Log.e(TAG, "onResponse", e);
|
||||||
@ -411,6 +297,41 @@ public class ProfileService extends BaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private SavedPostsFetchResponse parseTaggedPostsResponse(@NonNull final String body)
|
||||||
|
throws JSONException {
|
||||||
|
final List<FeedModel> feedModels = new ArrayList<>();
|
||||||
|
final JSONObject timelineFeed = new JSONObject(body)
|
||||||
|
.getJSONObject("data")
|
||||||
|
.getJSONObject(Constants.EXTRAS_USER)
|
||||||
|
.getJSONObject("edge_user_to_photos_of_you");
|
||||||
|
final String endCursor;
|
||||||
|
final boolean hasNextPage;
|
||||||
|
|
||||||
|
final JSONObject pageInfo = timelineFeed.getJSONObject("page_info");
|
||||||
|
if (pageInfo.has("has_next_page")) {
|
||||||
|
hasNextPage = pageInfo.getBoolean("has_next_page");
|
||||||
|
endCursor = hasNextPage ? pageInfo.getString("end_cursor") : null;
|
||||||
|
} else {
|
||||||
|
hasNextPage = false;
|
||||||
|
endCursor = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final JSONArray feedItems = timelineFeed.getJSONArray("edges");
|
||||||
|
|
||||||
|
for (int i = 0; i < feedItems.length(); ++i) {
|
||||||
|
final JSONObject itemJson = feedItems.optJSONObject(i);
|
||||||
|
if (itemJson == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final FeedModel feedModel = ResponseBodyUtils.parseGraphQLItem(itemJson);
|
||||||
|
if (feedModel != null) {
|
||||||
|
feedModels.add(feedModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new SavedPostsFetchResponse(hasNextPage, endCursor, timelineFeed.getInt("count"), "ok", feedModels);
|
||||||
|
}
|
||||||
|
|
||||||
private List<FeedModel> parseItems(final JSONArray items, final boolean isInMedia) throws JSONException {
|
private List<FeedModel> parseItems(final JSONArray items, final boolean isInMedia) throws JSONException {
|
||||||
if (items == null) {
|
if (items == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
@ -123,7 +123,7 @@ public class StoriesService extends BaseService {
|
|||||||
user.getString("username"),
|
user.getString("username"),
|
||||||
null, null, null,
|
null, null, null,
|
||||||
user.getString("profile_pic_url"),
|
user.getString("profile_pic_url"),
|
||||||
null, 0, 0, 0, false, false, false, false);
|
null, 0, 0, 0, false, false, false, false, false);
|
||||||
final String id = node.getString("id");
|
final String id = node.getString("id");
|
||||||
final boolean fullyRead = !node.isNull("seen") && node.getLong("seen") == node.getLong("latest_reel_media");
|
final boolean fullyRead = !node.isNull("seen") && node.getLong("seen") == node.getLong("latest_reel_media");
|
||||||
feedStoryModels.add(new FeedStoryModel(id, profileModel, fullyRead));
|
feedStoryModels.add(new FeedStoryModel(id, profileModel, fullyRead));
|
||||||
|
@ -18,45 +18,96 @@
|
|||||||
app:layout_constraintEnd_toStartOf="@id/mainPostCount"
|
app:layout_constraintEnd_toStartOf="@id/mainPostCount"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/fav_chip"
|
||||||
tools:background="@mipmap/ic_launcher" />
|
tools:background="@mipmap/ic_launcher" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<com.google.android.material.chip.Chip
|
||||||
android:id="@+id/mainPostCount"
|
android:id="@+id/mainPostCount"
|
||||||
android:layout_width="0dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="0dp"
|
android:layout_height="@dimen/profile_chip_size"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:clickable="false"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat"
|
app:layout_constraintBottom_toTopOf="@id/mainFollowers"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/mainProfileImage"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/mainFollowers"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/mainProfileImage"
|
app:layout_constraintStart_toEndOf="@id/mainProfileImage"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="@id/mainProfileImage"
|
||||||
tools:text="35\nPosts" />
|
tools:text="35 Posts" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<com.google.android.material.chip.Chip
|
||||||
android:id="@+id/mainFollowers"
|
android:id="@+id/mainStatus"
|
||||||
android:layout_width="0dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="0dp"
|
android:layout_height="@dimen/profile_chip_size"
|
||||||
android:background="?selectableItemBackgroundBorderless"
|
android:layout_marginStart="4dp"
|
||||||
|
android:clickable="false"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat"
|
app:layout_constraintBottom_toTopOf="@id/mainFollowers"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/mainProfileImage"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/mainFollowing"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/mainPostCount"
|
app:layout_constraintStart_toEndOf="@id/mainPostCount"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="@id/mainPostCount"
|
||||||
tools:text="68\nFollowers" />
|
tools:text="omg what do u expect" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<com.google.android.material.chip.Chip
|
||||||
android:id="@+id/mainFollowing"
|
android:id="@+id/mainFollowers"
|
||||||
android:layout_width="0dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="0dp"
|
android:layout_height="@dimen/profile_chip_size"
|
||||||
android:background="?selectableItemBackgroundBorderless"
|
android:layout_marginStart="4dp"
|
||||||
|
android:clickable="false"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat"
|
app:layout_constraintBottom_toTopOf="@id/fav_chip"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/mainProfileImage"
|
app:layout_constraintStart_toEndOf="@id/mainProfileImage"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintTop_toBottomOf="@id/mainPostCount"
|
||||||
|
app:rippleColor="@color/grey_400"
|
||||||
|
tools:text="10 Followers" />
|
||||||
|
|
||||||
|
<com.google.android.material.chip.Chip
|
||||||
|
android:id="@+id/mainFollowing"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/profile_chip_size"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:clickable="false"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"
|
||||||
|
android:gravity="center"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/fav_chip"
|
||||||
app:layout_constraintStart_toEndOf="@id/mainFollowers"
|
app:layout_constraintStart_toEndOf="@id/mainFollowers"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toBottomOf="@id/mainPostCount"
|
||||||
tools:text="64\nFollowing" />
|
app:rippleColor="@color/grey_400"
|
||||||
|
tools:text="10 Following" />
|
||||||
|
|
||||||
|
<com.google.android.material.chip.Chip
|
||||||
|
android:id="@+id/fav_chip"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/profile_chip_size"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:text="@string/add_to_favorites"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:chipIcon="@drawable/ic_outline_star_plus_24"
|
||||||
|
app:chipIconTint="@color/yellow_800"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/mainProfileImage"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/mainProfileImage"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/mainFollowers"
|
||||||
|
app:rippleColor="@color/yellow_400"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<com.google.android.material.chip.Chip
|
||||||
|
android:id="@+id/btnTagged"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/profile_chip_size"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:text="@string/tagged"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:chipIcon="@drawable/ic_outline_person_pin_24"
|
||||||
|
app:chipIconTint="@color/deep_orange_800"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/fav_chip"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/fav_chip"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/mainFollowers"
|
||||||
|
app:rippleColor="@color/deep_orange_400"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
android:id="@+id/mainFullName"
|
android:id="@+id/mainFullName"
|
||||||
@ -70,7 +121,7 @@
|
|||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/mainProfileImage"
|
app:layout_constraintTop_toBottomOf="@id/fav_chip"
|
||||||
tools:text="Austin Huang" />
|
tools:text="Austin Huang" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
@ -84,7 +135,7 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/mainFullName"
|
app:layout_constraintBottom_toBottomOf="@id/mainFullName"
|
||||||
app:layout_constraintStart_toEndOf="@id/mainFullName"
|
app:layout_constraintStart_toEndOf="@id/mainFullName"
|
||||||
app:layout_constraintTop_toBottomOf="@id/mainProfileImage"
|
app:layout_constraintTop_toBottomOf="@id/fav_chip"
|
||||||
app:srcCompat="@drawable/verified"
|
app:srcCompat="@drawable/verified"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
@ -151,29 +202,12 @@
|
|||||||
app:iconGravity="top"
|
app:iconGravity="top"
|
||||||
app:iconTint="@color/deep_purple_200"
|
app:iconTint="@color/deep_purple_200"
|
||||||
app:layout_constraintBottom_toTopOf="@id/highlights_barrier"
|
app:layout_constraintBottom_toTopOf="@id/highlights_barrier"
|
||||||
app:layout_constraintEnd_toStartOf="@id/btnTagged"
|
app:layout_constraintEnd_toStartOf="@id/btnSaved"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/mainUrl"
|
app:layout_constraintTop_toBottomOf="@id/mainUrl"
|
||||||
app:rippleColor="@color/purple_200"
|
app:rippleColor="@color/purple_200"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnTagged"
|
|
||||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/tagged"
|
|
||||||
android:textColor="@color/deep_orange_600"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:icon="@drawable/ic_outline_person_pin_24"
|
|
||||||
app:iconGravity="top"
|
|
||||||
app:iconTint="@color/deep_orange_600"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/highlights_barrier"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/btnSaved"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/btnFollow"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/mainUrl"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/btnSaved"
|
android:id="@+id/btnSaved"
|
||||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||||
@ -187,7 +221,7 @@
|
|||||||
app:iconTint="@color/blue_700"
|
app:iconTint="@color/blue_700"
|
||||||
app:layout_constraintBottom_toTopOf="@id/highlights_barrier"
|
app:layout_constraintBottom_toTopOf="@id/highlights_barrier"
|
||||||
app:layout_constraintEnd_toStartOf="@id/btnLiked"
|
app:layout_constraintEnd_toStartOf="@id/btnLiked"
|
||||||
app:layout_constraintStart_toEndOf="@id/btnTagged"
|
app:layout_constraintStart_toEndOf="@id/btnFollow"
|
||||||
app:layout_constraintTop_toBottomOf="@id/mainUrl"
|
app:layout_constraintTop_toBottomOf="@id/mainUrl"
|
||||||
app:rippleColor="@color/blue_A400"
|
app:rippleColor="@color/blue_A400"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
<dimen name="private_page_margins">@dimen/profile_picture_size</dimen>
|
<dimen name="private_page_margins">@dimen/profile_picture_size</dimen>
|
||||||
|
|
||||||
<dimen name="profile_picture_size">90dp</dimen>
|
<dimen name="profile_picture_size">90dp</dimen>
|
||||||
|
<dimen name="profile_chip_size">40dp</dimen>
|
||||||
<dimen name="image_size_40">40dp</dimen>
|
<dimen name="image_size_40">40dp</dimen>
|
||||||
|
|
||||||
<dimen name="profile_pic_size_tiny">24dp</dimen>
|
<dimen name="profile_pic_size_tiny">24dp</dimen>
|
||||||
|
@ -45,10 +45,15 @@
|
|||||||
<string name="instadp_settings">Use Instadp for high definition profile pictures</string>
|
<string name="instadp_settings">Use Instadp for high definition profile pictures</string>
|
||||||
<string name="import_export">Import/Export</string>
|
<string name="import_export">Import/Export</string>
|
||||||
<string name="select_language">Language</string>
|
<string name="select_language">Language</string>
|
||||||
<string name="main_posts_count">%s\nPosts</string>
|
<plurals name="main_posts_count_inline">
|
||||||
<string name="main_posts_count_inline">%s Posts</string>
|
<item quantity="one">%s Post</item>
|
||||||
<string name="main_posts_followers">%s\nFollowers</string>
|
<item quantity="other">%s Posts</item>
|
||||||
<string name="main_posts_following">%s\nFollowing</string>
|
</plurals>
|
||||||
|
<plurals name="main_posts_followers">
|
||||||
|
<item quantity="one">%s Follower</item>
|
||||||
|
<item quantity="other">%s Followers</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="main_posts_following">%s Following </string>
|
||||||
<string name="post_viewer_autoplay_video">Autoplay videos</string>
|
<string name="post_viewer_autoplay_video">Autoplay videos</string>
|
||||||
<string name="post_viewer_muted_autoplay">Always mute videos</string>
|
<string name="post_viewer_muted_autoplay">Always mute videos</string>
|
||||||
<string name="post_viewer_download_dialog_title">Select what to download</string>
|
<string name="post_viewer_download_dialog_title">Select what to download</string>
|
||||||
@ -107,6 +112,9 @@
|
|||||||
<string name="unblock">Unblock</string>
|
<string name="unblock">Unblock</string>
|
||||||
<string name="restrict">Restrict</string>
|
<string name="restrict">Restrict</string>
|
||||||
<string name="unrestrict">Unrestrict</string>
|
<string name="unrestrict">Unrestrict</string>
|
||||||
|
<string name="status_mutual">Following each other</string>
|
||||||
|
<string name="status_following">Followed by you</string>
|
||||||
|
<string name="status_follower">Following you</string>
|
||||||
<string name="map">Map</string>
|
<string name="map">Map</string>
|
||||||
<string name="dialog_export_btn_export">Export</string>
|
<string name="dialog_export_btn_export">Export</string>
|
||||||
<string name="dialog_export_btn_import">Import</string>
|
<string name="dialog_export_btn_import">Import</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user