10 changed files with 460 additions and 400 deletions
-
14app/src/main/AndroidManifest.xml
-
23app/src/main/java/awais/instagrabber/MainHelper.java
-
333app/src/main/java/awais/instagrabber/activities/FollowViewer.java
-
371app/src/main/java/awais/instagrabber/activities/FollowViewerFragment.java
-
3app/src/main/java/awais/instagrabber/activities/MainActivity.java
-
17app/src/main/java/awais/instagrabber/activities/ProfileViewer.java
-
17app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
-
31app/src/main/res/layout/activity_follow.xml
-
21app/src/main/res/layout/fragment_followers_viewer.xml
-
30app/src/main/res/navigation/profile_nav_graph.xml
@ -1,333 +0,0 @@ |
|||||
package awais.instagrabber.activities; |
|
||||
|
|
||||
import android.content.Intent; |
|
||||
import android.content.res.Resources; |
|
||||
import android.os.AsyncTask; |
|
||||
import android.os.Bundle; |
|
||||
import android.util.Log; |
|
||||
import android.view.Menu; |
|
||||
import android.view.MenuItem; |
|
||||
import android.view.View; |
|
||||
|
|
||||
import androidx.annotation.Nullable; |
|
||||
import androidx.appcompat.widget.SearchView; |
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; |
|
||||
|
|
||||
import java.util.ArrayList; |
|
||||
import java.util.Arrays; |
|
||||
|
|
||||
import awais.instagrabber.BuildConfig; |
|
||||
import awais.instagrabber.R; |
|
||||
import awais.instagrabber.adapters.FollowAdapter; |
|
||||
import awais.instagrabber.asyncs.FollowFetcher; |
|
||||
import awais.instagrabber.databinding.ActivityFollowBinding; |
|
||||
import awais.instagrabber.interfaces.FetchListener; |
|
||||
import awais.instagrabber.models.FollowModel; |
|
||||
import awais.instagrabber.utils.Constants; |
|
||||
import awais.instagrabber.utils.Utils; |
|
||||
import awaisomereport.LogCollector; |
|
||||
import thoughtbot.expandableadapter.ExpandableGroup; |
|
||||
|
|
||||
import static awais.instagrabber.utils.Utils.logCollector; |
|
||||
|
|
||||
public final class FollowViewer extends BaseLanguageActivity implements SwipeRefreshLayout.OnRefreshListener { |
|
||||
private final ArrayList<FollowModel> followModels = new ArrayList<>(); |
|
||||
private final ArrayList<FollowModel> followingModels = new ArrayList<>(); |
|
||||
private final ArrayList<FollowModel> followersModels = new ArrayList<>(); |
|
||||
private final ArrayList<FollowModel> allFollowing = new ArrayList<>(); |
|
||||
private boolean followers, isCompare = false; |
|
||||
private String id, name, namePost, type; |
|
||||
private Resources resources; |
|
||||
private FollowModel model; |
|
||||
private FollowAdapter adapter; |
|
||||
private View.OnClickListener clickListener; |
|
||||
private ActivityFollowBinding followBinding; |
|
||||
private AsyncTask<Void, Void, FollowModel[]> currentlyExecuting; |
|
||||
|
|
||||
@Override |
|
||||
protected void onCreate(@Nullable final Bundle savedInstanceState) { |
|
||||
super.onCreate(savedInstanceState); |
|
||||
followBinding = ActivityFollowBinding.inflate(getLayoutInflater()); |
|
||||
setContentView(followBinding.getRoot()); |
|
||||
|
|
||||
final Intent intent = getIntent(); |
|
||||
if (intent == null || Utils.isEmpty(id = intent.getStringExtra(Constants.EXTRAS_ID))) { |
|
||||
Utils.errorFinish(this); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
setSupportActionBar(followBinding.toolbar.toolbar); |
|
||||
|
|
||||
followers = intent.getBooleanExtra(Constants.EXTRAS_FOLLOWERS, false); |
|
||||
name = intent.getStringExtra(Constants.EXTRAS_NAME); |
|
||||
namePost = name; |
|
||||
if (Utils.isEmpty(name)) { |
|
||||
// this usually should not occur |
|
||||
name = "You"; |
|
||||
namePost = "You're"; |
|
||||
} |
|
||||
|
|
||||
followBinding.toolbar.toolbar.setTitle(name); |
|
||||
|
|
||||
resources = getResources(); |
|
||||
|
|
||||
clickListener = v -> { |
|
||||
final Object tag = v.getTag(); |
|
||||
if (tag instanceof FollowModel) { |
|
||||
model = (FollowModel) tag; |
|
||||
startActivity( |
|
||||
new Intent(getApplicationContext(), ProfileViewer.class) |
|
||||
.putExtra(Constants.EXTRAS_USERNAME, model.getUsername()) |
|
||||
); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
followBinding.swipeRefreshLayout.setOnRefreshListener(this); |
|
||||
|
|
||||
onRefresh(); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void onRefresh() { |
|
||||
if (isCompare) listCompare(); |
|
||||
else listFollows(); |
|
||||
} |
|
||||
|
|
||||
private void listFollows() { |
|
||||
stopCurrentExecutor(); |
|
||||
|
|
||||
type = resources.getString(followers ? R.string.followers_type_followers : R.string.followers_type_following); |
|
||||
followBinding.toolbar.toolbar.setSubtitle(type); |
|
||||
|
|
||||
followModels.clear(); |
|
||||
|
|
||||
final FetchListener<FollowModel[]> fetchListener = new FetchListener<FollowModel[]>() { |
|
||||
@Override |
|
||||
public void doBefore() { |
|
||||
followBinding.swipeRefreshLayout.setRefreshing(true); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void onResult(final FollowModel[] result) { |
|
||||
if (result == null) followBinding.swipeRefreshLayout.setRefreshing(false); |
|
||||
else { |
|
||||
followModels.addAll(Arrays.asList(result)); |
|
||||
|
|
||||
final FollowModel model = result[result.length - 1]; |
|
||||
if (model != null && model.hasNextPage()) { |
|
||||
stopCurrentExecutor(); |
|
||||
currentlyExecuting = new FollowFetcher(id, followers, model.getEndCursor(), this) |
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
|
||||
model.setPageCursor(false, null); |
|
||||
} else { |
|
||||
followBinding.swipeRefreshLayout.setRefreshing(false); |
|
||||
|
|
||||
refreshAdapter(followModels, null, null, null); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
currentlyExecuting = new FollowFetcher(id, followers, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
|
||||
} |
|
||||
|
|
||||
private void listCompare() { |
|
||||
stopCurrentExecutor(); |
|
||||
|
|
||||
followBinding.toolbar.toolbar.setSubtitle(R.string.followers_compare); |
|
||||
|
|
||||
allFollowing.clear(); |
|
||||
followersModels.clear(); |
|
||||
followingModels.clear(); |
|
||||
|
|
||||
final FetchListener<FollowModel[]> followingFetchListener = new FetchListener<FollowModel[]>() { |
|
||||
@Override |
|
||||
public void onResult(final FollowModel[] result) { |
|
||||
if (result != null) { |
|
||||
followingModels.addAll(Arrays.asList(result)); |
|
||||
|
|
||||
final FollowModel model = result[result.length - 1]; |
|
||||
if (model != null && model.hasNextPage()) { |
|
||||
stopCurrentExecutor(); |
|
||||
currentlyExecuting = new FollowFetcher(id, false, model.getEndCursor(), this) |
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
|
||||
model.setPageCursor(false, null); |
|
||||
} else { |
|
||||
allFollowing.addAll(followersModels); |
|
||||
allFollowing.retainAll(followingModels); |
|
||||
|
|
||||
for (final FollowModel followModel : allFollowing) { |
|
||||
followersModels.remove(followModel); |
|
||||
followingModels.remove(followModel); |
|
||||
} |
|
||||
|
|
||||
allFollowing.trimToSize(); |
|
||||
followersModels.trimToSize(); |
|
||||
followingModels.trimToSize(); |
|
||||
|
|
||||
followBinding.swipeRefreshLayout.setRefreshing(false); |
|
||||
|
|
||||
refreshAdapter(null, followingModels, followersModels, allFollowing); |
|
||||
} |
|
||||
} else followBinding.swipeRefreshLayout.setRefreshing(false); |
|
||||
} |
|
||||
}; |
|
||||
final FetchListener<FollowModel[]> followersFetchListener = new FetchListener<FollowModel[]>() { |
|
||||
@Override |
|
||||
public void doBefore() { |
|
||||
followBinding.swipeRefreshLayout.setRefreshing(true); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void onResult(final FollowModel[] result) { |
|
||||
if (result != null) { |
|
||||
followersModels.addAll(Arrays.asList(result)); |
|
||||
final FollowModel model = result[result.length - 1]; |
|
||||
if (model == null || !model.hasNextPage()) { |
|
||||
stopCurrentExecutor(); |
|
||||
currentlyExecuting = new FollowFetcher(id, false, followingFetchListener) |
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
|
||||
} else { |
|
||||
stopCurrentExecutor(); |
|
||||
currentlyExecuting = new FollowFetcher(id, true, model.getEndCursor(), this) |
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
|
||||
model.setPageCursor(false, null); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
currentlyExecuting = new FollowFetcher(id, true, followersFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public boolean onCreateOptionsMenu(final Menu menu) { |
|
||||
getMenuInflater().inflate(R.menu.follow, menu); |
|
||||
|
|
||||
final MenuItem menuSearch = menu.findItem(R.id.action_search); |
|
||||
|
|
||||
final SearchView searchView = (SearchView) menuSearch.getActionView(); |
|
||||
searchView.setQueryHint(getResources().getString(R.string.action_search)); |
|
||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { |
|
||||
// private final Filter filter = new Filter() { |
|
||||
// private final ArrayList<FollowModel> searchFollowModels = new ArrayList<>(followModels.size() / 2); |
|
||||
// private final ArrayList<FollowModel> searchFollowingModels = new ArrayList<>(followingModels.size() / 2); |
|
||||
// private final ArrayList<FollowModel> searchFollowersModels = new ArrayList<>(followersModels.size() / 2); |
|
||||
// private final ArrayList<FollowModel> searchAllFollowing = new ArrayList<>(allFollowing.size() / 2); |
|
||||
// |
|
||||
// @Nullable |
|
||||
// @Override |
|
||||
// protected FilterResults performFiltering(@NonNull final CharSequence constraint) { |
|
||||
// searchFollowModels.clear(); |
|
||||
// searchFollowingModels.clear(); |
|
||||
// searchFollowersModels.clear(); |
|
||||
// searchAllFollowing.clear(); |
|
||||
// |
|
||||
// final int followModelsSize = followModels.size(); |
|
||||
// final int followingModelsSize = followingModels.size(); |
|
||||
// final int followersModelsSize = followersModels.size(); |
|
||||
// final int allFollowingSize = allFollowing.size(); |
|
||||
// |
|
||||
// int maxSize = followModelsSize; |
|
||||
// if (maxSize < followingModelsSize) maxSize = followingModelsSize; |
|
||||
// if (maxSize < followersModelsSize) maxSize = followersModelsSize; |
|
||||
// if (maxSize < allFollowingSize) maxSize = allFollowingSize; |
|
||||
// |
|
||||
// final String query = constraint.toString().toLowerCase(); |
|
||||
// FollowModel followModel; |
|
||||
// while (maxSize != -1) { |
|
||||
// if (maxSize < followModelsSize) { |
|
||||
// followModel = followModels.get(maxSize); |
|
||||
// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName())) |
|
||||
// searchFollowModels.add(followModel); |
|
||||
// } |
|
||||
// |
|
||||
// if (maxSize < followingModelsSize) { |
|
||||
// followModel = followingModels.get(maxSize); |
|
||||
// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName())) |
|
||||
// searchFollowingModels.add(followModel); |
|
||||
// } |
|
||||
// |
|
||||
// if (maxSize < followersModelsSize) { |
|
||||
// followModel = followersModels.get(maxSize); |
|
||||
// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName())) |
|
||||
// searchFollowersModels.add(followModel); |
|
||||
// } |
|
||||
// |
|
||||
// if (maxSize < allFollowingSize) { |
|
||||
// followModel = allFollowing.get(maxSize); |
|
||||
// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName())) |
|
||||
// searchAllFollowing.add(followModel); |
|
||||
// } |
|
||||
// |
|
||||
// --maxSize; |
|
||||
// } |
|
||||
// |
|
||||
// return null; |
|
||||
// } |
|
||||
// |
|
||||
// @Override |
|
||||
// protected void publishResults(final CharSequence query, final FilterResults results) { |
|
||||
// refreshAdapter(searchFollowModels, searchFollowingModels, searchFollowersModels, searchAllFollowing); |
|
||||
// } |
|
||||
// }; |
|
||||
|
|
||||
@Override |
|
||||
public boolean onQueryTextSubmit(final String query) { |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public boolean onQueryTextChange(final String query) { |
|
||||
// if (Utils.isEmpty(query)) refreshAdapter(followModels, followingModels, followersModels, allFollowing); |
|
||||
// else filter.filter(query.toLowerCase()); |
|
||||
if (adapter != null) adapter.getFilter().filter(query); |
|
||||
return true; |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
final MenuItem menuCompare = menu.findItem(R.id.action_compare); |
|
||||
menuCompare.setOnMenuItemClickListener(item -> { |
|
||||
followBinding.rvFollow.setAdapter(null); |
|
||||
if (isCompare) listFollows(); |
|
||||
else listCompare(); |
|
||||
isCompare = !isCompare; |
|
||||
return true; |
|
||||
}); |
|
||||
|
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
private void refreshAdapter(final ArrayList<FollowModel> followModels, final ArrayList<FollowModel> followingModels, |
|
||||
final ArrayList<FollowModel> followersModels, final ArrayList<FollowModel> allFollowing) { |
|
||||
final ArrayList<ExpandableGroup> groups = new ArrayList<>(1); |
|
||||
|
|
||||
if (isCompare) { |
|
||||
if (followingModels != null && followingModels.size() > 0) |
|
||||
groups.add(new ExpandableGroup(resources.getString(R.string.followers_not_following, name), followingModels)); |
|
||||
if (followersModels != null && followersModels.size() > 0) |
|
||||
groups.add(new ExpandableGroup(resources.getString(R.string.followers_not_follower, namePost), followersModels)); |
|
||||
if (allFollowing != null && allFollowing.size() > 0) |
|
||||
groups.add(new ExpandableGroup(resources.getString(R.string.followers_both_following), allFollowing)); |
|
||||
} else { |
|
||||
final ExpandableGroup group = new ExpandableGroup(type, followModels); |
|
||||
groups.add(group); |
|
||||
} |
|
||||
|
|
||||
adapter = new FollowAdapter(this, clickListener, groups); |
|
||||
adapter.toggleGroup(0); |
|
||||
followBinding.rvFollow.setAdapter(adapter); |
|
||||
} |
|
||||
|
|
||||
public void stopCurrentExecutor() { |
|
||||
if (currentlyExecuting != null) { |
|
||||
try { |
|
||||
currentlyExecuting.cancel(true); |
|
||||
} catch (final Exception e) { |
|
||||
if (logCollector != null) |
|
||||
logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor"); |
|
||||
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -0,0 +1,371 @@ |
|||||
|
package awais.instagrabber.activities; |
||||
|
|
||||
|
import android.content.res.Resources; |
||||
|
import android.os.AsyncTask; |
||||
|
import android.os.Bundle; |
||||
|
import android.util.Log; |
||||
|
import android.view.LayoutInflater; |
||||
|
import android.view.Menu; |
||||
|
import android.view.MenuInflater; |
||||
|
import android.view.MenuItem; |
||||
|
import android.view.View; |
||||
|
import android.view.ViewGroup; |
||||
|
|
||||
|
import androidx.annotation.NonNull; |
||||
|
import androidx.annotation.Nullable; |
||||
|
import androidx.appcompat.app.ActionBar; |
||||
|
import androidx.appcompat.app.AppCompatActivity; |
||||
|
import androidx.appcompat.widget.SearchView; |
||||
|
import androidx.fragment.app.Fragment; |
||||
|
import androidx.navigation.fragment.NavHostFragment; |
||||
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.Arrays; |
||||
|
|
||||
|
import awais.instagrabber.BuildConfig; |
||||
|
import awais.instagrabber.R; |
||||
|
import awais.instagrabber.adapters.FollowAdapter; |
||||
|
import awais.instagrabber.asyncs.FollowFetcher; |
||||
|
import awais.instagrabber.databinding.FragmentFollowersViewerBinding; |
||||
|
import awais.instagrabber.interfaces.FetchListener; |
||||
|
import awais.instagrabber.models.FollowModel; |
||||
|
import awais.instagrabber.utils.Utils; |
||||
|
import awaisomereport.LogCollector; |
||||
|
import thoughtbot.expandableadapter.ExpandableGroup; |
||||
|
|
||||
|
import static awais.instagrabber.utils.Utils.logCollector; |
||||
|
|
||||
|
public final class FollowViewerFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener { |
||||
|
private static final String TAG = "FollowViewerFragment"; |
||||
|
|
||||
|
private final ArrayList<FollowModel> followModels = new ArrayList<>(); |
||||
|
private final ArrayList<FollowModel> followingModels = new ArrayList<>(); |
||||
|
private final ArrayList<FollowModel> followersModels = new ArrayList<>(); |
||||
|
private final ArrayList<FollowModel> allFollowing = new ArrayList<>(); |
||||
|
|
||||
|
private boolean isFollowersList, isCompare = false; |
||||
|
private String profileId, username, namePost, type; |
||||
|
private Resources resources; |
||||
|
private FollowModel model; |
||||
|
private FollowAdapter adapter; |
||||
|
private View.OnClickListener clickListener; |
||||
|
private FragmentFollowersViewerBinding binding; |
||||
|
private AsyncTask<Void, Void, FollowModel[]> currentlyExecuting; |
||||
|
private SwipeRefreshLayout root; |
||||
|
private boolean shouldRefresh = true; |
||||
|
private AppCompatActivity fragmentActivity; |
||||
|
|
||||
|
@Override |
||||
|
public void onCreate(@Nullable final Bundle savedInstanceState) { |
||||
|
super.onCreate(savedInstanceState); |
||||
|
fragmentActivity = (AppCompatActivity) getActivity(); |
||||
|
setHasOptionsMenu(true); |
||||
|
} |
||||
|
|
||||
|
@NonNull |
||||
|
@Override |
||||
|
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) { |
||||
|
if (root != null) { |
||||
|
shouldRefresh = false; |
||||
|
return root; |
||||
|
} |
||||
|
binding = FragmentFollowersViewerBinding.inflate(getLayoutInflater()); |
||||
|
root = binding.getRoot(); |
||||
|
return root; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { |
||||
|
if (!shouldRefresh) return; |
||||
|
init(); |
||||
|
shouldRefresh = false; |
||||
|
} |
||||
|
|
||||
|
private void init() { |
||||
|
if (getArguments() == null) return; |
||||
|
final FollowViewerFragmentArgs fragmentArgs = FollowViewerFragmentArgs.fromBundle(getArguments()); |
||||
|
profileId = fragmentArgs.getProfileId(); |
||||
|
isFollowersList = fragmentArgs.getIsFollowersList(); |
||||
|
username = fragmentArgs.getUsername(); |
||||
|
namePost = username; |
||||
|
if (Utils.isEmpty(username)) { |
||||
|
// this usually should not occur |
||||
|
username = "You"; |
||||
|
namePost = "You're"; |
||||
|
} |
||||
|
setTitle(username); |
||||
|
resources = getResources(); |
||||
|
clickListener = v -> { |
||||
|
final Object tag = v.getTag(); |
||||
|
if (tag instanceof FollowModel) { |
||||
|
model = (FollowModel) tag; |
||||
|
final FollowViewerFragmentDirections.ActionFollowViewerFragmentToProfileFragment action = FollowViewerFragmentDirections |
||||
|
.actionFollowViewerFragmentToProfileFragment(); |
||||
|
action.setUsername("@" + model.getUsername()); |
||||
|
NavHostFragment.findNavController(this).navigate(action); |
||||
|
} |
||||
|
}; |
||||
|
binding.swipeRefreshLayout.setOnRefreshListener(this); |
||||
|
onRefresh(); |
||||
|
} |
||||
|
|
||||
|
private void setTitle(final String title) { |
||||
|
final ActionBar actionBar = fragmentActivity.getSupportActionBar(); |
||||
|
if (actionBar == null) return; |
||||
|
actionBar.setTitle(title); |
||||
|
} |
||||
|
|
||||
|
private void setSubtitle(final String subtitle) { |
||||
|
final ActionBar actionBar = fragmentActivity.getSupportActionBar(); |
||||
|
if (actionBar == null) return; |
||||
|
actionBar.setSubtitle(subtitle); |
||||
|
} |
||||
|
|
||||
|
private void setSubtitle(@SuppressWarnings("SameParameterValue") final int subtitleRes) { |
||||
|
final ActionBar actionBar = fragmentActivity.getSupportActionBar(); |
||||
|
if (actionBar == null) return; |
||||
|
actionBar.setSubtitle(subtitleRes); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onRefresh() { |
||||
|
if (isCompare) listCompare(); |
||||
|
else listFollows(); |
||||
|
} |
||||
|
|
||||
|
private void listFollows() { |
||||
|
stopCurrentExecutor(); |
||||
|
type = resources.getString(isFollowersList ? R.string.followers_type_followers : R.string.followers_type_following); |
||||
|
setSubtitle(type); |
||||
|
followModels.clear(); |
||||
|
final FetchListener<FollowModel[]> fetchListener = new FetchListener<FollowModel[]>() { |
||||
|
@Override |
||||
|
public void doBefore() { |
||||
|
binding.swipeRefreshLayout.setRefreshing(true); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onResult(final FollowModel[] result) { |
||||
|
if (result == null) binding.swipeRefreshLayout.setRefreshing(false); |
||||
|
else { |
||||
|
followModels.addAll(Arrays.asList(result)); |
||||
|
|
||||
|
final FollowModel model = result[result.length - 1]; |
||||
|
if (model != null && model.hasNextPage()) { |
||||
|
stopCurrentExecutor(); |
||||
|
currentlyExecuting = new FollowFetcher(profileId, isFollowersList, model.getEndCursor(), this) |
||||
|
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
||||
|
model.setPageCursor(false, null); |
||||
|
} else { |
||||
|
binding.swipeRefreshLayout.setRefreshing(false); |
||||
|
|
||||
|
refreshAdapter(followModels, null, null, null); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
currentlyExecuting = new FollowFetcher(profileId, isFollowersList, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
||||
|
} |
||||
|
|
||||
|
private void listCompare() { |
||||
|
stopCurrentExecutor(); |
||||
|
setSubtitle(R.string.followers_compare); |
||||
|
allFollowing.clear(); |
||||
|
followersModels.clear(); |
||||
|
followingModels.clear(); |
||||
|
final FetchListener<FollowModel[]> followingFetchListener = new FetchListener<FollowModel[]>() { |
||||
|
@Override |
||||
|
public void onResult(final FollowModel[] result) { |
||||
|
if (result != null) { |
||||
|
followingModels.addAll(Arrays.asList(result)); |
||||
|
|
||||
|
final FollowModel model = result[result.length - 1]; |
||||
|
if (model != null && model.hasNextPage()) { |
||||
|
stopCurrentExecutor(); |
||||
|
currentlyExecuting = new FollowFetcher(profileId, false, model.getEndCursor(), this) |
||||
|
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
||||
|
model.setPageCursor(false, null); |
||||
|
} else { |
||||
|
allFollowing.addAll(followersModels); |
||||
|
allFollowing.retainAll(followingModels); |
||||
|
|
||||
|
for (final FollowModel followModel : allFollowing) { |
||||
|
followersModels.remove(followModel); |
||||
|
followingModels.remove(followModel); |
||||
|
} |
||||
|
|
||||
|
allFollowing.trimToSize(); |
||||
|
followersModels.trimToSize(); |
||||
|
followingModels.trimToSize(); |
||||
|
|
||||
|
binding.swipeRefreshLayout.setRefreshing(false); |
||||
|
|
||||
|
refreshAdapter(null, followingModels, followersModels, allFollowing); |
||||
|
} |
||||
|
} else binding.swipeRefreshLayout.setRefreshing(false); |
||||
|
} |
||||
|
}; |
||||
|
final FetchListener<FollowModel[]> followersFetchListener = new FetchListener<FollowModel[]>() { |
||||
|
@Override |
||||
|
public void doBefore() { |
||||
|
binding.swipeRefreshLayout.setRefreshing(true); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onResult(final FollowModel[] result) { |
||||
|
if (result != null) { |
||||
|
followersModels.addAll(Arrays.asList(result)); |
||||
|
final FollowModel model = result[result.length - 1]; |
||||
|
if (model == null || !model.hasNextPage()) { |
||||
|
stopCurrentExecutor(); |
||||
|
currentlyExecuting = new FollowFetcher(profileId, false, followingFetchListener) |
||||
|
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
||||
|
} else { |
||||
|
stopCurrentExecutor(); |
||||
|
currentlyExecuting = new FollowFetcher(profileId, true, model.getEndCursor(), this) |
||||
|
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
||||
|
model.setPageCursor(false, null); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
currentlyExecuting = new FollowFetcher(profileId, true, followersFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onCreateOptionsMenu(@NonNull final Menu menu, final MenuInflater inflater) { |
||||
|
inflater.inflate(R.menu.follow, menu); |
||||
|
final MenuItem favItem = menu.findItem(R.id.favourites); |
||||
|
if (favItem != null) { |
||||
|
favItem.setVisible(false); |
||||
|
} |
||||
|
final MenuItem menuSearch = menu.findItem(R.id.action_search); |
||||
|
final SearchView searchView = (SearchView) menuSearch.getActionView(); |
||||
|
searchView.setQueryHint(getResources().getString(R.string.action_search)); |
||||
|
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { |
||||
|
// private final Filter filter = new Filter() { |
||||
|
// private final ArrayList<FollowModel> searchFollowModels = new ArrayList<>(followModels.size() / 2); |
||||
|
// private final ArrayList<FollowModel> searchFollowingModels = new ArrayList<>(followingModels.size() / 2); |
||||
|
// private final ArrayList<FollowModel> searchFollowersModels = new ArrayList<>(followersModels.size() / 2); |
||||
|
// private final ArrayList<FollowModel> searchAllFollowing = new ArrayList<>(allFollowing.size() / 2); |
||||
|
// |
||||
|
// @Nullable |
||||
|
// @Override |
||||
|
// protected FilterResults performFiltering(@NonNull final CharSequence constraint) { |
||||
|
// searchFollowModels.clear(); |
||||
|
// searchFollowingModels.clear(); |
||||
|
// searchFollowersModels.clear(); |
||||
|
// searchAllFollowing.clear(); |
||||
|
// |
||||
|
// final int followModelsSize = followModels.size(); |
||||
|
// final int followingModelsSize = followingModels.size(); |
||||
|
// final int followersModelsSize = followersModels.size(); |
||||
|
// final int allFollowingSize = allFollowing.size(); |
||||
|
// |
||||
|
// int maxSize = followModelsSize; |
||||
|
// if (maxSize < followingModelsSize) maxSize = followingModelsSize; |
||||
|
// if (maxSize < followersModelsSize) maxSize = followersModelsSize; |
||||
|
// if (maxSize < allFollowingSize) maxSize = allFollowingSize; |
||||
|
// |
||||
|
// final String query = constraint.toString().toLowerCase(); |
||||
|
// FollowModel followModel; |
||||
|
// while (maxSize != -1) { |
||||
|
// if (maxSize < followModelsSize) { |
||||
|
// followModel = followModels.get(maxSize); |
||||
|
// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName())) |
||||
|
// searchFollowModels.add(followModel); |
||||
|
// } |
||||
|
// |
||||
|
// if (maxSize < followingModelsSize) { |
||||
|
// followModel = followingModels.get(maxSize); |
||||
|
// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName())) |
||||
|
// searchFollowingModels.add(followModel); |
||||
|
// } |
||||
|
// |
||||
|
// if (maxSize < followersModelsSize) { |
||||
|
// followModel = followersModels.get(maxSize); |
||||
|
// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName())) |
||||
|
// searchFollowersModels.add(followModel); |
||||
|
// } |
||||
|
// |
||||
|
// if (maxSize < allFollowingSize) { |
||||
|
// followModel = allFollowing.get(maxSize); |
||||
|
// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName())) |
||||
|
// searchAllFollowing.add(followModel); |
||||
|
// } |
||||
|
// |
||||
|
// --maxSize; |
||||
|
// } |
||||
|
// |
||||
|
// return null; |
||||
|
// } |
||||
|
// |
||||
|
// @Override |
||||
|
// protected void publishResults(final CharSequence query, final FilterResults results) { |
||||
|
// refreshAdapter(searchFollowModels, searchFollowingModels, searchFollowersModels, searchAllFollowing); |
||||
|
// } |
||||
|
// }; |
||||
|
|
||||
|
@Override |
||||
|
public boolean onQueryTextSubmit(final String query) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean onQueryTextChange(final String query) { |
||||
|
// if (Utils.isEmpty(query)) refreshAdapter(followModels, followingModels, followersModels, allFollowing); |
||||
|
// else filter.filter(query.toLowerCase()); |
||||
|
if (adapter != null) adapter.getFilter().filter(query); |
||||
|
return true; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean onOptionsItemSelected(@NonNull final MenuItem item) { |
||||
|
if (item.getItemId() != R.id.action_compare) return super.onOptionsItemSelected(item); |
||||
|
binding.rvFollow.setAdapter(null); |
||||
|
if (isCompare) listFollows(); |
||||
|
else listCompare(); |
||||
|
isCompare = !isCompare; |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
private void refreshAdapter(final ArrayList<FollowModel> followModels, |
||||
|
final ArrayList<FollowModel> followingModels, |
||||
|
final ArrayList<FollowModel> followersModels, |
||||
|
final ArrayList<FollowModel> allFollowing) { |
||||
|
final ArrayList<ExpandableGroup> groups = new ArrayList<>(1); |
||||
|
|
||||
|
if (isCompare) { |
||||
|
if (followingModels != null && followingModels.size() > 0) |
||||
|
groups.add(new ExpandableGroup(resources.getString(R.string.followers_not_following, username), followingModels)); |
||||
|
if (followersModels != null && followersModels.size() > 0) |
||||
|
groups.add(new ExpandableGroup(resources.getString(R.string.followers_not_follower, namePost), followersModels)); |
||||
|
if (allFollowing != null && allFollowing.size() > 0) |
||||
|
groups.add(new ExpandableGroup(resources.getString(R.string.followers_both_following), allFollowing)); |
||||
|
} else { |
||||
|
final ExpandableGroup group = new ExpandableGroup(type, followModels); |
||||
|
groups.add(group); |
||||
|
} |
||||
|
|
||||
|
adapter = new FollowAdapter(requireContext(), clickListener, groups); |
||||
|
adapter.toggleGroup(0); |
||||
|
binding.rvFollow.setAdapter(adapter); |
||||
|
} |
||||
|
|
||||
|
public void stopCurrentExecutor() { |
||||
|
if (currentlyExecuting != null) { |
||||
|
try { |
||||
|
currentlyExecuting.cancel(true); |
||||
|
} catch (final Exception e) { |
||||
|
if (logCollector != null) |
||||
|
logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor"); |
||||
|
if (BuildConfig.DEBUG) { |
||||
|
Log.e(TAG, "", e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -1,31 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
|
||||
xmlns:tools="http://schemas.android.com/tools" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="match_parent" |
|
||||
android:orientation="vertical" |
|
||||
tools:context=".activities.FollowViewer"> |
|
||||
|
|
||||
<include |
|
||||
android:id="@+id/toolbar" |
|
||||
layout="@layout/layout_include_toolbar" /> |
|
||||
|
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout |
|
||||
android:id="@+id/swipeRefreshLayout" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="match_parent"> |
|
||||
|
|
||||
<androidx.recyclerview.widget.RecyclerView |
|
||||
android:id="@+id/rvFollow" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="match_parent" |
|
||||
android:clipToPadding="false" |
|
||||
android:paddingStart="8dp" |
|
||||
android:paddingLeft="8dp" |
|
||||
android:paddingEnd="8dp" |
|
||||
android:paddingRight="8dp" |
|
||||
app:layoutManager="LinearLayoutManager" |
|
||||
tools:listitem="@layout/item_follow" /> |
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> |
|
||||
</LinearLayout> |
|
@ -0,0 +1,21 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
|
xmlns:tools="http://schemas.android.com/tools" |
||||
|
android:id="@+id/swipeRefreshLayout" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="match_parent" |
||||
|
tools:context=".activities.FollowViewerFragment"> |
||||
|
|
||||
|
<androidx.recyclerview.widget.RecyclerView |
||||
|
android:id="@+id/rvFollow" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="match_parent" |
||||
|
android:clipToPadding="false" |
||||
|
android:paddingStart="8dp" |
||||
|
android:paddingLeft="8dp" |
||||
|
android:paddingEnd="8dp" |
||||
|
android:paddingRight="8dp" |
||||
|
app:layoutManager="LinearLayoutManager" |
||||
|
tools:listitem="@layout/item_follow" /> |
||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue