fix mentions (final), improve follower comparison

This commit is contained in:
Austin Huang 2020-12-21 14:27:15 -05:00
parent 484b0f9657
commit 7cd56080cd
No known key found for this signature in database
GPG Key ID: 84C23AA04587A91F
7 changed files with 125 additions and 85 deletions

View File

@ -87,7 +87,7 @@ dependencies {
annotationProcessor "androidx.room:room-compiler:$room_version" annotationProcessor "androidx.room:room-compiler:$room_version"
// implementation 'com.github.hendrawd:StorageUtil:1.1.0' // implementation 'com.github.hendrawd:StorageUtil:1.1.0'
implementation 'com.github.ammargitham:AutoLinkTextViewV2:master-SNAPSHOT' implementation 'me.austinhuang:AutoLinkTextViewV2:-SNAPSHOT'
implementation 'org.jsoup:jsoup:1.13.1' implementation 'org.jsoup:jsoup:1.13.1'
implementation 'com.facebook.fresco:fresco:2.3.0' implementation 'com.facebook.fresco:fresco:2.3.0'

View File

@ -23,7 +23,6 @@ public final class FollowsViewHolder extends RecyclerView.ViewHolder {
public void bind(final ProfileModel model, public void bind(final ProfileModel model,
final List<Long> admins, final List<Long> admins,
final View.OnClickListener onClickListener) { final View.OnClickListener onClickListener) {
Log.d("austin_debug", "bind "+model);
if (model == null) return; if (model == null) return;
itemView.setTag(model); itemView.setTag(model);
itemView.setOnClickListener(onClickListener); itemView.setOnClickListener(onClickListener);

View File

@ -20,29 +20,22 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.SearchView;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment; import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.R; import awais.instagrabber.R;
import awais.instagrabber.adapters.FollowAdapter; import awais.instagrabber.adapters.FollowAdapter;
import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
import awais.instagrabber.databinding.FragmentFollowersViewerBinding; import awais.instagrabber.databinding.FragmentFollowersViewerBinding;
import awais.instagrabber.models.FollowModel; import awais.instagrabber.models.FollowModel;
import awais.instagrabber.repositories.responses.FriendshipRepoChangeRootResponse;
import awais.instagrabber.repositories.responses.FriendshipRepoListFetchResponse; import awais.instagrabber.repositories.responses.FriendshipRepoListFetchResponse;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.CookieUtils;
import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.TextUtils;
import awais.instagrabber.webservices.FriendshipService; import awais.instagrabber.webservices.FriendshipService;
import awais.instagrabber.webservices.ServiceCallback; import awais.instagrabber.webservices.ServiceCallback;
import awaisomereport.LogCollector;
import thoughtbot.expandableadapter.ExpandableGroup; import thoughtbot.expandableadapter.ExpandableGroup;
import static awais.instagrabber.utils.Utils.logCollector;
import static awais.instagrabber.utils.Utils.settingsHelper;
public final class FollowViewerFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener { public final class FollowViewerFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private static final String TAG = "FollowViewerFragment"; private static final String TAG = "FollowViewerFragment";
@ -51,9 +44,11 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
private final ArrayList<FollowModel> followersModels = new ArrayList<>(); private final ArrayList<FollowModel> followersModels = new ArrayList<>();
private final ArrayList<FollowModel> allFollowing = new ArrayList<>(); private final ArrayList<FollowModel> allFollowing = new ArrayList<>();
private boolean isFollowersList, isCompare = false, loading = false; private boolean moreAvailable = true, isFollowersList, isCompare = false, loading = false, shouldRefresh = true;
private String profileId, username, namePost, type; private String profileId, username, namePost, type, endCursor;
private Resources resources; private Resources resources;
private LinearLayoutManager layoutManager;
private RecyclerLazyLoader lazyLoader;
private FollowModel model; private FollowModel model;
private FollowAdapter adapter; private FollowAdapter adapter;
private View.OnClickListener clickListener; private View.OnClickListener clickListener;
@ -61,9 +56,59 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
private AsyncTask<Void, Void, FollowModel[]> currentlyExecuting; private AsyncTask<Void, Void, FollowModel[]> currentlyExecuting;
private SwipeRefreshLayout root; private SwipeRefreshLayout root;
private FriendshipService friendshipService; private FriendshipService friendshipService;
private boolean shouldRefresh = true;
private AppCompatActivity fragmentActivity; private AppCompatActivity fragmentActivity;
final ServiceCallback<FriendshipRepoListFetchResponse> followingFetchCb = new ServiceCallback<FriendshipRepoListFetchResponse>() {
@Override
public void onSuccess(final FriendshipRepoListFetchResponse result) {
if (result != null) {
followingModels.addAll(result.getItems());
if (!isFollowersList) followModels.addAll(result.getItems());
if (result.isMoreAvailable()) {
endCursor = result.getNextMaxId();
friendshipService.getList(false, profileId, endCursor, this);
} else if (followersModels.size() == 0) {
if (!isFollowersList) moreAvailable = false;
friendshipService.getList(true, profileId, null, followingFetchCb);
} else {
if (!isFollowersList) moreAvailable = false;
showCompare();
}
} else binding.swipeRefreshLayout.setRefreshing(false);
}
@Override
public void onFailure(final Throwable t) {
binding.swipeRefreshLayout.setRefreshing(false);
Log.e(TAG, "Error fetching list (double, following)", t);
}
};
final ServiceCallback<FriendshipRepoListFetchResponse> followersFetchCb = new ServiceCallback<FriendshipRepoListFetchResponse>() {
@Override
public void onSuccess(final FriendshipRepoListFetchResponse result) {
if (result != null) {
followersModels.addAll(result.getItems());
if (isFollowersList) followModels.addAll(result.getItems());
if (result.isMoreAvailable()) {
endCursor = result.getNextMaxId();
friendshipService.getList(true, profileId, endCursor, this);
} else if (followingModels.size() == 0) {
if (isFollowersList) moreAvailable = false;
friendshipService.getList(false, profileId, null, followingFetchCb);
} else {
if (isFollowersList) moreAvailable = false;
showCompare();
}
}
}
@Override
public void onFailure(final Throwable t) {
binding.swipeRefreshLayout.setRefreshing(false);
Log.e(TAG, "Error fetching list (double, follower)", t);
}
};
@Override @Override
public void onCreate(@Nullable final Bundle savedInstanceState) { public void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -141,13 +186,13 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
public void onRefresh() { public void onRefresh() {
if (isCompare) listCompare(); if (isCompare) listCompare();
else listFollows(); else listFollows();
endCursor = null;
lazyLoader.resetState();
} }
private void listFollows() { private void listFollows() {
loading = true;
type = resources.getString(isFollowersList ? R.string.followers_type_followers : R.string.followers_type_following); type = resources.getString(isFollowersList ? R.string.followers_type_followers : R.string.followers_type_following);
setSubtitle(type); setSubtitle(type);
followModels.clear();
final ServiceCallback<FriendshipRepoListFetchResponse> cb = new ServiceCallback<FriendshipRepoListFetchResponse>() { final ServiceCallback<FriendshipRepoListFetchResponse> cb = new ServiceCallback<FriendshipRepoListFetchResponse>() {
@Override @Override
public void onSuccess(final FriendshipRepoListFetchResponse result) { public void onSuccess(final FriendshipRepoListFetchResponse result) {
@ -156,16 +201,18 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
return; return;
} }
else { else {
int oldSize = followModels.size() == 0 ? 0 : followModels.size() - 1;
followModels.addAll(result.getItems()); followModels.addAll(result.getItems());
if (result.isMoreAvailable()) { if (result.isMoreAvailable()) {
friendshipService.getList(isFollowersList, profileId, result.getNextMaxId(), this); moreAvailable = true;
} endCursor = result.getNextMaxId();
else {
binding.swipeRefreshLayout.setRefreshing(false);
if (isFollowersList) followersModels.addAll(followModels);
else followingModels.addAll(followModels);
refreshAdapter(followModels, null, null, null);
} }
else moreAvailable = false;
binding.swipeRefreshLayout.setRefreshing(false);
if (isFollowersList) followersModels.addAll(result.getItems());
else followingModels.addAll(result.getItems());
refreshAdapter(followModels, null, null, null);
layoutManager.scrollToPosition(oldSize);
} }
} }
@ -175,64 +222,43 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
Log.e(TAG, "Error fetching list (single)", t); Log.e(TAG, "Error fetching list (single)", t);
} }
}; };
binding.swipeRefreshLayout.setRefreshing(true); layoutManager = new LinearLayoutManager(getContext());
friendshipService.getList(isFollowersList, profileId, null, cb); lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
if (!TextUtils.isEmpty(endCursor)) {
binding.swipeRefreshLayout.setRefreshing(true);
friendshipService.getList(isFollowersList, profileId, endCursor, cb);
}
endCursor = null;
});
binding.rvFollow.addOnScrollListener(lazyLoader);
binding.rvFollow.setLayoutManager(layoutManager);
layoutManager.setStackFromEnd(true);
if (moreAvailable) {
binding.swipeRefreshLayout.setRefreshing(true);
friendshipService.getList(isFollowersList, profileId, endCursor, cb);
}
else {
refreshAdapter(followModels, null, null, null);
layoutManager.scrollToPosition(0);
}
} }
private void listCompare() { private void listCompare() {
layoutManager.setStackFromEnd(false);
binding.rvFollow.clearOnScrollListeners();
loading = true; loading = true;
setSubtitle(R.string.followers_compare); setSubtitle(R.string.followers_compare);
allFollowing.clear(); allFollowing.clear();
followersModels.clear();
followingModels.clear();
final ServiceCallback<FriendshipRepoListFetchResponse> followingFetchCb = new ServiceCallback<FriendshipRepoListFetchResponse>() {
@Override
public void onSuccess(final FriendshipRepoListFetchResponse result) {
if (result != null) {
followingModels.addAll(result.getItems());
if (result.isMoreAvailable()) {
friendshipService.getList(false, profileId, result.getNextMaxId(), this);
} else {
showCompare();
}
} else binding.swipeRefreshLayout.setRefreshing(false);
}
@Override
public void onFailure(final Throwable t) {
binding.swipeRefreshLayout.setRefreshing(false);
Log.e(TAG, "Error fetching list (double, following)", t);
}
};
final ServiceCallback<FriendshipRepoListFetchResponse> followersFetchCb = new ServiceCallback<FriendshipRepoListFetchResponse>() {
@Override
public void onSuccess(final FriendshipRepoListFetchResponse result) {
if (result != null) {
followersModels.addAll(result.getItems());
if (result.isMoreAvailable()) {
friendshipService.getList(true, profileId, result.getNextMaxId(), this);
} else if (followingModels.size() == 0) {
friendshipService.getList(false, profileId, null, followingFetchCb);
} else {
showCompare();
}
}
}
@Override
public void onFailure(final Throwable t) {
binding.swipeRefreshLayout.setRefreshing(false);
Log.e(TAG, "Error fetching list (double, follower)", t);
}
};
binding.swipeRefreshLayout.setRefreshing(true); binding.swipeRefreshLayout.setRefreshing(true);
if (followersModels.size() == 0) { if (moreAvailable) friendshipService.getList(isFollowersList,
friendshipService.getList(true, profileId, null, followersFetchCb); profileId,
} endCursor,
else if (followingModels.size() == 0) { isFollowersList ? followersFetchCb : followingFetchCb);
friendshipService.getList(false, profileId, null, followingFetchCb); else if (followersModels.size() == 0 || followingModels.size() == 0)
} friendshipService.getList(!isFollowersList,
profileId,
null,
isFollowersList ? followingFetchCb : followersFetchCb);
else showCompare(); else showCompare();
} }
@ -346,12 +372,12 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
final Context context = getContext(); final Context context = getContext();
if (loading) Toast.makeText(context, R.string.follower_wait_to_load, Toast.LENGTH_LONG).show(); if (loading) Toast.makeText(context, R.string.follower_wait_to_load, Toast.LENGTH_LONG).show();
else if (isCompare) { else if (isCompare) {
listFollows();
isCompare = !isCompare; isCompare = !isCompare;
listFollows();
} }
else { else {
listCompare();
isCompare = !isCompare; isCompare = !isCompare;
listCompare();
} }
return true; return true;
} }
@ -371,8 +397,7 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
if (allFollowing != null && allFollowing.size() > 0) if (allFollowing != null && allFollowing.size() > 0)
groups.add(new ExpandableGroup(resources.getString(R.string.followers_both_following), allFollowing)); groups.add(new ExpandableGroup(resources.getString(R.string.followers_both_following), allFollowing));
} else { } else {
final ExpandableGroup group = new ExpandableGroup(type, followModels); groups.add(new ExpandableGroup(type, followModels));
groups.add(group);
} }
adapter = new FollowAdapter(clickListener, groups); adapter = new FollowAdapter(clickListener, groups);
adapter.toggleGroup(0); adapter.toggleGroup(0);

