Post redesign part 2 (AND-18)
This commit is contained in:
parent
3820eee174
commit
ace0072118
13 changed files with 222 additions and 109 deletions
|
@ -30,8 +30,6 @@ import org.joinmastodon.android.model.Translation;
|
||||||
import org.joinmastodon.android.ui.BetterItemAnimator;
|
import org.joinmastodon.android.ui.BetterItemAnimator;
|
||||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||||
import org.joinmastodon.android.ui.PhotoLayoutHelper;
|
import org.joinmastodon.android.ui.PhotoLayoutHelper;
|
||||||
import org.joinmastodon.android.ui.sheets.NonMutualPreReplySheet;
|
|
||||||
import org.joinmastodon.android.ui.sheets.OldPostPreReplySheet;
|
|
||||||
import org.joinmastodon.android.ui.displayitems.AccountStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.AccountStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.GapStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.GapStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.HashtagStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.HashtagStatusDisplayItem;
|
||||||
|
@ -43,6 +41,8 @@ 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.photoviewer.PhotoViewer;
|
import org.joinmastodon.android.ui.photoviewer.PhotoViewer;
|
||||||
import org.joinmastodon.android.ui.photoviewer.PhotoViewerHost;
|
import org.joinmastodon.android.ui.photoviewer.PhotoViewerHost;
|
||||||
|
import org.joinmastodon.android.ui.sheets.NonMutualPreReplySheet;
|
||||||
|
import org.joinmastodon.android.ui.sheets.OldPostPreReplySheet;
|
||||||
import org.joinmastodon.android.ui.utils.MediaAttachmentViewController;
|
import org.joinmastodon.android.ui.utils.MediaAttachmentViewController;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
import org.joinmastodon.android.ui.views.MediaGridLayout;
|
import org.joinmastodon.android.ui.views.MediaGridLayout;
|
||||||
|
@ -51,7 +51,6 @@ import org.joinmastodon.android.utils.TypedObjectPool;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -362,6 +361,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, Status status, Poll poll){
|
protected void updatePoll(String itemID, Status status, Poll poll){
|
||||||
|
if(status.poll!=poll)
|
||||||
status.poll=poll;
|
status.poll=poll;
|
||||||
int firstOptionIndex=-1, footerIndex=-1;
|
int firstOptionIndex=-1, footerIndex=-1;
|
||||||
int i=0;
|
int i=0;
|
||||||
|
@ -393,16 +393,33 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||||
public void onPollOptionClick(PollOptionStatusDisplayItem.Holder holder){
|
public void onPollOptionClick(PollOptionStatusDisplayItem.Holder holder){
|
||||||
Poll poll=holder.getItem().poll;
|
Poll poll=holder.getItem().poll;
|
||||||
Poll.Option option=holder.getItem().option;
|
Poll.Option option=holder.getItem().option;
|
||||||
if(poll.multiple){
|
|
||||||
if(poll.selectedOptions==null)
|
if(poll.selectedOptions==null)
|
||||||
poll.selectedOptions=new ArrayList<>();
|
poll.selectedOptions=new ArrayList<>();
|
||||||
|
if(poll.multiple){
|
||||||
if(poll.selectedOptions.contains(option)){
|
if(poll.selectedOptions.contains(option)){
|
||||||
poll.selectedOptions.remove(option);
|
poll.selectedOptions.remove(option);
|
||||||
holder.itemView.setSelected(false);
|
|
||||||
}else{
|
}else{
|
||||||
poll.selectedOptions.add(option);
|
poll.selectedOptions.add(option);
|
||||||
holder.itemView.setSelected(true);
|
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
if(poll.selectedOptions.contains(option))
|
||||||
|
return;
|
||||||
|
if(!poll.selectedOptions.isEmpty()){
|
||||||
|
Poll.Option previouslySelected=poll.selectedOptions.get(0);
|
||||||
|
poll.selectedOptions.clear();
|
||||||
|
for(int i=0;i<list.getChildCount();i++){
|
||||||
|
RecyclerView.ViewHolder vh=list.getChildViewHolder(list.getChildAt(i));
|
||||||
|
if(vh instanceof PollOptionStatusDisplayItem.Holder otherOption){
|
||||||
|
if(otherOption.getItemID().equals(holder.getItemID()) && otherOption.getItem().option==previouslySelected){
|
||||||
|
otherOption.updateCheckedState();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
poll.selectedOptions.add(option);
|
||||||
|
}
|
||||||
|
holder.updateCheckedState();
|
||||||
for(int i=0;i<list.getChildCount();i++){
|
for(int i=0;i<list.getChildCount();i++){
|
||||||
RecyclerView.ViewHolder vh=list.getChildViewHolder(list.getChildAt(i));
|
RecyclerView.ViewHolder vh=list.getChildViewHolder(list.getChildAt(i));
|
||||||
if(vh instanceof PollFooterStatusDisplayItem.Holder footer){
|
if(vh instanceof PollFooterStatusDisplayItem.Holder footer){
|
||||||
|
@ -412,9 +429,32 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
submitPollVote(holder.getItemID(), poll.id, Collections.singletonList(poll.options.indexOf(option)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onPollToggleResultsClick(PollFooterStatusDisplayItem.Holder holder){
|
||||||
|
Status status=holder.getItem().status.getContentStatus();
|
||||||
|
status.poll.showResults=!status.poll.showResults;
|
||||||
|
String itemID=holder.getItemID();
|
||||||
|
if(status.poll.selectedOptions!=null)
|
||||||
|
status.poll.selectedOptions.clear();
|
||||||
|
int firstOptionIndex=-1, footerIndex=-1;
|
||||||
|
int i=0;
|
||||||
|
for(StatusDisplayItem item:displayItems){
|
||||||
|
if(item.parentID.equals(itemID)){
|
||||||
|
if(item instanceof PollOptionStatusDisplayItem optItem){
|
||||||
|
if(firstOptionIndex==-1)
|
||||||
|
firstOptionIndex=i;
|
||||||
|
optItem.showResults=status.poll.showResults;
|
||||||
|
}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");
|
||||||
|
adapter.notifyItemRangeChanged(firstOptionIndex, status.poll.options.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPollVoteButtonClick(PollFooterStatusDisplayItem.Holder holder){
|
public void onPollVoteButtonClick(PollFooterStatusDisplayItem.Holder holder){
|
||||||
|
|
|
@ -26,12 +26,14 @@ public class Poll extends BaseModel{
|
||||||
public List<Emoji> emojis;
|
public List<Emoji> emojis;
|
||||||
|
|
||||||
public transient ArrayList<Option> selectedOptions;
|
public transient ArrayList<Option> selectedOptions;
|
||||||
|
public transient boolean showResults;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postprocess() throws ObjectValidationException{
|
public void postprocess() throws ObjectValidationException{
|
||||||
super.postprocess();
|
super.postprocess();
|
||||||
for(Emoji e:emojis)
|
for(Emoji e:emojis)
|
||||||
e.postprocess();
|
e.postprocess();
|
||||||
|
showResults=voted || isExpired();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -9,14 +9,19 @@ import android.widget.TextView;
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||||
import org.joinmastodon.android.model.Poll;
|
import org.joinmastodon.android.model.Poll;
|
||||||
|
import org.joinmastodon.android.model.Status;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
|
|
||||||
|
import me.grishka.appkit.utils.V;
|
||||||
|
|
||||||
public class PollFooterStatusDisplayItem extends StatusDisplayItem{
|
public class PollFooterStatusDisplayItem extends StatusDisplayItem{
|
||||||
public final Poll poll;
|
public final Poll poll;
|
||||||
|
public final Status status;
|
||||||
|
|
||||||
public PollFooterStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Poll poll){
|
public PollFooterStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Poll poll, Status status){
|
||||||
super(parentID, parentFragment);
|
super(parentID, parentFragment);
|
||||||
this.poll=poll;
|
this.poll=poll;
|
||||||
|
this.status=status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,18 +30,24 @@ public class PollFooterStatusDisplayItem extends StatusDisplayItem{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Holder extends StatusDisplayItem.Holder<PollFooterStatusDisplayItem>{
|
public static class Holder extends StatusDisplayItem.Holder<PollFooterStatusDisplayItem>{
|
||||||
private TextView text;
|
private final TextView text;
|
||||||
private Button button;
|
private final Button voteButton, toggleResultsButton;
|
||||||
|
|
||||||
public Holder(Activity activity, ViewGroup parent){
|
public Holder(Activity activity, ViewGroup parent){
|
||||||
super(activity, R.layout.display_item_poll_footer, parent);
|
super(activity, R.layout.display_item_poll_footer, parent);
|
||||||
text=findViewById(R.id.text);
|
text=findViewById(R.id.text);
|
||||||
button=findViewById(R.id.vote_btn);
|
voteButton=findViewById(R.id.vote_btn);
|
||||||
button.setOnClickListener(v->item.parentFragment.onPollVoteButtonClick(this));
|
toggleResultsButton=findViewById(R.id.show_results_btn);
|
||||||
|
voteButton.setOnClickListener(v->item.parentFragment.onPollVoteButtonClick(this));
|
||||||
|
toggleResultsButton.setOnClickListener(v->{
|
||||||
|
item.parentFragment.onPollToggleResultsClick(this);
|
||||||
|
rebind();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBind(PollFooterStatusDisplayItem item){
|
public void onBind(PollFooterStatusDisplayItem item){
|
||||||
|
itemView.setPaddingRelative(V.dp(item.fullWidth ? 16 : 64), itemView.getPaddingTop(), itemView.getPaddingEnd(), itemView.getPaddingBottom());
|
||||||
String text=item.parentFragment.getResources().getQuantityString(R.plurals.x_votes, item.poll.votesCount, item.poll.votesCount);
|
String text=item.parentFragment.getResources().getQuantityString(R.plurals.x_votes, item.poll.votesCount, item.poll.votesCount);
|
||||||
if(item.poll.expiresAt!=null && !item.poll.isExpired()){
|
if(item.poll.expiresAt!=null && !item.poll.isExpired()){
|
||||||
text+=" · "+UiUtils.formatTimeLeft(itemView.getContext(), item.poll.expiresAt);
|
text+=" · "+UiUtils.formatTimeLeft(itemView.getContext(), item.poll.expiresAt);
|
||||||
|
@ -46,8 +57,9 @@ public class PollFooterStatusDisplayItem extends StatusDisplayItem{
|
||||||
text+=" · "+item.parentFragment.getString(R.string.poll_closed);
|
text+=" · "+item.parentFragment.getString(R.string.poll_closed);
|
||||||
}
|
}
|
||||||
this.text.setText(text);
|
this.text.setText(text);
|
||||||
button.setVisibility(item.poll.isExpired() || item.poll.voted || !item.poll.multiple ? View.GONE : View.VISIBLE);
|
voteButton.setEnabled(item.poll.selectedOptions!=null && !item.poll.selectedOptions.isEmpty() && !item.poll.isExpired() && !item.poll.voted);
|
||||||
button.setEnabled(item.poll.selectedOptions!=null && !item.poll.selectedOptions.isEmpty());
|
toggleResultsButton.setVisibility(item.poll.isExpired() || item.poll.voted ? View.GONE : View.VISIBLE);
|
||||||
|
toggleResultsButton.setText(item.poll.showResults ? R.string.poll_hide_results : R.string.poll_see_results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,38 @@
|
||||||
package org.joinmastodon.android.ui.displayitems;
|
package org.joinmastodon.android.ui.displayitems;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.graphics.LinearGradient;
|
||||||
|
import android.graphics.Matrix;
|
||||||
|
import android.graphics.Shader;
|
||||||
import android.graphics.drawable.Animatable;
|
import android.graphics.drawable.Animatable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.RadioButton;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||||
import org.joinmastodon.android.model.Poll;
|
import org.joinmastodon.android.model.Poll;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
import org.joinmastodon.android.ui.OutlineProviders;
|
|
||||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||||
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
|
import org.joinmastodon.android.ui.views.CheckableLinearLayout;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
||||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||||
|
import me.grishka.appkit.utils.V;
|
||||||
|
|
||||||
public class PollOptionStatusDisplayItem extends StatusDisplayItem{
|
public class PollOptionStatusDisplayItem extends StatusDisplayItem{
|
||||||
private CharSequence text;
|
private CharSequence text;
|
||||||
private CharSequence translatedText;
|
private CharSequence translatedText;
|
||||||
public final Poll.Option option;
|
public final Poll.Option option;
|
||||||
private CustomEmojiHelper emojiHelper=new CustomEmojiHelper();
|
private CustomEmojiHelper emojiHelper=new CustomEmojiHelper();
|
||||||
private boolean showResults;
|
public boolean showResults;
|
||||||
private float votesFraction; // 0..1
|
private float votesFraction; // 0..1
|
||||||
private boolean isMostVoted;
|
private boolean isMostVoted;
|
||||||
private final int optionIndex;
|
private final int optionIndex;
|
||||||
|
@ -42,9 +48,9 @@ public class PollOptionStatusDisplayItem extends StatusDisplayItem{
|
||||||
this.status=status;
|
this.status=status;
|
||||||
text=HtmlParser.parseCustomEmoji(option.title, poll.emojis);
|
text=HtmlParser.parseCustomEmoji(option.title, poll.emojis);
|
||||||
emojiHelper.setText(text);
|
emojiHelper.setText(text);
|
||||||
showResults=poll.isExpired() || poll.voted;
|
showResults=poll.showResults;
|
||||||
int total=poll.votersCount>0 ? poll.votersCount : poll.votesCount;
|
int total=poll.votersCount>0 ? poll.votersCount : poll.votesCount;
|
||||||
if(showResults && option.votesCount!=null && total>0){
|
if(option.votesCount!=null && total>0){
|
||||||
votesFraction=(float)option.votesCount/(float)total;
|
votesFraction=(float)option.votesCount/(float)total;
|
||||||
int mostVotedCount=0;
|
int mostVotedCount=0;
|
||||||
for(Poll.Option opt:poll.options)
|
for(Poll.Option opt:poll.options)
|
||||||
|
@ -70,8 +76,11 @@ public class PollOptionStatusDisplayItem extends StatusDisplayItem{
|
||||||
|
|
||||||
public static class Holder extends StatusDisplayItem.Holder<PollOptionStatusDisplayItem> implements ImageLoaderViewHolder{
|
public static class Holder extends StatusDisplayItem.Holder<PollOptionStatusDisplayItem> implements ImageLoaderViewHolder{
|
||||||
private final TextView text, percent;
|
private final TextView text, percent;
|
||||||
private final View check, button;
|
private final View check;
|
||||||
private final Drawable progressBg;
|
private final Drawable progressBg;
|
||||||
|
private final Drawable checkboxIcon, radioIcon;
|
||||||
|
private final CheckableLinearLayout button;
|
||||||
|
private LinearGradient textShader, percentShader;
|
||||||
|
|
||||||
public Holder(Activity activity, ViewGroup parent){
|
public Holder(Activity activity, ViewGroup parent){
|
||||||
super(activity, R.layout.display_item_poll_option, parent);
|
super(activity, R.layout.display_item_poll_option, parent);
|
||||||
|
@ -81,12 +90,26 @@ public class PollOptionStatusDisplayItem extends StatusDisplayItem{
|
||||||
button=findViewById(R.id.button);
|
button=findViewById(R.id.button);
|
||||||
progressBg=activity.getResources().getDrawable(R.drawable.bg_poll_option_voted, activity.getTheme()).mutate();
|
progressBg=activity.getResources().getDrawable(R.drawable.bg_poll_option_voted, activity.getTheme()).mutate();
|
||||||
itemView.setOnClickListener(this::onButtonClick);
|
itemView.setOnClickListener(this::onButtonClick);
|
||||||
button.setOutlineProvider(OutlineProviders.roundedRect(20));
|
|
||||||
button.setClipToOutline(true);
|
checkboxIcon=new CheckBox(activity).getButtonDrawable();
|
||||||
|
radioIcon=new RadioButton(activity).getButtonDrawable();
|
||||||
|
Matrix matrix=new Matrix();
|
||||||
|
button.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom)->{
|
||||||
|
if(textShader!=null){
|
||||||
|
int width=right-left;
|
||||||
|
matrix.setScale(width, 1f, 0f, 0f);
|
||||||
|
matrix.postTranslate(-text.getLeft(), 0);
|
||||||
|
textShader.setLocalMatrix(matrix);
|
||||||
|
matrix.setScale(width, 1f, 0f, 0f);
|
||||||
|
matrix.postTranslate(-percent.getLeft(), 0);
|
||||||
|
percentShader.setLocalMatrix(matrix);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBind(PollOptionStatusDisplayItem item){
|
public void onBind(PollOptionStatusDisplayItem item){
|
||||||
|
itemView.setPaddingRelative(V.dp(item.fullWidth ? 16 : 64), itemView.getPaddingTop(), itemView.getPaddingEnd(), itemView.getPaddingBottom());
|
||||||
if (item.status.translation != null && item.status.translationState == Status.TranslationState.SHOWN) {
|
if (item.status.translation != null && item.status.translationState == Status.TranslationState.SHOWN) {
|
||||||
if(item.translatedText==null){
|
if(item.translatedText==null){
|
||||||
item.translatedText=item.status.translation.poll.options[item.optionIndex].title;
|
item.translatedText=item.status.translation.poll.options[item.optionIndex].title;
|
||||||
|
@ -96,20 +119,39 @@ public class PollOptionStatusDisplayItem extends StatusDisplayItem{
|
||||||
text.setText(item.text);
|
text.setText(item.text);
|
||||||
}
|
}
|
||||||
percent.setVisibility(item.showResults ? View.VISIBLE : View.GONE);
|
percent.setVisibility(item.showResults ? View.VISIBLE : View.GONE);
|
||||||
|
check.setVisibility(item.showResults ? View.GONE : View.VISIBLE);
|
||||||
itemView.setClickable(!item.showResults);
|
itemView.setClickable(!item.showResults);
|
||||||
if(item.showResults){
|
if(item.showResults){
|
||||||
Drawable bg=progressBg;
|
Drawable bg=progressBg;
|
||||||
bg.setLevel(Math.round(10000f*item.votesFraction));
|
int drawableLevel=Math.round(10000f*item.votesFraction);
|
||||||
|
bg.setLevel(drawableLevel);
|
||||||
button.setBackground(bg);
|
button.setBackground(bg);
|
||||||
itemView.setSelected(item.isMostVoted);
|
button.setChecked(item.isMostVoted);
|
||||||
check.setSelected(item.poll.ownVotes!=null && item.poll.ownVotes.contains(item.optionIndex));
|
|
||||||
percent.setText(String.format(Locale.getDefault(), "%d%%", Math.round(item.votesFraction*100f)));
|
percent.setText(String.format(Locale.getDefault(), "%d%%", Math.round(item.votesFraction*100f)));
|
||||||
|
text.setTextColor(UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3Outline));
|
||||||
|
if(item.isMostVoted){
|
||||||
|
int leftColor=UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3OnSurfaceInverse);
|
||||||
|
int rightColor=UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3Outline);
|
||||||
|
text.getPaint().setShader(textShader=new LinearGradient(0, 0, 1, 0, new int[]{leftColor, rightColor}, new float[]{item.votesFraction, item.votesFraction+Float.MIN_VALUE}, Shader.TileMode.CLAMP));
|
||||||
|
percent.getPaint().setShader(percentShader=new LinearGradient(0, 0, 1, 0, new int[]{leftColor, rightColor}, new float[]{item.votesFraction, item.votesFraction+Float.MIN_VALUE}, Shader.TileMode.CLAMP));
|
||||||
}else{
|
}else{
|
||||||
itemView.setSelected(item.poll.selectedOptions!=null && item.poll.selectedOptions.contains(item.option));
|
textShader=percentShader=null;
|
||||||
button.setBackgroundResource(R.drawable.bg_poll_option_clickable);
|
text.getPaint().setShader(null);
|
||||||
|
percent.getPaint().setShader(null);
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
textShader=percentShader=null;
|
||||||
|
text.getPaint().setShader(null);
|
||||||
|
percent.getPaint().setShader(null);
|
||||||
|
button.setBackgroundResource(R.drawable.bg_poll_option_clickable);
|
||||||
|
check.setForeground(item.poll.multiple ? checkboxIcon : radioIcon);
|
||||||
text.setTextColor(UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3Primary));
|
text.setTextColor(UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3Primary));
|
||||||
percent.setTextColor(UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3OnSecondaryContainer));
|
updateCheckedState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateCheckedState(){
|
||||||
|
button.setChecked(item.poll.selectedOptions!=null && item.poll.selectedOptions.contains(item.option));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -202,7 +202,7 @@ public abstract class StatusDisplayItem{
|
||||||
items.add(new PollOptionStatusDisplayItem(parentID, poll, i, fragment, status));
|
items.add(new PollOptionStatusDisplayItem(parentID, poll, i, fragment, status));
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
items.add(new PollFooterStatusDisplayItem(parentID, fragment, poll));
|
items.add(new PollFooterStatusDisplayItem(parentID, fragment, poll, status));
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Type{
|
public enum Type{
|
||||||
|
|
5
mastodon/src/main/res/color/poll_option_checkbox.xml
Normal file
5
mastodon/src/main/res/color/poll_option_checkbox.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:color="?colorM3Primary" android:state_checked="true"/>
|
||||||
|
<item android:color="?colorM3Outline"/>
|
||||||
|
</selector>
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<item android:color="?colorM3TertiaryContainer" android:state_selected="true"/>
|
|
||||||
<item android:color="?colorM3SurfaceVariant"/>
|
|
||||||
</selector>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<item android:color="?colorM3OnTertiaryContainer" android:state_selected="true"/>
|
|
||||||
<item android:color="?colorM3OnSurface"/>
|
|
||||||
</selector>
|
|
|
@ -1,15 +1,25 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="?android:colorControlHighlight">
|
<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="?android:colorControlHighlight">
|
||||||
|
<item>
|
||||||
|
<selector android:enterFadeDuration="150" android:exitFadeDuration="150">
|
||||||
|
<item android:state_checked="true">
|
||||||
|
<shape android:tint="?colorM3Primary">
|
||||||
|
<solid android:color="#29000000"/>
|
||||||
|
<corners android:radius="9dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<shape>
|
<shape>
|
||||||
<stroke android:width="1dp" android:color="?colorM3Outline"/>
|
<stroke android:width="0.5dp" android:color="?colorM3OutlineVariant"/>
|
||||||
<corners android:radius="20dp"/>
|
<corners android:radius="8dp"/>
|
||||||
</shape>
|
</shape>
|
||||||
</item>
|
</item>
|
||||||
<item android:id="@android:id/mask">
|
<item android:id="@android:id/mask">
|
||||||
<shape>
|
<shape>
|
||||||
<solid android:color="#000"/>
|
<solid android:color="#000"/>
|
||||||
<corners android:radius="20dp"/>
|
<corners android:radius="8dp"/>
|
||||||
</shape>
|
</shape>
|
||||||
</item>
|
</item>
|
||||||
</ripple>
|
</ripple>
|
|
@ -1,17 +1,27 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item>
|
<item>
|
||||||
<scale android:scaleGravity="start|fill_vertical" android:scaleWidth="100%">
|
<clip>
|
||||||
|
<selector>
|
||||||
|
<item android:state_checked="true">
|
||||||
<shape>
|
<shape>
|
||||||
<solid android:color="?colorM3SecondaryContainer"/>
|
<corners android:radius="9dp"/>
|
||||||
<corners android:radius="20dp"/>
|
<solid android:color="?colorM3SurfaceInverse"/>
|
||||||
</shape>
|
</shape>
|
||||||
</scale>
|
</item>
|
||||||
|
<item>
|
||||||
|
<shape android:tint="?colorM3SurfaceInverse">
|
||||||
|
<corners android:radius="9dp"/>
|
||||||
|
<solid android:color="#29000000"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
|
</clip>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<shape>
|
<shape>
|
||||||
<stroke android:width="1dp" android:color="?colorM3Outline"/>
|
<stroke android:width="0.5dp" android:color="?colorM3OutlineVariant"/>
|
||||||
<corners android:radius="20dp"/>
|
<corners android:radius="8dp"/>
|
||||||
</shape>
|
</shape>
|
||||||
</item>
|
</item>
|
||||||
</layer-list>
|
</layer-list>
|
|
@ -4,29 +4,38 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text"
|
android:id="@+id/text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="20dp"
|
android:layout_height="16dp"
|
||||||
android:paddingLeft="16dp"
|
android:layout_marginBottom="16dp"
|
||||||
android:paddingRight="16dp"
|
android:textAppearance="@style/m3_body_small"
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:textAppearance="@style/m3_body_medium"
|
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:textColor="?colorM3OnSurfaceVariant"
|
android:textColor="?colorM3Outline"
|
||||||
tools:text="fdsafdsafsdafds"/>
|
tools:text="fdsafdsafsdafds"/>
|
||||||
|
|
||||||
<Button
|
<LinearLayout
|
||||||
android:id="@+id/vote_btn"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="16dp"
|
android:orientation="horizontal">
|
||||||
android:layout_marginRight="16dp"
|
<Button
|
||||||
android:layout_marginBottom="8dp"
|
android:id="@+id/vote_btn"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
android:enabled="false"
|
android:enabled="false"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
style="@style/Widget.Mastodon.M3.Button.Filled"
|
style="@style/Widget.Mastodon.M3.Button.Filled"
|
||||||
android:text="@string/action_vote"/>
|
android:text="@string/action_vote"/>
|
||||||
|
<Button
|
||||||
|
android:id="@+id/show_results_btn"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/Widget.Mastodon.M3.Button.Tonal"
|
||||||
|
android:text="@string/poll_see_results"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -3,62 +3,53 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingLeft="16dp"
|
android:paddingEnd="16dp"
|
||||||
android:paddingRight="16dp"
|
|
||||||
android:paddingBottom="8dp"
|
android:paddingBottom="8dp"
|
||||||
android:clipToPadding="false">
|
android:clipToPadding="false">
|
||||||
|
|
||||||
<LinearLayout
|
<org.joinmastodon.android.ui.views.CheckableLinearLayout
|
||||||
android:id="@+id/button"
|
android:id="@+id/button"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="40dp"
|
android:layout_height="44dp"
|
||||||
|
android:paddingHorizontal="12dp"
|
||||||
android:background="@drawable/bg_poll_option_clickable"
|
android:background="@drawable/bg_poll_option_clickable"
|
||||||
android:duplicateParentState="true"
|
|
||||||
android:layoutDirection="locale">
|
android:layoutDirection="locale">
|
||||||
|
|
||||||
<LinearLayout
|
<View
|
||||||
android:layout_width="0dp"
|
android:id="@+id/checkbox"
|
||||||
android:layout_height="match_parent"
|
android:layout_width="36dp"
|
||||||
android:layout_weight="1"
|
android:layout_height="36dp"
|
||||||
android:orientation="horizontal">
|
android:layout_marginStart="-8dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:duplicateParentState="true"
|
||||||
|
android:foregroundGravity="center"
|
||||||
|
android:foregroundTint="@color/poll_option_checkbox"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text"
|
android:id="@+id/text"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:textAppearance="@style/m3_label_large"
|
android:textAppearance="@style/m3_label_large"
|
||||||
android:textColor="?colorM3Primary"
|
android:textColor="?colorM3Primary"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:paddingEnd="26dp"
|
|
||||||
tools:text="scream into void jsfdklfjdalskfjdsalkfjdsalkfjdsalkfdjsalkfdsajlk"/>
|
tools:text="scream into void jsfdklfjdalskfjdsalkfjdsalkfjdsalkfdjsalkfdsajlk"/>
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/checkbox"
|
|
||||||
android:layout_width="18dp"
|
|
||||||
android:layout_height="18dp"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_marginStart="-26dp"
|
|
||||||
android:tint="?colorM3OnSecondaryContainer"
|
|
||||||
android:scaleType="center"
|
|
||||||
android:src="@drawable/ic_poll_check" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/percent"
|
android:id="@+id/percent"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="24dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:textAppearance="@style/m3_label_large"
|
android:textAppearance="@style/m3_label_small"
|
||||||
android:textColor="?colorM3OnSecondaryContainer"
|
android:textColor="?colorM3Outline"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
tools:visibility="visible"
|
tools:visibility="visible"
|
||||||
tools:text="00.0%"/>
|
tools:text="00.0%"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</org.joinmastodon.android.ui.views.CheckableLinearLayout>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
|
@ -778,4 +778,6 @@
|
||||||
<string name="settings_donate">Donate to Mastodon</string>
|
<string name="settings_donate">Donate to Mastodon</string>
|
||||||
<string name="settings_manage_donations">Manage donations</string>
|
<string name="settings_manage_donations">Manage donations</string>
|
||||||
<string name="cant_load_image">Couldn’t load image</string>
|
<string name="cant_load_image">Couldn’t load image</string>
|
||||||
|
<string name="poll_see_results">See results</string>
|
||||||
|
<string name="poll_hide_results">Hide results</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Add table
Reference in a new issue