diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/requests/polls/SubmitPollVote.java b/mastodon/src/main/java/org/joinmastodon/android/api/requests/polls/SubmitPollVote.java new file mode 100644 index 00000000..bc127dc5 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/api/requests/polls/SubmitPollVote.java @@ -0,0 +1,21 @@ +package org.joinmastodon.android.api.requests.polls; + +import org.joinmastodon.android.api.MastodonAPIRequest; +import org.joinmastodon.android.model.Poll; + +import java.util.List; + +public class SubmitPollVote extends MastodonAPIRequest{ + public SubmitPollVote(String pollID, List choices){ + super(HttpMethod.POST, "/polls/"+pollID+"/votes", Poll.class); + setRequestBody(new Body(choices)); + } + + private static class Body{ + public List choices; + + public Body(List choices){ + this.choices=choices; + } + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java index e0e9eac0..d905444f 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java @@ -16,24 +16,31 @@ import android.widget.ImageView; import android.widget.Toolbar; import org.joinmastodon.android.R; +import org.joinmastodon.android.api.requests.polls.SubmitPollVote; import org.joinmastodon.android.model.Account; import org.joinmastodon.android.model.DisplayItemsParent; +import org.joinmastodon.android.model.Poll; import org.joinmastodon.android.model.Status; import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.ImageStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.PhotoStatusDisplayItem; +import org.joinmastodon.android.ui.displayitems.PollFooterStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.PollOptionStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.StatusDisplayItem; import org.joinmastodon.android.ui.photoviewer.PhotoViewer; import org.joinmastodon.android.ui.photoviewer.PhotoViewerHost; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.stream.Collectors; import androidx.annotation.NonNull; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import me.grishka.appkit.api.Callback; +import me.grishka.appkit.api.ErrorResponse; import me.grishka.appkit.fragments.BaseRecyclerFragment; import me.grishka.appkit.imageloader.ImageLoaderRecyclerAdapter; import me.grishka.appkit.imageloader.ImageLoaderViewHolder; @@ -334,11 +341,86 @@ public abstract class BaseStatusListFragment exten return 0; } - public void onItemClick(String id){ + public abstract void onItemClick(String id); + protected void updatePoll(String itemID, Poll poll){ + int firstOptionIndex=-1, footerIndex=-1; + int i=0; + for(StatusDisplayItem item:displayItems){ + if(item.parentID.equals(itemID)){ + if(item instanceof PollOptionStatusDisplayItem && firstOptionIndex==-1){ + firstOptionIndex=i; + }else if(item instanceof PollFooterStatusDisplayItem){ + footerIndex=i; + break; + } + } + i++; + } + if(firstOptionIndex==-1 || footerIndex==-1) + throw new IllegalStateException("Can't find all poll items in displayItems"); + List pollItems=displayItems.subList(firstOptionIndex, footerIndex+1); + int prevSize=pollItems.size(); + pollItems.clear(); + StatusDisplayItem.buildPollItems(itemID, this, poll, pollItems); + if(prevSize!=pollItems.size()){ + adapter.notifyItemRangeRemoved(firstOptionIndex, prevSize); + adapter.notifyItemRangeInserted(firstOptionIndex, pollItems.size()); + }else{ + adapter.notifyItemRangeChanged(firstOptionIndex, pollItems.size()); + } } public void onPollOptionClick(PollOptionStatusDisplayItem.Holder holder){ + Poll poll=holder.getItem().poll; + Poll.Option option=holder.getItem().option; + if(poll.multiple){ + if(poll.selectedOptions==null) + poll.selectedOptions=new ArrayList<>(); + if(poll.selectedOptions.contains(option)){ + poll.selectedOptions.remove(option); + holder.itemView.setSelected(false); + }else{ + poll.selectedOptions.add(option); + holder.itemView.setSelected(true); + } + for(int i=0;ipoll.options.indexOf(opt)).collect(Collectors.toList())); + } + + protected void submitPollVote(String parentID, String pollID, List choices){ + if(refreshing) + return; + new SubmitPollVote(pollID, choices) + .setCallback(new Callback<>(){ + @Override + public void onSuccess(Poll result){ + updatePoll(parentID, result); + } + + @Override + public void onError(ErrorResponse error){ + error.showToast(getActivity()); + } + }) + .wrapProgress(getActivity(), R.string.loading, false) + .exec(accountID); } protected class DisplayItemsAdapter extends UsableRecyclerView.Adapter> implements ImageLoaderRecyclerAdapter{ diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsFragment.java index 2db0c96b..08a448c2 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsFragment.java @@ -5,6 +5,7 @@ import android.app.Activity; import org.joinmastodon.android.R; import org.joinmastodon.android.api.requests.notifications.GetNotifications; import org.joinmastodon.android.model.Notification; +import org.joinmastodon.android.model.Poll; import org.joinmastodon.android.ui.displayitems.ReblogOrReplyLineStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.StatusDisplayItem; @@ -67,4 +68,26 @@ public class NotificationsFragment extends BaseStatusListFragment{ if(!getArguments().getBoolean("noAutoLoad") && !loaded && !dataLoading) loadData(); } + + @Override + public void onItemClick(String id){ + + } + + @Override + protected void updatePoll(String itemID, Poll poll){ + Notification notification=getNotificationByID(itemID); + if(notification==null || notification.status==null) + return; + notification.status.poll=poll; + super.updatePoll(itemID, poll); + } + + private Notification getNotificationByID(String id){ + for(Notification n:data){ + if(n.id.equals(id)) + return n; + } + return null; + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java index f365ff20..b8d3209c 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java @@ -6,8 +6,11 @@ import com.squareup.otto.Subscribe; import org.joinmastodon.android.E; import org.joinmastodon.android.events.StatusCountersUpdatedEvent; +import org.joinmastodon.android.model.Poll; import org.joinmastodon.android.model.Status; import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem; +import org.joinmastodon.android.ui.displayitems.PollFooterStatusDisplayItem; +import org.joinmastodon.android.ui.displayitems.PollOptionStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.StatusDisplayItem; import org.parceler.Parcels; @@ -41,13 +44,7 @@ public abstract class StatusListFragment extends BaseStatusListFragment{ @Override public void onItemClick(String id){ - Status status=null; - for(Status s:data){ - if(s.id.equals(id)){ - status=s.getContentStatus(); - break; - } - } + Status status=getContentStatusByID(id); if(status==null) return; Bundle args=new Bundle(); @@ -58,6 +55,15 @@ public abstract class StatusListFragment extends BaseStatusListFragment{ Nav.go(getActivity(), ThreadFragment.class, args); } + @Override + protected void updatePoll(String itemID, Poll poll){ + Status status=getContentStatusByID(itemID); + if(status==null) + return; + status.poll=poll; + super.updatePoll(itemID, poll); + } + @Subscribe public void onStatusCountersUpdated(StatusCountersUpdatedEvent ev){ for(Status s:data){ @@ -80,4 +86,13 @@ public abstract class StatusListFragment extends BaseStatusListFragment{ } } } + + protected Status getContentStatusByID(String id){ + for(Status s:data){ + if(s.id.equals(id)){ + return s.getContentStatus(); + } + } + return null; + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/Poll.java b/mastodon/src/main/java/org/joinmastodon/android/model/Poll.java index a8fb5214..bdd2e262 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/model/Poll.java +++ b/mastodon/src/main/java/org/joinmastodon/android/model/Poll.java @@ -5,6 +5,7 @@ import org.joinmastodon.android.api.ObjectValidationException; import org.parceler.Parcel; import java.time.Instant; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -21,6 +22,8 @@ public class Poll extends BaseModel{ public List