View File

@ -580,7 +580,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
profileDetailsBinding.favChip.setText(R.string.added_to_favs); profileDetailsBinding.favChip.setText(R.string.added_to_favs);
favoriteRepository.insertOrUpdateFavorite(new Favorite( favoriteRepository.insertOrUpdateFavorite(new Favorite(
result.getId(), result.getId(),
finalUsername, profileModel.getUsername(),
FavoriteType.USER, FavoriteType.USER,
profileModel.getName(), profileModel.getName(),
profileModel.getSdProfilePic(), profileModel.getSdProfilePic(),
@ -619,10 +619,9 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
@Override @Override
public void onDataNotAvailable() { public void onDataNotAvailable() {
final String finalUsername = username.startsWith("@") ? username.substring(1) : username;
favoriteRepository.insertOrUpdateFavorite(new Favorite( favoriteRepository.insertOrUpdateFavorite(new Favorite(
-1, -1,
finalUsername, profileModel.getUsername(),
FavoriteType.USER, FavoriteType.USER,
profileModel.getName(), profileModel.getName(),
profileModel.getSdProfilePic(), profileModel.getSdProfilePic(),

View File

@ -0,0 +1,19 @@
package awais.instagrabber.viewmodels;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import java.util.List;
import awais.instagrabber.models.FollowModel;
public class FollowViewModel extends ViewModel {
private MutableLiveData<List<FollowModel>> list;
public MutableLiveData<List<FollowModel>> getList() {
if (list == null) {
list = new MutableLiveData<>();
}
return list;
}
}

View File

@ -153,13 +153,12 @@ public class FriendshipService extends BaseService {
}); });
} }
// log in required
public void getList(final boolean follower, public void getList(final boolean follower,
final String targetUserId, final String targetUserId,
final String maxId, final String maxId,
final ServiceCallback<FriendshipRepoListFetchResponse> callback) { final ServiceCallback<FriendshipRepoListFetchResponse> callback) {
final Map<String, String> queryMap = new HashMap<>(); final Map<String, String> queryMap = new HashMap<>();
queryMap.put("max_id", maxId == null ? "" : maxId); if (maxId != null) queryMap.put("max_id", maxId);
final Call<String> request = repository.getList(Constants.I_USER_AGENT, final Call<String> request = repository.getList(Constants.I_USER_AGENT,
targetUserId, targetUserId,
follower ? "followers" : "following", follower ? "followers" : "following",
@ -173,7 +172,6 @@ public class FriendshipService extends BaseService {
} }
final String body = response.body(); final String body = response.body();
if (TextUtils.isEmpty(body)) { if (TextUtils.isEmpty(body)) {
callback.onSuccess(null); callback.onSuccess(null);
return; return;
} }

View File

@ -274,7 +274,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:barrierDirection="bottom" app:barrierDirection="bottom"
app:constraint_referenced_ids="btnTagged, btnSaved, btnLiked, btnFollow, btnDM" /> app:constraint_referenced_ids="btnSaved, btnLiked, btnFollow, btnDM" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/highlightsList" android:id="@+id/highlightsList"