implement adding/removing users from lists
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
package org.joinmastodon.android.api.requests.lists;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import java.util.List;
|
||||
|
||||
public class AddAccountsToList extends MastodonAPIRequest<Object> {
|
||||
public AddAccountsToList(String listId, List<String> accountIds){
|
||||
super(HttpMethod.POST, "/lists/"+listId+"/accounts", Object.class);
|
||||
Request req = new Request();
|
||||
req.accountIds = accountIds;
|
||||
setRequestBody(req);
|
||||
}
|
||||
|
||||
public static class Request{
|
||||
public List<String> accountIds;
|
||||
}
|
||||
}
|
||||
@@ -11,4 +11,7 @@ public class GetLists extends MastodonAPIRequest<List<ListTimeline>>{
|
||||
public GetLists() {
|
||||
super(HttpMethod.GET, "/lists", new TypeToken<>(){});
|
||||
}
|
||||
public GetLists(String accountID) {
|
||||
super(HttpMethod.GET, "/accounts/"+accountID+"/lists", new TypeToken<>(){});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.joinmastodon.android.api.requests.lists;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import java.util.List;
|
||||
|
||||
public class RemoveAccountsFromList extends MastodonAPIRequest<Object> {
|
||||
public RemoveAccountsFromList(String listId, List<String> accountIds){
|
||||
super(HttpMethod.DELETE, "/lists/"+listId+"/accounts", Object.class);
|
||||
Request req = new Request();
|
||||
req.accountIds = accountIds;
|
||||
setRequestBody(req);
|
||||
}
|
||||
|
||||
public static class Request{
|
||||
public List<String> accountIds;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,48 @@
|
||||
package org.joinmastodon.android.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.api.requests.lists.AddAccountsToList;
|
||||
import org.joinmastodon.android.api.requests.lists.GetLists;
|
||||
import org.joinmastodon.android.fragments.ScrollableToTop;
|
||||
import org.joinmastodon.android.api.requests.lists.RemoveAccountsFromList;
|
||||
import org.joinmastodon.android.model.ListTimeline;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import me.grishka.appkit.api.ErrorResponse;
|
||||
import me.grishka.appkit.api.SimpleCallback;
|
||||
import me.grishka.appkit.fragments.BaseRecyclerFragment;
|
||||
import me.grishka.appkit.utils.BindableViewHolder;
|
||||
import me.grishka.appkit.utils.V;
|
||||
import me.grishka.appkit.views.UsableRecyclerView;
|
||||
|
||||
public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> implements ScrollableToTop {
|
||||
private String accountId;
|
||||
private String profileAccountId;
|
||||
private String profileDisplayUsername;
|
||||
private HashMap<String, Boolean> userInListBefore = new HashMap<>();
|
||||
private HashMap<String, Boolean> userInList = new HashMap<>();
|
||||
private int inProgress = 0;
|
||||
|
||||
public ListTimelinesFragment() {
|
||||
super(10);
|
||||
@@ -32,16 +51,101 @@ public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> im
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
accountId=getArguments().getString("account");
|
||||
Bundle args=getArguments();
|
||||
accountId=args.getString("account");
|
||||
|
||||
if(args.containsKey("profileAccount")){
|
||||
profileAccountId=args.getString("profileAccount");
|
||||
profileDisplayUsername=args.getString("profileDisplayUsername");
|
||||
setTitle(getString(R.string.lists_with_user, profileDisplayUsername));
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShown(){
|
||||
super.onShown();
|
||||
if(!getArguments().getBoolean("noAutoLoad") && !loaded && !dataLoading)
|
||||
loadData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
Button saveButton=new Button(getActivity());
|
||||
saveButton.setText(R.string.save);
|
||||
saveButton.setOnClickListener(this::onSaveClick);
|
||||
LinearLayout wrap=new LinearLayout(getActivity());
|
||||
wrap.setOrientation(LinearLayout.HORIZONTAL);
|
||||
wrap.addView(saveButton, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
wrap.setPadding(V.dp(16), V.dp(4), V.dp(16), V.dp(8));
|
||||
wrap.setClipToPadding(false);
|
||||
MenuItem item=menu.add(R.string.save);
|
||||
item.setActionView(wrap);
|
||||
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
|
||||
}
|
||||
|
||||
private void onSaveClick(View view) {
|
||||
List<String> addUserToLists = new ArrayList<>();
|
||||
List<String> removeUserFromLists = new ArrayList<>();
|
||||
for (Map.Entry<String, Boolean> entry : userInList.entrySet()) {
|
||||
Boolean changedValue = entry.getValue();
|
||||
String id = entry.getKey();
|
||||
if (changedValue != null && !changedValue.equals(userInListBefore.get(id))) {
|
||||
(changedValue ? addUserToLists : removeUserFromLists).add(id);
|
||||
}
|
||||
}
|
||||
List<String> accountIdList = Collections.singletonList(profileAccountId);
|
||||
for (String listId : addUserToLists) {
|
||||
inProgress++;
|
||||
new AddAccountsToList(listId, accountIdList).setCallback(new SimpleCallback<>(this) {
|
||||
@Override
|
||||
public void onSuccess(Object o) { onRequestComplete(); }
|
||||
@Override
|
||||
public void onError(ErrorResponse error) { super.onError(error); onSuccess(null); }
|
||||
}).exec(accountId);
|
||||
}
|
||||
for (String listId : removeUserFromLists) {
|
||||
inProgress++;
|
||||
new RemoveAccountsFromList(listId, accountIdList).setCallback(new SimpleCallback<>(this) {
|
||||
@Override
|
||||
public void onSuccess(Object o) { onRequestComplete(); }
|
||||
@Override
|
||||
public void onError(ErrorResponse error) { super.onError(error); onSuccess(null); }
|
||||
}).exec(accountId);
|
||||
}
|
||||
}
|
||||
|
||||
private void onRequestComplete() {
|
||||
if (--inProgress == 0) reload();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){
|
||||
currentRequest=new GetLists()
|
||||
userInListBefore.clear();
|
||||
userInList.clear();
|
||||
currentRequest=(profileAccountId != null ? new GetLists(profileAccountId) : new GetLists())
|
||||
.setCallback(new SimpleCallback<>(this) {
|
||||
@Override
|
||||
public void onSuccess(List<ListTimeline> result) {
|
||||
onDataLoaded(result, false);
|
||||
public void onSuccess(List<ListTimeline> lists) {
|
||||
for (ListTimeline l : lists) userInListBefore.put(l.id, true);
|
||||
userInList.putAll(userInListBefore);
|
||||
onDataLoaded(lists, false);
|
||||
if (profileAccountId == null) return;
|
||||
|
||||
currentRequest=new GetLists().setCallback(new SimpleCallback<>(ListTimelinesFragment.this) {
|
||||
@Override
|
||||
public void onSuccess(List<ListTimeline> allLists) {
|
||||
List<ListTimeline> newLists = new ArrayList<>();
|
||||
for (ListTimeline l : allLists) {
|
||||
if (lists.stream().noneMatch(e -> e.id.equals(l.id))) newLists.add(l);
|
||||
if (!userInListBefore.containsKey(l.id)) {
|
||||
userInListBefore.put(l.id, false);
|
||||
}
|
||||
}
|
||||
userInList.putAll(userInListBefore);
|
||||
onDataLoaded(newLists, false);
|
||||
}
|
||||
}).exec(accountId);
|
||||
}
|
||||
})
|
||||
.exec(accountId);
|
||||
@@ -77,15 +181,30 @@ public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> im
|
||||
|
||||
private class ListViewHolder extends BindableViewHolder<ListTimeline> implements UsableRecyclerView.Clickable{
|
||||
private final TextView title;
|
||||
private final CheckBox listToggle;
|
||||
|
||||
public ListViewHolder(){
|
||||
super(getActivity(), R.layout.item_list_timeline, list);
|
||||
title=findViewById(R.id.title);
|
||||
listToggle=findViewById(R.id.list_toggle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(ListTimeline item) {
|
||||
title.setText(item.title);
|
||||
if (profileAccountId != null) {
|
||||
Boolean checked = userInList.get(item.id);
|
||||
listToggle.setChecked(userInList.containsKey(item.id) && checked != null && checked);
|
||||
listToggle.setOnClickListener(this::onClickToggle);
|
||||
} else {
|
||||
listToggle.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void onClickToggle(View view) {
|
||||
if (view instanceof CheckBox cb) {
|
||||
userInList.put(item.id, cb.isChecked());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -521,10 +521,11 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
return;
|
||||
inflater.inflate(R.menu.profile, menu);
|
||||
menu.findItem(R.id.share).setTitle(getString(R.string.share_user, account.getDisplayUsername()));
|
||||
menu.findItem(R.id.manage_user_lists).setTitle(getString(R.string.lists_with_user, account.getDisplayUsername()));
|
||||
if(isOwnProfile){
|
||||
for(int i=0;i<menu.size();i++){
|
||||
MenuItem item=menu.getItem(i);
|
||||
item.setVisible(item.getItemId()==R.id.share);
|
||||
item.setVisible(item.getItemId()==R.id.share || item.getItemId()==R.id.manage_user_lists);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -580,6 +581,12 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
})
|
||||
.wrapProgress(getActivity(), R.string.loading, false)
|
||||
.exec(accountID);
|
||||
}else if(id==R.id.manage_user_lists){
|
||||
final Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
args.putString("profileAccount", profileAccountID);
|
||||
args.putString("profileDisplayUsername", account.getDisplayUsername());
|
||||
Nav.go(getActivity(), ListTimelinesFragment.class, args);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user