Update polls throughout the app when voting

This commit is contained in:
Grishka 2022-04-08 00:11:45 +03:00
parent d82616f871
commit cfcd50cb76
9 changed files with 122 additions and 149 deletions

View File

@ -0,0 +1,13 @@
package org.joinmastodon.android.events;
import org.joinmastodon.android.model.Poll;
public class PollUpdatedEvent{
public String accountID;
public Poll poll;
public PollUpdatedEvent(String accountID, Poll poll){
this.accountID=accountID;
this.poll=poll;
}
}

View File

@ -4,14 +4,10 @@ import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import com.squareup.otto.Subscribe;
import org.joinmastodon.android.R; import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.accounts.GetAccountStatuses; import org.joinmastodon.android.api.requests.accounts.GetAccountStatuses;
import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
import org.joinmastodon.android.events.StatusCreatedEvent; import org.joinmastodon.android.events.StatusCreatedEvent;
import org.joinmastodon.android.events.StatusDeletedEvent;
import org.joinmastodon.android.model.Account; import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.Status; import org.joinmastodon.android.model.Status;
import org.parceler.Parcels; import org.parceler.Parcels;
@ -73,20 +69,7 @@ public class AccountTimelineFragment extends StatusListFragment{
loadData(); loadData();
} }
@Override protected void onStatusCreated(StatusCreatedEvent ev){
@Subscribe
public void onStatusCountersUpdated(StatusCountersUpdatedEvent ev){
super.onStatusCountersUpdated(ev);
}
@Override
@Subscribe
public void onStatusDeleted(StatusDeletedEvent ev){
super.onStatusDeleted(ev);
}
@Subscribe
public void onStatusCreated(StatusCreatedEvent ev){
if(!AccountSessionManager.getInstance().isSelf(accountID, ev.status.account)) if(!AccountSessionManager.getInstance().isSelf(accountID, ev.status.account))
return; return;
if(filter==GetAccountStatuses.Filter.DEFAULT){ if(filter==GetAccountStatuses.Filter.DEFAULT){

View File

@ -18,9 +18,11 @@ import android.view.ViewGroup;
import android.view.WindowInsets; import android.view.WindowInsets;
import android.widget.Toolbar; import android.widget.Toolbar;
import org.joinmastodon.android.E;
import org.joinmastodon.android.R; import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships; import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
import org.joinmastodon.android.api.requests.polls.SubmitPollVote; import org.joinmastodon.android.api.requests.polls.SubmitPollVote;
import org.joinmastodon.android.events.PollUpdatedEvent;
import org.joinmastodon.android.model.Account; import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.DisplayItemsParent; import org.joinmastodon.android.model.DisplayItemsParent;
import org.joinmastodon.android.model.Poll; import org.joinmastodon.android.model.Poll;
@ -344,7 +346,7 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
public abstract void onItemClick(String id); public abstract void onItemClick(String id);
protected void updatePoll(String itemID, Poll poll){ protected void updatePoll(String itemID, Status status, Poll poll){
int firstOptionIndex=-1, footerIndex=-1; int firstOptionIndex=-1, footerIndex=-1;
int i=0; int i=0;
for(StatusDisplayItem item:displayItems){ for(StatusDisplayItem item:displayItems){
@ -412,7 +414,7 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
.setCallback(new Callback<>(){ .setCallback(new Callback<>(){
@Override @Override
public void onSuccess(Poll result){ public void onSuccess(Poll result){
updatePoll(parentID, result); E.post(new PollUpdatedEvent(accountID, result));
} }
@Override @Override

View File

@ -1,8 +1,6 @@
package org.joinmastodon.android.fragments; package org.joinmastodon.android.fragments;
import android.app.Activity; import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Bundle; import android.os.Bundle;
@ -11,35 +9,22 @@ 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.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Toolbar; import android.widget.Toolbar;
import com.squareup.otto.Subscribe; import com.squareup.otto.Subscribe;
import org.joinmastodon.android.E;
import org.joinmastodon.android.MainActivity;
import org.joinmastodon.android.R; import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.oauth.RevokeOauthToken;
import org.joinmastodon.android.api.requests.timelines.GetHomeTimeline;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
import org.joinmastodon.android.events.StatusCreatedEvent; import org.joinmastodon.android.events.StatusCreatedEvent;
import org.joinmastodon.android.events.StatusDeletedEvent;
import org.joinmastodon.android.model.Status; import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
import org.joinmastodon.android.ui.utils.UiUtils; import org.joinmastodon.android.ui.utils.UiUtils;
import org.parceler.Parcels;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import me.grishka.appkit.Nav; 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.api.SimpleCallback;
public class HomeTimelineFragment extends StatusListFragment{ public class HomeTimelineFragment extends StatusListFragment{
@ -121,16 +106,4 @@ public class HomeTimelineFragment extends StatusListFragment{
Toolbar toolbar=getToolbar(); Toolbar toolbar=getToolbar();
toolbar.addView(logo, new Toolbar.LayoutParams(Gravity.CENTER)); toolbar.addView(logo, new Toolbar.LayoutParams(Gravity.CENTER));
} }
@Override
@Subscribe
public void onStatusCountersUpdated(StatusCountersUpdatedEvent ev){
super.onStatusCountersUpdated(ev);
}
@Override
@Subscribe
public void onStatusDeleted(StatusDeletedEvent ev){
super.onStatusDeleted(ev);
}
} }

View File

@ -8,8 +8,12 @@ import android.graphics.RectF;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import com.squareup.otto.Subscribe;
import org.joinmastodon.android.E;
import org.joinmastodon.android.R; import org.joinmastodon.android.R;
import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.PollUpdatedEvent;
import org.joinmastodon.android.model.Notification; import org.joinmastodon.android.model.Notification;
import org.joinmastodon.android.model.Poll; import org.joinmastodon.android.model.Poll;
import org.joinmastodon.android.model.Status; import org.joinmastodon.android.model.Status;
@ -37,6 +41,18 @@ import me.grishka.appkit.utils.V;
public class NotificationsListFragment extends BaseStatusListFragment<Notification>{ public class NotificationsListFragment extends BaseStatusListFragment<Notification>{
private boolean onlyMentions; private boolean onlyMentions;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
E.register(this);
}
@Override
public void onDestroy(){
super.onDestroy();
E.unregister(this);
}
@Override @Override
public void onAttach(Activity activity){ public void onAttach(Activity activity){
super.onAttach(activity); super.onAttach(activity);
@ -136,15 +152,6 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
} }
} }
@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);
}
@Override @Override
public void onViewCreated(View view, Bundle savedInstanceState){ public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
@ -241,4 +248,18 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
} }
return null; return null;
} }
@Subscribe
public void onPollUpdated(PollUpdatedEvent ev){
if(!ev.accountID.equals(accountID))
return;
for(Notification ntf:data){
if(ntf.status==null)
continue;
Status contentStatus=ntf.status.getContentStatus();
if(contentStatus.poll!=null && contentStatus.poll.id.equals(ev.poll.id)){
updatePoll(ntf.id, ntf.status, ev.poll);
}
}
}
} }

View File

@ -5,7 +5,9 @@ import android.os.Bundle;
import com.squareup.otto.Subscribe; import com.squareup.otto.Subscribe;
import org.joinmastodon.android.E; import org.joinmastodon.android.E;
import org.joinmastodon.android.events.PollUpdatedEvent;
import org.joinmastodon.android.events.StatusCountersUpdatedEvent; import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
import org.joinmastodon.android.events.StatusCreatedEvent;
import org.joinmastodon.android.events.StatusDeletedEvent; import org.joinmastodon.android.events.StatusDeletedEvent;
import org.joinmastodon.android.model.Poll; import org.joinmastodon.android.model.Poll;
import org.joinmastodon.android.model.Status; import org.joinmastodon.android.model.Status;
@ -20,6 +22,8 @@ import androidx.recyclerview.widget.RecyclerView;
import me.grishka.appkit.Nav; import me.grishka.appkit.Nav;
public abstract class StatusListFragment extends BaseStatusListFragment<Status>{ public abstract class StatusListFragment extends BaseStatusListFragment<Status>{
protected EventListener eventListener=new EventListener();
protected List<StatusDisplayItem> buildDisplayItems(Status s){ protected List<StatusDisplayItem> buildDisplayItems(Status s){
return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, false, true); return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, false, true);
} }
@ -33,13 +37,13 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>{
@Override @Override
public void onCreate(Bundle savedInstanceState){ public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
E.register(this); E.register(eventListener);
} }
@Override @Override
public void onDestroy(){ public void onDestroy(){
super.onDestroy(); super.onDestroy();
E.unregister(this); E.unregister(eventListener);
} }
@Override @Override
@ -55,59 +59,7 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>{
Nav.go(getActivity(), ThreadFragment.class, args); Nav.go(getActivity(), ThreadFragment.class, args);
} }
@Override protected void onStatusCreated(StatusCreatedEvent ev){}
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){
if(s.getContentStatus().id.equals(ev.id)){
s.update(ev);
for(int i=0;i<list.getChildCount();i++){
RecyclerView.ViewHolder holder=list.getChildViewHolder(list.getChildAt(i));
if(holder instanceof FooterStatusDisplayItem.Holder && ((FooterStatusDisplayItem.Holder) holder).getItem().status==s.getContentStatus()){
((FooterStatusDisplayItem.Holder) holder).rebind();
return;
}
}
return;
}
}
for(Status s:preloadedData){
if(s.id.equals(ev.id)){
s.update(ev);
return;
}
}
}
@Subscribe
public void onStatusDeleted(StatusDeletedEvent ev){
if(!ev.accountID.equals(accountID))
return;
Status status=getStatusByID(ev.id);
if(status==null)
return;
data.remove(status);
preloadedData.remove(status);
HeaderStatusDisplayItem item=findItemOfType(ev.id, HeaderStatusDisplayItem.class);
if(item==null)
return;
int index=displayItems.indexOf(item);
int lastIndex;
for(lastIndex=index;lastIndex<displayItems.size();lastIndex++){
if(!displayItems.get(lastIndex).parentID.equals(ev.id))
break;
}
displayItems.subList(index, lastIndex).clear();
adapter.notifyItemRangeRemoved(index, lastIndex-index);
}
protected Status getContentStatusByID(String id){ protected Status getContentStatusByID(String id){
Status s=getStatusByID(id); Status s=getStatusByID(id);
@ -127,4 +79,69 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>{
} }
return null; return null;
} }
public class EventListener{
@Subscribe
public void onStatusCountersUpdated(StatusCountersUpdatedEvent ev){
for(Status s:data){
if(s.getContentStatus().id.equals(ev.id)){
s.update(ev);
for(int i=0;i<list.getChildCount();i++){
RecyclerView.ViewHolder holder=list.getChildViewHolder(list.getChildAt(i));
if(holder instanceof FooterStatusDisplayItem.Holder && ((FooterStatusDisplayItem.Holder) holder).getItem().status==s.getContentStatus()){
((FooterStatusDisplayItem.Holder) holder).rebind();
return;
}
}
return;
}
}
for(Status s:preloadedData){
if(s.id.equals(ev.id)){
s.update(ev);
return;
}
}
}
@Subscribe
public void onStatusDeleted(StatusDeletedEvent ev){
if(!ev.accountID.equals(accountID))
return;
Status status=getStatusByID(ev.id);
if(status==null)
return;
data.remove(status);
preloadedData.remove(status);
HeaderStatusDisplayItem item=findItemOfType(ev.id, HeaderStatusDisplayItem.class);
if(item==null)
return;
int index=displayItems.indexOf(item);
int lastIndex;
for(lastIndex=index;lastIndex<displayItems.size();lastIndex++){
if(!displayItems.get(lastIndex).parentID.equals(ev.id))
break;
}
displayItems.subList(index, lastIndex).clear();
adapter.notifyItemRangeRemoved(index, lastIndex-index);
}
@Subscribe
public void onStatusCreated(StatusCreatedEvent ev){
StatusListFragment.this.onStatusCreated(ev);
}
@Subscribe
public void onPollUpdated(PollUpdatedEvent ev){
if(!ev.accountID.equals(accountID))
return;
for(Status status:data){
Status contentStatus=status.getContentStatus();
if(contentStatus.poll!=null && contentStatus.poll.id.equals(ev.poll.id)){
updatePoll(status.id, status, ev.poll);
}
}
}
}
} }

View File

@ -1,20 +1,14 @@
package org.joinmastodon.android.fragments; package org.joinmastodon.android.fragments;
import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.view.View; import android.view.View;
import com.squareup.otto.Subscribe;
import org.joinmastodon.android.R; import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.statuses.GetStatusContext; import org.joinmastodon.android.api.requests.statuses.GetStatusContext;
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
import org.joinmastodon.android.events.StatusCreatedEvent; import org.joinmastodon.android.events.StatusCreatedEvent;
import org.joinmastodon.android.events.StatusDeletedEvent;
import org.joinmastodon.android.model.Account; import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.StatusContext;
import org.joinmastodon.android.model.Status; import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.model.StatusContext;
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem; import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.TextStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.TextStatusDisplayItem;
import org.joinmastodon.android.ui.text.HtmlParser; import org.joinmastodon.android.ui.text.HtmlParser;
@ -102,20 +96,7 @@ public class ThreadFragment extends StatusListFragment{
footerProgress.setVisibility(View.VISIBLE); footerProgress.setVisibility(View.VISIBLE);
} }
@Override protected void onStatusCreated(StatusCreatedEvent ev){
@Subscribe
public void onStatusCountersUpdated(StatusCountersUpdatedEvent ev){
super.onStatusCountersUpdated(ev);
}
@Override
@Subscribe
public void onStatusDeleted(StatusDeletedEvent ev){
super.onStatusDeleted(ev);
}
@Subscribe
public void onStatusCreated(StatusCreatedEvent ev){
if(ev.status.inReplyToId!=null && getStatusByID(ev.status.inReplyToId)!=null){ if(ev.status.inReplyToId!=null && getStatusByID(ev.status.inReplyToId)!=null){
onAppendItems(Collections.singletonList(ev.status)); onAppendItems(Collections.singletonList(ev.status));
} }

View File

@ -1,10 +1,6 @@
package org.joinmastodon.android.fragments.discover; package org.joinmastodon.android.fragments.discover;
import com.squareup.otto.Subscribe;
import org.joinmastodon.android.api.requests.trends.GetTrendingStatuses; import org.joinmastodon.android.api.requests.trends.GetTrendingStatuses;
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
import org.joinmastodon.android.events.StatusDeletedEvent;
import org.joinmastodon.android.fragments.StatusListFragment; import org.joinmastodon.android.fragments.StatusListFragment;
import org.joinmastodon.android.model.Status; import org.joinmastodon.android.model.Status;
@ -23,16 +19,4 @@ public class DiscoverPostsFragment extends StatusListFragment{
} }
}).exec(accountID); }).exec(accountID);
} }
@Override
@Subscribe
public void onStatusCountersUpdated(StatusCountersUpdatedEvent ev){
super.onStatusCountersUpdated(ev);
}
@Override
@Subscribe
public void onStatusDeleted(StatusDeletedEvent ev){
super.onStatusDeleted(ev);
}
} }

View File

@ -1,7 +1,6 @@
package org.joinmastodon.android.ui.displayitems; package org.joinmastodon.android.ui.displayitems;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;