AND-127
This commit is contained in:
parent
6bcf259de9
commit
d0e33c8a12
|
@ -1,12 +1,17 @@
|
||||||
package org.joinmastodon.android.fragments;
|
package org.joinmastodon.android.fragments;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.ActionMode;
|
import android.view.ActionMode;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.view.WindowInsets;
|
import android.view.WindowInsets;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
|
|
||||||
import com.squareup.otto.Subscribe;
|
import com.squareup.otto.Subscribe;
|
||||||
|
@ -19,7 +24,7 @@ import org.joinmastodon.android.api.requests.lists.GetListAccounts;
|
||||||
import org.joinmastodon.android.api.requests.lists.RemoveAccountsFromList;
|
import org.joinmastodon.android.api.requests.lists.RemoveAccountsFromList;
|
||||||
import org.joinmastodon.android.events.AccountAddedToListEvent;
|
import org.joinmastodon.android.events.AccountAddedToListEvent;
|
||||||
import org.joinmastodon.android.events.AccountRemovedFromListEvent;
|
import org.joinmastodon.android.events.AccountRemovedFromListEvent;
|
||||||
import org.joinmastodon.android.fragments.account_list.AddListMembersFragment;
|
import org.joinmastodon.android.fragments.account_list.AddNewListMembersFragment;
|
||||||
import org.joinmastodon.android.fragments.account_list.PaginatedAccountListFragment;
|
import org.joinmastodon.android.fragments.account_list.PaginatedAccountListFragment;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
import org.joinmastodon.android.model.FollowList;
|
import org.joinmastodon.android.model.FollowList;
|
||||||
|
@ -33,24 +38,31 @@ import org.parceler.Parcels;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import me.grishka.appkit.Nav;
|
import me.grishka.appkit.Nav;
|
||||||
import me.grishka.appkit.api.Callback;
|
import me.grishka.appkit.api.Callback;
|
||||||
import me.grishka.appkit.api.ErrorResponse;
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
|
import me.grishka.appkit.fragments.OnBackPressedListener;
|
||||||
|
import me.grishka.appkit.utils.CubicBezierInterpolator;
|
||||||
import me.grishka.appkit.utils.V;
|
import me.grishka.appkit.utils.V;
|
||||||
|
import me.grishka.appkit.views.FragmentRootLinearLayout;
|
||||||
|
|
||||||
public class ListMembersFragment extends PaginatedAccountListFragment{
|
public class ListMembersFragment extends PaginatedAccountListFragment implements AddNewListMembersFragment.Listener, OnBackPressedListener{
|
||||||
private static final int ADD_MEMBER_RESULT=600;
|
|
||||||
|
|
||||||
private ImageButton fab;
|
private ImageButton fab;
|
||||||
private FollowList followList;
|
private FollowList followList;
|
||||||
private boolean inSelectionMode;
|
private boolean inSelectionMode;
|
||||||
private Set<String> selectedAccounts=new HashSet<>();
|
private Set<String> selectedAccounts=new HashSet<>();
|
||||||
private ActionMode actionMode;
|
private ActionMode actionMode;
|
||||||
private MenuItem deleteItem;
|
private MenuItem deleteItem;
|
||||||
|
private FrameLayout searchFragmentContainer;
|
||||||
|
private FrameLayout fragmentContentWrap;
|
||||||
|
private AddNewListMembersFragment searchFragment;
|
||||||
|
private FragmentRootLinearLayout rootView;
|
||||||
|
private WindowInsets lastInsets;
|
||||||
|
private HashSet<String> accountIDsInList=new HashSet<>();
|
||||||
|
private boolean dismissingSearchFragment;
|
||||||
|
|
||||||
public ListMembersFragment(){
|
public ListMembersFragment(){
|
||||||
setListLayoutId(R.layout.recycler_fragment_with_fab);
|
setListLayoutId(R.layout.recycler_fragment_with_fab);
|
||||||
|
@ -76,6 +88,26 @@ public class ListMembersFragment extends PaginatedAccountListFragment{
|
||||||
return new GetListAccounts(followList.id, maxID, count);
|
return new GetListAccounts(followList.id, maxID, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDataLoaded(List<AccountViewModel> d, boolean more){
|
||||||
|
if(refreshing)
|
||||||
|
accountIDsInList.clear();
|
||||||
|
for(AccountViewModel a:d){
|
||||||
|
accountIDsInList.add(a.account.id);
|
||||||
|
}
|
||||||
|
super.onDataLoaded(d, more);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
|
||||||
|
View view=super.onCreateView(inflater, container, savedInstanceState);
|
||||||
|
FrameLayout wrapper=new FrameLayout(getActivity());
|
||||||
|
wrapper.addView(view);
|
||||||
|
rootView=(FragmentRootLinearLayout) view;
|
||||||
|
fragmentContentWrap=wrapper;
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onConfigureViewHolder(AccountViewHolder holder){
|
protected void onConfigureViewHolder(AccountViewHolder holder){
|
||||||
super.onConfigureViewHolder(holder);
|
super.onConfigureViewHolder(holder);
|
||||||
|
@ -132,16 +164,19 @@ public class ListMembersFragment extends PaginatedAccountListFragment{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onApplyWindowInsets(WindowInsets insets){
|
public void onApplyWindowInsets(WindowInsets insets){
|
||||||
super.onApplyWindowInsets(insets);
|
lastInsets=insets;
|
||||||
|
if(searchFragment!=null)
|
||||||
|
searchFragment.onApplyWindowInsets(insets);
|
||||||
UiUtils.applyBottomInsetToFAB(fab, insets);
|
UiUtils.applyBottomInsetToFAB(fab, insets);
|
||||||
}
|
if(Build.VERSION.SDK_INT>=29 && insets.getTappableElementInsets().bottom==0){
|
||||||
|
list.setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
|
||||||
@Override
|
emptyView.setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
|
||||||
public void onFragmentResult(int reqCode, boolean success, Bundle result){
|
progress.setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
|
||||||
if(reqCode==ADD_MEMBER_RESULT && success){
|
insets=insets.inset(0, 0, 0, insets.getSystemWindowInsetBottom());
|
||||||
Account acc=Objects.requireNonNull(Parcels.unwrap(result.getParcelable("selectedAccount")));
|
}else{
|
||||||
addAccounts(List.of(acc));
|
list.setPadding(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
rootView.onApplyWindowInsets(insets);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
@ -160,9 +195,25 @@ public class ListMembersFragment extends PaginatedAccountListFragment{
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onFabClick(){
|
private void onFabClick(){
|
||||||
|
searchFragmentContainer=new FrameLayout(getActivity());
|
||||||
|
searchFragmentContainer.setId(R.id.search_fragment);
|
||||||
|
fragmentContentWrap.addView(searchFragmentContainer);
|
||||||
|
|
||||||
Bundle args=new Bundle();
|
Bundle args=new Bundle();
|
||||||
args.putString("account", accountID);
|
args.putString("account", accountID);
|
||||||
Nav.goForResult(getActivity(), AddListMembersFragment.class, args, ADD_MEMBER_RESULT, this);
|
args.putParcelable("list", Parcels.wrap(followList));
|
||||||
|
args.putBoolean("_can_go_back", true);
|
||||||
|
searchFragment=new AddNewListMembersFragment(this);
|
||||||
|
searchFragment.setArguments(args);
|
||||||
|
getChildFragmentManager().beginTransaction().add(R.id.search_fragment, searchFragment).commit();
|
||||||
|
getChildFragmentManager().executePendingTransactions();
|
||||||
|
if(lastInsets!=null)
|
||||||
|
searchFragment.onApplyWindowInsets(lastInsets);
|
||||||
|
searchFragmentContainer.setTranslationX(V.dp(100));
|
||||||
|
searchFragmentContainer.setAlpha(0f);
|
||||||
|
searchFragmentContainer.animate().translationX(0).alpha(1).setDuration(300).withLayer().setInterpolator(CubicBezierInterpolator.DEFAULT).withEndAction(()->{
|
||||||
|
rootView.setVisibility(View.GONE);
|
||||||
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onItemClick(AccountViewHolder holder){
|
private void onItemClick(AccountViewHolder holder){
|
||||||
|
@ -198,7 +249,7 @@ public class ListMembersFragment extends PaginatedAccountListFragment{
|
||||||
if(id==R.id.remove_from_list){
|
if(id==R.id.remove_from_list){
|
||||||
new M3AlertDialogBuilder(getActivity())
|
new M3AlertDialogBuilder(getActivity())
|
||||||
.setTitle(R.string.confirm_remove_list_member)
|
.setTitle(R.string.confirm_remove_list_member)
|
||||||
.setPositiveButton(R.string.remove, (dlg, which)->removeAccounts(Set.of(holder.getItem().account.id)))
|
.setPositiveButton(R.string.remove, (dlg, which)->removeAccounts(Set.of(holder.getItem().account.id), null))
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
@ -229,7 +280,7 @@ public class ListMembersFragment extends PaginatedAccountListFragment{
|
||||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item){
|
public boolean onActionItemClicked(ActionMode mode, MenuItem item){
|
||||||
new M3AlertDialogBuilder(getActivity())
|
new M3AlertDialogBuilder(getActivity())
|
||||||
.setTitle(R.string.confirm_remove_list_members)
|
.setTitle(R.string.confirm_remove_list_members)
|
||||||
.setPositiveButton(R.string.remove, (dlg, which)->removeAccounts(new HashSet<>(selectedAccounts)))
|
.setPositiveButton(R.string.remove, (dlg, which)->removeAccounts(new HashSet<>(selectedAccounts), null))
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
.show();
|
.show();
|
||||||
return true;
|
return true;
|
||||||
|
@ -251,13 +302,16 @@ public class ListMembersFragment extends PaginatedAccountListFragment{
|
||||||
actionMode.setTitle(getResources().getQuantityString(R.plurals.x_items_selected, selectedAccounts.size(), selectedAccounts.size()));
|
actionMode.setTitle(getResources().getQuantityString(R.plurals.x_items_selected, selectedAccounts.size(), selectedAccounts.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeAccounts(Set<String> ids){
|
private void removeAccounts(Set<String> ids, Runnable onDone){
|
||||||
new RemoveAccountsFromList(followList.id, ids)
|
new RemoveAccountsFromList(followList.id, ids)
|
||||||
.setCallback(new Callback<>(){
|
.setCallback(new Callback<>(){
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Void result){
|
public void onSuccess(Void result){
|
||||||
|
if(onDone!=null)
|
||||||
|
onDone.run();
|
||||||
if(inSelectionMode)
|
if(inSelectionMode)
|
||||||
actionMode.finish();
|
actionMode.finish();
|
||||||
|
accountIDsInList.removeAll(ids);
|
||||||
removeAccountRows(ids);
|
removeAccountRows(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,12 +324,15 @@ public class ListMembersFragment extends PaginatedAccountListFragment{
|
||||||
.exec(accountID);
|
.exec(accountID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAccounts(Collection<Account> accounts){
|
private void addAccounts(Collection<Account> accounts, Runnable onDone){
|
||||||
new AddAccountsToList(followList.id, accounts.stream().map(a->a.id).collect(Collectors.toSet()))
|
new AddAccountsToList(followList.id, accounts.stream().map(a->a.id).collect(Collectors.toSet()))
|
||||||
.setCallback(new Callback<>(){
|
.setCallback(new Callback<>(){
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Void result){
|
public void onSuccess(Void result){
|
||||||
|
if(onDone!=null)
|
||||||
|
onDone.run();
|
||||||
for(Account acc:accounts){
|
for(Account acc:accounts){
|
||||||
|
accountIDsInList.add(acc.id);
|
||||||
data.add(new AccountViewModel(acc, accountID));
|
data.add(new AccountViewModel(acc, accountID));
|
||||||
}
|
}
|
||||||
list.getAdapter().notifyItemRangeInserted(data.size()-accounts.size(), accounts.size());
|
list.getAdapter().notifyItemRangeInserted(data.size()-accounts.size(), accounts.size());
|
||||||
|
@ -298,4 +355,54 @@ public class ListMembersFragment extends PaginatedAccountListFragment{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAccountInList(AccountViewModel account){
|
||||||
|
return accountIDsInList.contains(account.account.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAccountToList(AccountViewModel account, Runnable onDone){
|
||||||
|
addAccounts(Set.of(account.account), onDone);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeAccountAccountFromList(AccountViewModel account, Runnable onDone){
|
||||||
|
removeAccounts(Set.of(account.account.id), onDone);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onBackPressed(){
|
||||||
|
if(searchFragment!=null){
|
||||||
|
dismissSearchFragment();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dismissSearchFragment(){
|
||||||
|
if(searchFragment==null || dismissingSearchFragment)
|
||||||
|
return;
|
||||||
|
dismissingSearchFragment=true;
|
||||||
|
rootView.setVisibility(View.VISIBLE);
|
||||||
|
searchFragmentContainer.animate().translationX(V.dp(100)).alpha(0).setDuration(200).withLayer().setInterpolator(CubicBezierInterpolator.DEFAULT).withEndAction(()->{
|
||||||
|
getChildFragmentManager().beginTransaction().remove(searchFragment).commit();
|
||||||
|
getChildFragmentManager().executePendingTransactions();
|
||||||
|
fragmentContentWrap.removeView(searchFragmentContainer);
|
||||||
|
searchFragmentContainer=null;
|
||||||
|
searchFragment=null;
|
||||||
|
dismissingSearchFragment=false;
|
||||||
|
}).start();
|
||||||
|
getActivity().getSystemService(InputMethodManager.class).hideSoftInputFromWindow(contentView.getWindowToken(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setStatusBarColor(int color){
|
||||||
|
rootView.setStatusBarColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setNavigationBarColor(int color){
|
||||||
|
rootView.setNavigationBarColor(color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
package org.joinmastodon.android.fragments.account_list;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import org.joinmastodon.android.R;
|
|
||||||
import org.joinmastodon.android.api.requests.accounts.SearchAccounts;
|
|
||||||
import org.joinmastodon.android.model.Account;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.grishka.appkit.api.SimpleCallback;
|
|
||||||
|
|
||||||
public class AddListMembersFragment extends AccountSearchFragment{
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState){
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
dataLoaded();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doLoadData(int offset, int count){
|
|
||||||
refreshing=true;
|
|
||||||
currentRequest=new SearchAccounts(currentQuery, 0, 0, false, true)
|
|
||||||
.setCallback(new SimpleCallback<>(this){
|
|
||||||
@Override
|
|
||||||
public void onSuccess(List<Account> result){
|
|
||||||
AddListMembersFragment.this.onSuccess(result);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.exec(accountID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getSearchViewPlaceholder(){
|
|
||||||
return getString(R.string.search_among_people_you_follow);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue