|
|
|
|
@@ -1,61 +1,33 @@
|
|
|
|
|
package org.joinmastodon.android.fragments.onboarding;
|
|
|
|
|
|
|
|
|
|
import android.app.ProgressDialog;
|
|
|
|
|
import android.graphics.drawable.Animatable;
|
|
|
|
|
import android.graphics.drawable.Drawable;
|
|
|
|
|
import android.os.Build;
|
|
|
|
|
import android.os.Bundle;
|
|
|
|
|
import android.text.TextUtils;
|
|
|
|
|
import android.view.View;
|
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
|
import android.view.WindowInsets;
|
|
|
|
|
import android.widget.Button;
|
|
|
|
|
import android.widget.FrameLayout;
|
|
|
|
|
import android.widget.ImageView;
|
|
|
|
|
import android.widget.ProgressBar;
|
|
|
|
|
import android.widget.TextView;
|
|
|
|
|
|
|
|
|
|
import org.joinmastodon.android.R;
|
|
|
|
|
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
|
|
|
|
|
import org.joinmastodon.android.api.requests.accounts.GetFollowSuggestions;
|
|
|
|
|
import org.joinmastodon.android.api.requests.accounts.SetAccountFollowed;
|
|
|
|
|
import org.joinmastodon.android.fragments.HomeFragment;
|
|
|
|
|
import org.joinmastodon.android.fragments.ProfileFragment;
|
|
|
|
|
import org.joinmastodon.android.fragments.account_list.BaseAccountListFragment;
|
|
|
|
|
import org.joinmastodon.android.model.FollowSuggestion;
|
|
|
|
|
import org.joinmastodon.android.model.Relationship;
|
|
|
|
|
import org.joinmastodon.android.model.viewmodel.AccountViewModel;
|
|
|
|
|
import org.joinmastodon.android.ui.OutlineProviders;
|
|
|
|
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
|
|
|
|
import org.joinmastodon.android.ui.views.ProgressBarButton;
|
|
|
|
|
import org.joinmastodon.android.ui.viewholders.AccountViewHolder;
|
|
|
|
|
import org.joinmastodon.android.utils.ElevationOnScrollListener;
|
|
|
|
|
import org.parceler.Parcels;
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.function.Function;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
|
|
|
import me.grishka.appkit.Nav;
|
|
|
|
|
import me.grishka.appkit.api.Callback;
|
|
|
|
|
import me.grishka.appkit.api.ErrorResponse;
|
|
|
|
|
import me.grishka.appkit.api.SimpleCallback;
|
|
|
|
|
import me.grishka.appkit.fragments.BaseRecyclerFragment;
|
|
|
|
|
import me.grishka.appkit.imageloader.ImageLoaderRecyclerAdapter;
|
|
|
|
|
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
|
|
|
|
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
|
|
|
|
import me.grishka.appkit.utils.BindableViewHolder;
|
|
|
|
|
import me.grishka.appkit.utils.V;
|
|
|
|
|
import me.grishka.appkit.views.FragmentRootLinearLayout;
|
|
|
|
|
import me.grishka.appkit.views.UsableRecyclerView;
|
|
|
|
|
|
|
|
|
|
public class OnboardingFollowSuggestionsFragment extends BaseRecyclerFragment<AccountViewModel>{
|
|
|
|
|
public class OnboardingFollowSuggestionsFragment extends BaseAccountListFragment{
|
|
|
|
|
private String accountID;
|
|
|
|
|
private Map<String, Relationship> relationships=Collections.emptyMap();
|
|
|
|
|
private GetAccountRelationships relationshipsRequest;
|
|
|
|
|
private View buttonBar;
|
|
|
|
|
private ElevationOnScrollListener onScrollListener;
|
|
|
|
|
private int numRunningFollowRequests=0;
|
|
|
|
|
@@ -98,46 +70,16 @@ public class OnboardingFollowSuggestionsFragment extends BaseRecyclerFragment<Ac
|
|
|
|
|
@Override
|
|
|
|
|
public void onSuccess(List<FollowSuggestion> result){
|
|
|
|
|
onDataLoaded(result.stream().map(fs->new AccountViewModel(fs.account, accountID)).collect(Collectors.toList()), false);
|
|
|
|
|
loadRelationships();
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.exec(accountID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void loadRelationships(){
|
|
|
|
|
relationships=Collections.emptyMap();
|
|
|
|
|
relationshipsRequest=new GetAccountRelationships(data.stream().map(fs->fs.account.id).collect(Collectors.toList()));
|
|
|
|
|
relationshipsRequest.setCallback(new Callback<>(){
|
|
|
|
|
@Override
|
|
|
|
|
public void onSuccess(List<Relationship> result){
|
|
|
|
|
relationshipsRequest=null;
|
|
|
|
|
relationships=result.stream().collect(Collectors.toMap(rel->rel.id, Function.identity()));
|
|
|
|
|
if(list==null)
|
|
|
|
|
return;
|
|
|
|
|
for(int i=0;i<list.getChildCount();i++){
|
|
|
|
|
RecyclerView.ViewHolder holder=list.getChildViewHolder(list.getChildAt(i));
|
|
|
|
|
if(holder instanceof SuggestionViewHolder svh)
|
|
|
|
|
svh.rebind();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onError(ErrorResponse error){
|
|
|
|
|
relationshipsRequest=null;
|
|
|
|
|
}
|
|
|
|
|
}).exec(accountID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onApplyWindowInsets(WindowInsets insets){
|
|
|
|
|
super.onApplyWindowInsets(UiUtils.applyBottomInsetToFixedView(buttonBar, insets));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected RecyclerView.Adapter getAdapter(){
|
|
|
|
|
return new SuggestionsAdapter();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void onFollowAllClick(View v){
|
|
|
|
|
if(!loaded || relationships.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
@@ -183,7 +125,7 @@ public class OnboardingFollowSuggestionsFragment extends BaseRecyclerFragment<Ac
|
|
|
|
|
public void onSuccess(Relationship result){
|
|
|
|
|
relationships.put(id, result);
|
|
|
|
|
for(int i=0;i<list.getChildCount();i++){
|
|
|
|
|
if(list.getChildViewHolder(list.getChildAt(i)) instanceof SuggestionViewHolder svh && svh.getItem().account.id.equals(id)){
|
|
|
|
|
if(list.getChildViewHolder(list.getChildAt(i)) instanceof AccountViewHolder svh && svh.getItem().account.id.equals(id)){
|
|
|
|
|
svh.rebind();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -209,128 +151,9 @@ public class OnboardingFollowSuggestionsFragment extends BaseRecyclerFragment<Ac
|
|
|
|
|
Nav.go(getActivity(), OnboardingProfileSetupFragment.class, args);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class SuggestionsAdapter extends UsableRecyclerView.Adapter<SuggestionViewHolder> implements ImageLoaderRecyclerAdapter{
|
|
|
|
|
|
|
|
|
|
public SuggestionsAdapter(){
|
|
|
|
|
super(imgLoader);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@NonNull
|
|
|
|
|
@Override
|
|
|
|
|
public SuggestionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
|
|
|
|
|
return new SuggestionViewHolder();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int getItemCount(){
|
|
|
|
|
return data.size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onBindViewHolder(SuggestionViewHolder holder, int position){
|
|
|
|
|
holder.bind(data.get(position));
|
|
|
|
|
super.onBindViewHolder(holder, position);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int getImageCountForItem(int position){
|
|
|
|
|
return data.get(position).emojiHelper.getImageCount()+1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public ImageLoaderRequest getImageRequest(int position, int image){
|
|
|
|
|
AccountViewModel account=data.get(position);
|
|
|
|
|
if(image==0)
|
|
|
|
|
return account.avaRequest;
|
|
|
|
|
return account.emojiHelper.getImageRequest(image-1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class SuggestionViewHolder extends BindableViewHolder<AccountViewModel> implements ImageLoaderViewHolder, UsableRecyclerView.Clickable{
|
|
|
|
|
private final TextView name, username, bio;
|
|
|
|
|
private final ImageView avatar;
|
|
|
|
|
private final ProgressBarButton actionButton;
|
|
|
|
|
private final ProgressBar actionProgress;
|
|
|
|
|
private final View actionWrap;
|
|
|
|
|
|
|
|
|
|
private Relationship relationship;
|
|
|
|
|
|
|
|
|
|
public SuggestionViewHolder(){
|
|
|
|
|
super(getActivity(), R.layout.item_user_row_m3, list);
|
|
|
|
|
name=findViewById(R.id.name);
|
|
|
|
|
username=findViewById(R.id.username);
|
|
|
|
|
bio=findViewById(R.id.bio);
|
|
|
|
|
avatar=findViewById(R.id.avatar);
|
|
|
|
|
actionButton=findViewById(R.id.action_btn);
|
|
|
|
|
actionProgress=findViewById(R.id.action_progress);
|
|
|
|
|
actionWrap=findViewById(R.id.action_btn_wrap);
|
|
|
|
|
|
|
|
|
|
avatar.setOutlineProvider(OutlineProviders.roundedRect(10));
|
|
|
|
|
avatar.setClipToOutline(true);
|
|
|
|
|
actionButton.setOnClickListener(UiUtils.rateLimitedClickListener(this::onActionButtonClick));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onBind(AccountViewModel item){
|
|
|
|
|
name.setText(item.parsedName);
|
|
|
|
|
username.setText(item.account.getDisplayUsername());
|
|
|
|
|
if(TextUtils.isEmpty(item.parsedBio)){
|
|
|
|
|
bio.setVisibility(View.GONE);
|
|
|
|
|
}else{
|
|
|
|
|
bio.setVisibility(View.VISIBLE);
|
|
|
|
|
bio.setText(item.parsedBio);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
relationship=relationships.get(item.account.id);
|
|
|
|
|
if(relationship==null){
|
|
|
|
|
actionWrap.setVisibility(View.GONE);
|
|
|
|
|
}else{
|
|
|
|
|
actionWrap.setVisibility(View.VISIBLE);
|
|
|
|
|
UiUtils.setRelationshipToActionButtonM3(relationship, actionButton);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void setImage(int index, Drawable image){
|
|
|
|
|
if(index==0){
|
|
|
|
|
avatar.setImageDrawable(image);
|
|
|
|
|
}else{
|
|
|
|
|
item.emojiHelper.setImageDrawable(index-1, image);
|
|
|
|
|
name.invalidate();
|
|
|
|
|
bio.invalidate();
|
|
|
|
|
}
|
|
|
|
|
if(image instanceof Animatable a && !a.isRunning())
|
|
|
|
|
a.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void clearImage(int index){
|
|
|
|
|
setImage(index, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onClick(){
|
|
|
|
|
Bundle args=new Bundle();
|
|
|
|
|
args.putString("account", accountID);
|
|
|
|
|
args.putParcelable("profileAccount", Parcels.wrap(item.account));
|
|
|
|
|
Nav.go(getActivity(), ProfileFragment.class, args);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void onActionButtonClick(View v){
|
|
|
|
|
itemView.setHasTransientState(true);
|
|
|
|
|
UiUtils.performAccountAction(getActivity(), item.account, accountID, relationship, actionButton, this::setActionProgressVisible, rel->{
|
|
|
|
|
itemView.setHasTransientState(false);
|
|
|
|
|
relationships.put(item.account.id, rel);
|
|
|
|
|
rebind();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void setActionProgressVisible(boolean visible){
|
|
|
|
|
if(visible)
|
|
|
|
|
actionProgress.setIndeterminateTintList(actionButton.getTextColors());
|
|
|
|
|
actionButton.setTextVisible(!visible);
|
|
|
|
|
actionProgress.setVisibility(visible ? View.VISIBLE : View.GONE);
|
|
|
|
|
actionButton.setClickable(!visible);
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
protected void onConfigureViewHolder(AccountViewHolder holder){
|
|
|
|
|
super.onConfigureViewHolder(holder);
|
|
|
|
|
holder.setStyle(AccountViewHolder.AccessoryType.BUTTON, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|