Post redesign part 2 (AND-18)

This commit is contained in:
Grishka 2024-09-18 03:57:11 +03:00
parent 3820eee174
commit ace0072118
13 changed files with 222 additions and 109 deletions

View File

@ -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,7 +361,8 @@ 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){
status.poll=poll; if(status.poll!=poll)
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){
@ -393,28 +393,68 @@ 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.selectedOptions==null)
poll.selectedOptions=new ArrayList<>();
if(poll.multiple){ if(poll.multiple){
if(poll.selectedOptions==null)
poll.selectedOptions=new ArrayList<>();
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);
} }
for(int i=0;i<list.getChildCount();i++){ }else{
RecyclerView.ViewHolder vh=list.getChildViewHolder(list.getChildAt(i)); if(poll.selectedOptions.contains(option))
if(vh instanceof PollFooterStatusDisplayItem.Holder footer){ return;
if(footer.getItemID().equals(holder.getItemID())){ if(!poll.selectedOptions.isEmpty()){
footer.rebind(); Poll.Option previouslySelected=poll.selectedOptions.get(0);
break; 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;
}
} }
} }
} }
}else{ poll.selectedOptions.add(option);
submitPollVote(holder.getItemID(), poll.id, Collections.singletonList(poll.options.indexOf(option)));
} }
holder.updateCheckedState();
for(int i=0;i<list.getChildCount();i++){
RecyclerView.ViewHolder vh=list.getChildViewHolder(list.getChildAt(i));
if(vh instanceof PollFooterStatusDisplayItem.Holder footer){
if(footer.getItemID().equals(holder.getItemID())){
footer.rebind();
break;
}
}
}
}
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){

View File

@ -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

View File

@ -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);
} }
} }
} }

View File

@ -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{
textShader=percentShader=null;
text.getPaint().setShader(null);
percent.getPaint().setShader(null);
}
}else{ }else{
itemView.setSelected(item.poll.selectedOptions!=null && item.poll.selectedOptions.contains(item.option)); textShader=percentShader=null;
text.getPaint().setShader(null);
percent.getPaint().setShader(null);
button.setBackgroundResource(R.drawable.bg_poll_option_clickable); button.setBackgroundResource(R.drawable.bg_poll_option_clickable);
check.setForeground(item.poll.multiple ? checkboxIcon : radioIcon);
text.setTextColor(UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3Primary));
updateCheckedState();
} }
text.setTextColor(UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3Primary)); }
percent.setTextColor(UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3OnSecondaryContainer));
public void updateCheckedState(){
button.setChecked(item.poll.selectedOptions!=null && item.poll.selectedOptions.contains(item.option));
} }
@Override @Override

View File

@ -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{

View 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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>
<shape> <selector>
<solid android:color="?colorM3SecondaryContainer"/> <item android:state_checked="true">
<corners android:radius="20dp"/> <shape>
</shape> <corners android:radius="9dp"/>
</scale> <solid android:color="?colorM3SurfaceInverse"/>
</shape>
</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>

View File

@ -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:enabled="false" android:layout_width="0dp"
style="@style/Widget.Mastodon.M3.Button.Filled" android:layout_height="wrap_content"
android:text="@string/action_vote"/> android:layout_weight="1"
android:enabled="false"
android:layout_marginEnd="8dp"
style="@style/Widget.Mastodon.M3.Button.Filled"
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>

View File

@ -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"
<TextView android:layout_gravity="center_vertical"
android:id="@+id/text" android:duplicateParentState="true"
android:layout_width="wrap_content" android:foregroundGravity="center"
android:layout_height="wrap_content" android:foregroundTint="@color/poll_option_checkbox"/>
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:textAppearance="@style/m3_label_large"
android:textColor="?colorM3Primary"
android:singleLine="true"
android:ellipsize="end"
android:paddingEnd="26dp"
tools:text="scream into void jsfdklfjdalskfjdsalkfjdsalkfjdsalkfdjsalkfdsajlk"/>
<ImageView <TextView
android:id="@+id/checkbox" android:id="@+id/text"
android:layout_width="18dp" android:layout_width="0dp"
android:layout_height="18dp" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_weight="1"
android:layout_marginStart="-26dp" android:layout_gravity="center_vertical"
android:tint="?colorM3OnSecondaryContainer" android:textAppearance="@style/m3_label_large"
android:scaleType="center" android:textColor="?colorM3Primary"
android:src="@drawable/ic_poll_check" /> android:singleLine="true"
</LinearLayout> android:ellipsize="end"
tools:text="scream into void jsfdklfjdalskfjdsalkfjdsalkfjdsalkfdjsalkfdsajlk"/>
<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>

View File

@ -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">Couldnt load image</string> <string name="cant_load_image">Couldnt load image</string>
<string name="poll_see_results">See results</string>
<string name="poll_hide_results">Hide results</string>
</resources> </resources>