Post redesign part 1
This commit is contained in:
parent
192c634755
commit
3820eee174
35 changed files with 217 additions and 262 deletions
|
@ -9,14 +9,12 @@ import org.joinmastodon.android.model.Notification;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
import org.joinmastodon.android.ui.displayitems.NotificationHeaderStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.NotificationHeaderStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.utils.InsetStatusItemDecoration;
|
|
||||||
import org.parceler.Parcels;
|
import org.parceler.Parcels;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
import me.grishka.appkit.Nav;
|
import me.grishka.appkit.Nav;
|
||||||
|
|
||||||
public abstract class BaseNotificationsListFragment extends BaseStatusListFragment<Notification>{
|
public abstract class BaseNotificationsListFragment extends BaseStatusListFragment<Notification>{
|
||||||
|
@ -36,7 +34,8 @@ public abstract class BaseNotificationsListFragment extends BaseStatusListFragme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(n.status!=null){
|
if(n.status!=null){
|
||||||
int flags=titleItem==null ? 0 : (StatusDisplayItem.FLAG_NO_FOOTER | StatusDisplayItem.FLAG_INSET | StatusDisplayItem.FLAG_NO_HEADER);
|
// TODO
|
||||||
|
int flags=titleItem==null ? 0 : (StatusDisplayItem.FLAG_NO_FOOTER | StatusDisplayItem.FLAG_NO_HEADER);
|
||||||
ArrayList<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, n.status, accountID, n, knownAccounts, flags);
|
ArrayList<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, n.status, accountID, n, knownAccounts, flags);
|
||||||
if(titleItem!=null)
|
if(titleItem!=null)
|
||||||
items.add(0, titleItem);
|
items.add(0, titleItem);
|
||||||
|
@ -111,10 +110,4 @@ public abstract class BaseNotificationsListFragment extends BaseStatusListFragme
|
||||||
endMark.setVisibility(View.GONE);
|
endMark.setVisibility(View.GONE);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(View view, Bundle savedInstanceState){
|
|
||||||
super.onViewCreated(view, savedInstanceState);
|
|
||||||
list.addItemDecoration(new InsetStatusItemDecoration(this));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.joinmastodon.android.model.Status;
|
||||||
import org.joinmastodon.android.model.Translation;
|
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.sheets.NonMutualPreReplySheet;
|
import org.joinmastodon.android.ui.sheets.NonMutualPreReplySheet;
|
||||||
import org.joinmastodon.android.ui.sheets.OldPostPreReplySheet;
|
import org.joinmastodon.android.ui.sheets.OldPostPreReplySheet;
|
||||||
import org.joinmastodon.android.ui.displayitems.AccountStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.AccountStatusDisplayItem;
|
||||||
|
@ -44,6 +45,7 @@ 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.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.utils.TypedObjectPool;
|
import org.joinmastodon.android.utils.TypedObjectPool;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
@ -207,6 +209,15 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||||
list.setClipChildren(false);
|
list.setClipChildren(false);
|
||||||
gridHolder.setClipChildren(false);
|
gridHolder.setClipChildren(false);
|
||||||
transitioningHolder.view.setElevation(1f);
|
transitioningHolder.view.setElevation(1f);
|
||||||
|
int cornerMask=((MediaGridLayout.LayoutParams)holder.view.getLayoutParams()).tile.getRoundCornersMask();
|
||||||
|
if((cornerMask & PhotoLayoutHelper.CORNER_TL)!=0)
|
||||||
|
outCornerRadius[0]=V.dp(8);
|
||||||
|
if((cornerMask & PhotoLayoutHelper.CORNER_TR)!=0)
|
||||||
|
outCornerRadius[1]=V.dp(8);
|
||||||
|
if((cornerMask & PhotoLayoutHelper.CORNER_BR)!=0)
|
||||||
|
outCornerRadius[2]=V.dp(8);
|
||||||
|
if((cornerMask & PhotoLayoutHelper.CORNER_BL)!=0)
|
||||||
|
outCornerRadius[3]=V.dp(8);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -34,7 +34,6 @@ import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||||
import org.joinmastodon.android.ui.OutlineProviders;
|
import org.joinmastodon.android.ui.OutlineProviders;
|
||||||
import org.joinmastodon.android.ui.adapters.GenericListItemsAdapter;
|
import org.joinmastodon.android.ui.adapters.GenericListItemsAdapter;
|
||||||
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.utils.InsetStatusItemDecoration;
|
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
import org.joinmastodon.android.ui.viewcontrollers.GenericListItemsViewController;
|
import org.joinmastodon.android.ui.viewcontrollers.GenericListItemsViewController;
|
||||||
import org.joinmastodon.android.ui.views.NestedRecyclerScrollView;
|
import org.joinmastodon.android.ui.views.NestedRecyclerScrollView;
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class ProfileFeaturedFragment extends BaseStatusListFragment<SearchResult
|
||||||
ArrayList<StatusDisplayItem> items=switch(s.type){
|
ArrayList<StatusDisplayItem> items=switch(s.type){
|
||||||
case ACCOUNT -> new ArrayList<>(Collections.singletonList(new AccountStatusDisplayItem(s.id, this, s.account)));
|
case ACCOUNT -> new ArrayList<>(Collections.singletonList(new AccountStatusDisplayItem(s.id, this, s.account)));
|
||||||
case HASHTAG -> new ArrayList<>(Collections.singletonList(new HashtagStatusDisplayItem(s.id, this, s.hashtag)));
|
case HASHTAG -> new ArrayList<>(Collections.singletonList(new HashtagStatusDisplayItem(s.id, this, s.hashtag)));
|
||||||
case STATUS -> StatusDisplayItem.buildItems(this, s.status, accountID, s, knownAccounts, false, true);
|
case STATUS -> StatusDisplayItem.buildItems(this, s.status, accountID, s, knownAccounts, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
if(s.firstInSection){
|
if(s.firstInSection){
|
||||||
|
|
|
@ -2,14 +2,12 @@ package org.joinmastodon.android.fragments;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.api.requests.statuses.GetStatusEditHistory;
|
import org.joinmastodon.android.api.requests.statuses.GetStatusEditHistory;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
import org.joinmastodon.android.ui.displayitems.ReblogOrReplyLineStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.ReblogOrReplyLineStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.utils.InsetStatusItemDecoration;
|
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
|
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
|
@ -54,7 +52,7 @@ public class StatusEditHistoryFragment extends StatusListFragment{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
||||||
List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, true, false);
|
List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, false);
|
||||||
int idx=data.indexOf(s);
|
int idx=data.indexOf(s);
|
||||||
if(idx>=0){
|
if(idx>=0){
|
||||||
String date=UiUtils.DATE_TIME_FORMATTER.format(s.createdAt.atZone(ZoneId.systemDefault()));
|
String date=UiUtils.DATE_TIME_FORMATTER.format(s.createdAt.atZone(ZoneId.systemDefault()));
|
||||||
|
@ -144,12 +142,6 @@ public class StatusEditHistoryFragment extends StatusListFragment{
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(View view, Bundle savedInstanceState){
|
|
||||||
super.onViewCreated(view, savedInstanceState);
|
|
||||||
list.addItemDecoration(new InsetStatusItemDecoration(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isItemEnabled(String id){
|
public boolean isItemEnabled(String id){
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -29,7 +29,7 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>{
|
||||||
protected EventListener eventListener=new EventListener();
|
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, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -71,6 +71,7 @@ public class ThreadFragment extends StatusListFragment{
|
||||||
List<StatusDisplayItem> items=super.buildDisplayItems(s);
|
List<StatusDisplayItem> items=super.buildDisplayItems(s);
|
||||||
if(s.id.equals(mainStatus.id)){
|
if(s.id.equals(mainStatus.id)){
|
||||||
for(StatusDisplayItem item:items){
|
for(StatusDisplayItem item:items){
|
||||||
|
item.fullWidth=true;
|
||||||
if(item instanceof TextStatusDisplayItem text)
|
if(item instanceof TextStatusDisplayItem text)
|
||||||
text.textSelectable=true;
|
text.textSelectable=true;
|
||||||
else if(item instanceof FooterStatusDisplayItem footer)
|
else if(item instanceof FooterStatusDisplayItem footer)
|
||||||
|
|
|
@ -30,8 +30,6 @@ import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
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 SearchFragment extends BaseStatusListFragment<SearchResult>{
|
public class SearchFragment extends BaseStatusListFragment<SearchResult>{
|
||||||
|
@ -65,7 +63,7 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
|
||||||
return switch(s.type){
|
return switch(s.type){
|
||||||
case ACCOUNT -> Collections.singletonList(new AccountStatusDisplayItem(s.id, this, s.account));
|
case ACCOUNT -> Collections.singletonList(new AccountStatusDisplayItem(s.id, this, s.account));
|
||||||
case HASHTAG -> Collections.singletonList(new HashtagStatusDisplayItem(s.id, this, s.hashtag));
|
case HASHTAG -> Collections.singletonList(new HashtagStatusDisplayItem(s.id, this, s.hashtag));
|
||||||
case STATUS -> StatusDisplayItem.buildItems(this, s.status, accountID, s, knownAccounts, false, true);
|
case STATUS -> StatusDisplayItem.buildItems(this, s.status, accountID, s, knownAccounts, true);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,7 @@ public class ReportAddPostsChoiceFragment extends StatusListFragment{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
||||||
return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, StatusDisplayItem.FLAG_INSET | StatusDisplayItem.FLAG_NO_FOOTER | StatusDisplayItem.FLAG_CHECKABLE | StatusDisplayItem.FLAG_MEDIA_FORCE_HIDDEN);
|
return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, StatusDisplayItem.FLAG_NO_FOOTER | StatusDisplayItem.FLAG_CHECKABLE | StatusDisplayItem.FLAG_MEDIA_FORCE_HIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -241,7 +241,7 @@ public class ReportReasonChoiceFragment extends StatusListFragment{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
||||||
return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, StatusDisplayItem.FLAG_INSET | StatusDisplayItem.FLAG_NO_FOOTER);
|
return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, StatusDisplayItem.FLAG_NO_FOOTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,6 +16,11 @@ public class PhotoLayoutHelper{
|
||||||
public static final int MIN_HEIGHT=563;
|
public static final int MIN_HEIGHT=563;
|
||||||
public static final float GAP=1.5f;
|
public static final float GAP=1.5f;
|
||||||
|
|
||||||
|
public static final int CORNER_TL=1;
|
||||||
|
public static final int CORNER_TR=2;
|
||||||
|
public static final int CORNER_BL=4;
|
||||||
|
public static final int CORNER_BR=8;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static TiledLayoutResult processThumbs(List<Attachment> thumbs){
|
public static TiledLayoutResult processThumbs(List<Attachment> thumbs){
|
||||||
float maxRatio=MAX_WIDTH/(float)MAX_HEIGHT;
|
float maxRatio=MAX_WIDTH/(float)MAX_HEIGHT;
|
||||||
|
@ -33,8 +38,9 @@ public class PhotoLayoutHelper{
|
||||||
result.width=MAX_WIDTH;//Math.round(att.getWidth()/(float)att.getHeight()*MAX_HEIGHT);
|
result.width=MAX_WIDTH;//Math.round(att.getWidth()/(float)att.getHeight()*MAX_HEIGHT);
|
||||||
}
|
}
|
||||||
result.tiles=new TiledLayoutResult.Tile[]{new TiledLayoutResult.Tile(1, 1, 0, 0)};
|
result.tiles=new TiledLayoutResult.Tile[]{new TiledLayoutResult.Tile(1, 1, 0, 0)};
|
||||||
|
result.tiles[0].columnCount=result.tiles[0].rowCount=1;
|
||||||
return result;
|
return result;
|
||||||
}else if(thumbs.size()==0){
|
}else if(thumbs.isEmpty()){
|
||||||
throw new IllegalArgumentException("Empty thumbs array");
|
throw new IllegalArgumentException("Empty thumbs array");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,6 +315,11 @@ public class PhotoLayoutHelper{
|
||||||
result.height=Math.round(totalHeight+GAP*(optHeights.length-1));
|
result.height=Math.round(totalHeight+GAP*(optHeights.length-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(TiledLayoutResult.Tile tile:result.tiles){
|
||||||
|
tile.columnCount=result.columnSizes.length;
|
||||||
|
tile.rowCount=result.rowSizes.length;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,7 +351,7 @@ public class PhotoLayoutHelper{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Tile{
|
public static class Tile{
|
||||||
public int colSpan, rowSpan, startCol, startRow;
|
public int colSpan, rowSpan, startCol, startRow, columnCount, rowCount;
|
||||||
public int width;
|
public int width;
|
||||||
|
|
||||||
public Tile(int colSpan, int rowSpan, int startCol, int startRow){
|
public Tile(int colSpan, int rowSpan, int startCol, int startRow){
|
||||||
|
@ -364,6 +375,27 @@ public class PhotoLayoutHelper{
|
||||||
", startRow="+startRow+
|
", startRow="+startRow+
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getRoundCornersMask(){
|
||||||
|
if(columnCount==1 && rowCount==1){ // Single attachment. All corners are rounded
|
||||||
|
return CORNER_TL | CORNER_TR | CORNER_BL | CORNER_BR;
|
||||||
|
}else if(colSpan==columnCount && startRow==0){ // Top attachment. Top corners are rounded
|
||||||
|
return CORNER_TL | CORNER_TR;
|
||||||
|
}else if(colSpan==columnCount && startRow==rowCount-1){ // Bottom attachment. Bottom corners are rounded
|
||||||
|
return CORNER_BL | CORNER_BR;
|
||||||
|
}else if(startCol==0 && startRow==0 && rowSpan==rowCount){ // Left attachment in a vertical layout
|
||||||
|
return CORNER_TL | CORNER_BL;
|
||||||
|
}else if(startCol==0 && startRow==0){ // Top left
|
||||||
|
return CORNER_TL;
|
||||||
|
}else if(startCol==columnCount-colSpan && startRow==0){ // Top right
|
||||||
|
return CORNER_TR;
|
||||||
|
}else if(startCol==0 && startRow==rowCount-rowSpan){ // Bottom left
|
||||||
|
return CORNER_BL;
|
||||||
|
}else if(startCol==columnCount-colSpan && startRow==rowCount-rowSpan){ // Bottom right
|
||||||
|
return CORNER_BR;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,10 +98,13 @@ public class AudioStatusDisplayItem extends StatusDisplayItem{
|
||||||
image.setOutlineProvider(OutlineProviders.OVAL);
|
image.setOutlineProvider(OutlineProviders.OVAL);
|
||||||
image.setClipToOutline(true);
|
image.setClipToOutline(true);
|
||||||
content.setBackground(bgDrawable=new AudioAttachmentBackgroundDrawable());
|
content.setBackground(bgDrawable=new AudioAttachmentBackgroundDrawable());
|
||||||
|
content.setOutlineProvider(OutlineProviders.roundedRect(8));
|
||||||
|
content.setClipToOutline(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBind(AudioStatusDisplayItem item){
|
public void onBind(AudioStatusDisplayItem item){
|
||||||
|
itemView.setPaddingRelative(V.dp(item.fullWidth ? 16 : 64), itemView.getPaddingTop(), itemView.getPaddingEnd(), itemView.getPaddingBottom());
|
||||||
int seconds=(int)item.attachment.getDuration();
|
int seconds=(int)item.attachment.getDuration();
|
||||||
String duration=UiUtils.formatMediaDuration(seconds);
|
String duration=UiUtils.formatMediaDuration(seconds);
|
||||||
AudioPlayerService service=AudioPlayerService.getInstance();
|
AudioPlayerService service=AudioPlayerService.getInstance();
|
||||||
|
|
|
@ -53,6 +53,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
||||||
private final ColorStateList buttonColors;
|
private final ColorStateList buttonColors;
|
||||||
private final View replyBtn, boostBtn, favoriteBtn, shareBtn;
|
private final View replyBtn, boostBtn, favoriteBtn, shareBtn;
|
||||||
private final PopupMenu boostLongTapMenu, favoriteLongTapMenu;
|
private final PopupMenu boostLongTapMenu, favoriteLongTapMenu;
|
||||||
|
private final View spacer1, spacer2;
|
||||||
|
|
||||||
private final View.AccessibilityDelegate buttonAccessibilityDelegate=new View.AccessibilityDelegate(){
|
private final View.AccessibilityDelegate buttonAccessibilityDelegate=new View.AccessibilityDelegate(){
|
||||||
@Override
|
@Override
|
||||||
|
@ -69,6 +70,8 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
||||||
boost=findViewById(R.id.boost);
|
boost=findViewById(R.id.boost);
|
||||||
favorite=findViewById(R.id.favorite);
|
favorite=findViewById(R.id.favorite);
|
||||||
share=findViewById(R.id.share);
|
share=findViewById(R.id.share);
|
||||||
|
spacer1=findViewById(R.id.spacer1);
|
||||||
|
spacer2=findViewById(R.id.spacer2);
|
||||||
|
|
||||||
float[] hsb={0, 0, 0};
|
float[] hsb={0, 0, 0};
|
||||||
Color.colorToHSV(UiUtils.getThemeColor(activity, R.attr.colorM3Primary), hsb);
|
Color.colorToHSV(UiUtils.getThemeColor(activity, R.attr.colorM3Primary), hsb);
|
||||||
|
@ -81,8 +84,8 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
||||||
{}
|
{}
|
||||||
}, new int[]{
|
}, new int[]{
|
||||||
Color.HSVToColor(hsb),
|
Color.HSVToColor(hsb),
|
||||||
UiUtils.getThemeColor(activity, R.attr.colorM3OnSurfaceVariant),
|
UiUtils.getThemeColor(activity, R.attr.colorM3Outline),
|
||||||
UiUtils.getThemeColor(activity, R.attr.colorM3OnSurfaceVariant) & 0x80FFFFFF
|
UiUtils.getThemeColor(activity, R.attr.colorM3Outline) & 0x80FFFFFF
|
||||||
});
|
});
|
||||||
|
|
||||||
boost.setTextColor(buttonColors);
|
boost.setTextColor(buttonColors);
|
||||||
|
@ -120,6 +123,9 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBind(FooterStatusDisplayItem item){
|
public void onBind(FooterStatusDisplayItem item){
|
||||||
|
spacer1.setVisibility(item.fullWidth ? View.VISIBLE : View.GONE);
|
||||||
|
spacer2.setVisibility(item.fullWidth ? View.VISIBLE : View.GONE);
|
||||||
|
itemView.setPaddingRelative(V.dp(item.fullWidth ? 8 : 56), itemView.getPaddingTop(), itemView.getPaddingEnd(), itemView.getPaddingBottom());
|
||||||
bindButton(reply, item.status.repliesCount);
|
bindButton(reply, item.status.repliesCount);
|
||||||
bindButton(boost, item.status.reblogsCount);
|
bindButton(boost, item.status.reblogsCount);
|
||||||
bindButton(favorite, item.status.favouritesCount);
|
bindButton(favorite, item.status.favouritesCount);
|
||||||
|
|
|
@ -9,7 +9,6 @@ import android.graphics.drawable.Animatable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Parcel;
|
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
|
@ -23,7 +22,6 @@ import android.widget.Toast;
|
||||||
|
|
||||||
import org.joinmastodon.android.GlobalUserPreferences;
|
import org.joinmastodon.android.GlobalUserPreferences;
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
|
|
||||||
import org.joinmastodon.android.api.requests.statuses.GetStatusSourceText;
|
import org.joinmastodon.android.api.requests.statuses.GetStatusSourceText;
|
||||||
import org.joinmastodon.android.api.requests.statuses.SetStatusConversationMuted;
|
import org.joinmastodon.android.api.requests.statuses.SetStatusConversationMuted;
|
||||||
import org.joinmastodon.android.api.requests.statuses.SetStatusPinned;
|
import org.joinmastodon.android.api.requests.statuses.SetStatusPinned;
|
||||||
|
@ -46,13 +44,10 @@ import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
import org.parceler.Parcels;
|
import org.parceler.Parcels;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import androidx.annotation.LayoutRes;
|
import androidx.annotation.LayoutRes;
|
||||||
import me.grishka.appkit.Nav;
|
import me.grishka.appkit.Nav;
|
||||||
import me.grishka.appkit.api.APIRequest;
|
|
||||||
import me.grishka.appkit.api.Callback;
|
import me.grishka.appkit.api.Callback;
|
||||||
import me.grishka.appkit.api.ErrorResponse;
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
||||||
|
@ -272,9 +267,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||||
extraText.setVisibility(View.VISIBLE);
|
extraText.setVisibility(View.VISIBLE);
|
||||||
extraText.setText(item.extraText);
|
extraText.setText(item.extraText);
|
||||||
}
|
}
|
||||||
more.setVisibility(item.inset ? View.GONE : View.VISIBLE);
|
|
||||||
if(clickableThing!=null){
|
if(clickableThing!=null){
|
||||||
clickableThing.setClickable(!item.inset);
|
|
||||||
clickableThing.setContentDescription(item.parentFragment.getString(R.string.avatar_description, item.user.acct));
|
clickableThing.setContentDescription(item.parentFragment.getString(R.string.avatar_description, item.user.acct));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import org.joinmastodon.android.model.viewmodel.CardViewModel;
|
||||||
import org.joinmastodon.android.ui.viewholders.LinkCardHolder;
|
import org.joinmastodon.android.ui.viewholders.LinkCardHolder;
|
||||||
|
|
||||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||||
|
import me.grishka.appkit.utils.V;
|
||||||
|
|
||||||
public class LinkCardStatusDisplayItem extends StatusDisplayItem implements LinkCardHolder.LinkCardProvider{
|
public class LinkCardStatusDisplayItem extends StatusDisplayItem implements LinkCardHolder.LinkCardProvider{
|
||||||
private final Status status;
|
private final Status status;
|
||||||
|
@ -51,5 +52,11 @@ public class LinkCardStatusDisplayItem extends StatusDisplayItem implements Link
|
||||||
public Holder(Activity context, ViewGroup parent, boolean isLarge, String accountID){
|
public Holder(Activity context, ViewGroup parent, boolean isLarge, String accountID){
|
||||||
super(context, parent, isLarge, accountID);
|
super(context, parent, isLarge, accountID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBind(LinkCardStatusDisplayItem item){
|
||||||
|
super.onBind(item);
|
||||||
|
itemView.setPaddingRelative(V.dp(item.fullWidth ? 16 : 64), itemView.getPaddingTop(), itemView.getPaddingEnd(), itemView.getPaddingBottom());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,15 @@
|
||||||
package org.joinmastodon.android.ui.displayitems;
|
package org.joinmastodon.android.ui.displayitems;
|
||||||
|
|
||||||
import android.animation.Animator;
|
|
||||||
import android.animation.AnimatorListenerAdapter;
|
|
||||||
import android.animation.AnimatorSet;
|
|
||||||
import android.animation.ObjectAnimator;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.graphics.drawable.ColorDrawable;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.drawable.LayerDrawable;
|
import android.graphics.drawable.LayerDrawable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewTreeObserver;
|
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageButton;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
|
@ -46,7 +39,6 @@ import java.util.Optional;
|
||||||
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.imageloader.requests.UrlImageLoaderRequest;
|
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||||
import me.grishka.appkit.utils.CubicBezierInterpolator;
|
|
||||||
import me.grishka.appkit.utils.V;
|
import me.grishka.appkit.utils.V;
|
||||||
|
|
||||||
public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
||||||
|
@ -138,6 +130,8 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
||||||
sensitiveOverlayBG.setDrawableByLayerId(R.id.right_drawable, new SpoilerStripesDrawable(true));
|
sensitiveOverlayBG.setDrawableByLayerId(R.id.right_drawable, new SpoilerStripesDrawable(true));
|
||||||
sensitiveOverlay.setBackground(sensitiveOverlayBG);
|
sensitiveOverlay.setBackground(sensitiveOverlayBG);
|
||||||
sensitiveOverlay.setOnClickListener(v->revealSensitive());
|
sensitiveOverlay.setOnClickListener(v->revealSensitive());
|
||||||
|
sensitiveOverlay.setOutlineProvider(OutlineProviders.roundedRect(8));
|
||||||
|
sensitiveOverlay.setClipToOutline(true);
|
||||||
hideSensitiveButton.setOnClickListener(v->hideSensitive());
|
hideSensitiveButton.setOnClickListener(v->hideSensitive());
|
||||||
|
|
||||||
sensitiveText=findViewById(R.id.sensitive_text);
|
sensitiveText=findViewById(R.id.sensitive_text);
|
||||||
|
@ -146,7 +140,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
||||||
@Override
|
@Override
|
||||||
public void onBind(MediaGridStatusDisplayItem item){
|
public void onBind(MediaGridStatusDisplayItem item){
|
||||||
thereAreFailedImages=false;
|
thereAreFailedImages=false;
|
||||||
wrapper.setPadding(0, 0, 0, item.inset ? 0 : V.dp(8));
|
wrapper.setPaddingRelative(V.dp(item.fullWidth ? 16 : 64), 0, V.dp(16), V.dp(8));
|
||||||
|
|
||||||
layout.setTiledLayout(item.tiledLayout);
|
layout.setTiledLayout(item.tiledLayout);
|
||||||
for(MediaAttachmentViewController c:controllers){
|
for(MediaAttachmentViewController c:controllers){
|
||||||
|
|
|
@ -71,7 +71,7 @@ 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, button;
|
||||||
private final Drawable progressBg, progressBgInset;
|
private final Drawable progressBg;
|
||||||
|
|
||||||
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);
|
||||||
|
@ -80,7 +80,6 @@ public class PollOptionStatusDisplayItem extends StatusDisplayItem{
|
||||||
check=findViewById(R.id.checkbox);
|
check=findViewById(R.id.checkbox);
|
||||||
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();
|
||||||
progressBgInset=activity.getResources().getDrawable(R.drawable.bg_poll_option_voted_inset, activity.getTheme()).mutate();
|
|
||||||
itemView.setOnClickListener(this::onButtonClick);
|
itemView.setOnClickListener(this::onButtonClick);
|
||||||
button.setOutlineProvider(OutlineProviders.roundedRect(20));
|
button.setOutlineProvider(OutlineProviders.roundedRect(20));
|
||||||
button.setClipToOutline(true);
|
button.setClipToOutline(true);
|
||||||
|
@ -99,7 +98,7 @@ public class PollOptionStatusDisplayItem extends StatusDisplayItem{
|
||||||
percent.setVisibility(item.showResults ? View.VISIBLE : View.GONE);
|
percent.setVisibility(item.showResults ? View.VISIBLE : View.GONE);
|
||||||
itemView.setClickable(!item.showResults);
|
itemView.setClickable(!item.showResults);
|
||||||
if(item.showResults){
|
if(item.showResults){
|
||||||
Drawable bg=item.inset ? progressBgInset : progressBg;
|
Drawable bg=progressBg;
|
||||||
bg.setLevel(Math.round(10000f*item.votesFraction));
|
bg.setLevel(Math.round(10000f*item.votesFraction));
|
||||||
button.setBackground(bg);
|
button.setBackground(bg);
|
||||||
itemView.setSelected(item.isMostVoted);
|
itemView.setSelected(item.isMostVoted);
|
||||||
|
@ -107,15 +106,10 @@ public class PollOptionStatusDisplayItem extends StatusDisplayItem{
|
||||||
percent.setText(String.format(Locale.getDefault(), "%d%%", Math.round(item.votesFraction*100f)));
|
percent.setText(String.format(Locale.getDefault(), "%d%%", Math.round(item.votesFraction*100f)));
|
||||||
}else{
|
}else{
|
||||||
itemView.setSelected(item.poll.selectedOptions!=null && item.poll.selectedOptions.contains(item.option));
|
itemView.setSelected(item.poll.selectedOptions!=null && item.poll.selectedOptions.contains(item.option));
|
||||||
button.setBackgroundResource(item.inset ? R.drawable.bg_poll_option_clickable_inset : R.drawable.bg_poll_option_clickable);
|
button.setBackgroundResource(R.drawable.bg_poll_option_clickable);
|
||||||
}
|
|
||||||
if(item.inset){
|
|
||||||
text.setTextColor(itemView.getContext().getColorStateList(R.color.poll_option_text_inset));
|
|
||||||
percent.setTextColor(itemView.getContext().getColorStateList(R.color.poll_option_text_inset));
|
|
||||||
}else{
|
|
||||||
text.setTextColor(UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3Primary));
|
|
||||||
percent.setTextColor(UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3OnSecondaryContainer));
|
|
||||||
}
|
}
|
||||||
|
text.setTextColor(UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3Primary));
|
||||||
|
percent.setTextColor(UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3OnSecondaryContainer));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.List;
|
||||||
import androidx.annotation.DrawableRes;
|
import androidx.annotation.DrawableRes;
|
||||||
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 ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
||||||
private CharSequence text;
|
private CharSequence text;
|
||||||
|
@ -62,9 +63,15 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
||||||
@Override
|
@Override
|
||||||
public void onBind(ReblogOrReplyLineStatusDisplayItem item){
|
public void onBind(ReblogOrReplyLineStatusDisplayItem item){
|
||||||
text.setText(item.text);
|
text.setText(item.text);
|
||||||
text.setCompoundDrawablesRelativeWithIntrinsicBounds(item.icon, 0, 0, 0);
|
if(item.icon!=0){
|
||||||
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N)
|
Drawable icon=itemView.getContext().getDrawable(item.icon);
|
||||||
UiUtils.fixCompoundDrawableTintOnAndroid6(text);
|
icon.setBounds(0, 0, V.dp(16), V.dp(16));
|
||||||
|
text.setCompoundDrawablesRelative(icon, null, null, null);
|
||||||
|
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N)
|
||||||
|
UiUtils.fixCompoundDrawableTintOnAndroid6(text);
|
||||||
|
}else{
|
||||||
|
text.setCompoundDrawables(null, null, null, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.ArrayList;
|
||||||
|
|
||||||
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 SpoilerStatusDisplayItem extends StatusDisplayItem{
|
public class SpoilerStatusDisplayItem extends StatusDisplayItem{
|
||||||
public final Status status;
|
public final Status status;
|
||||||
|
@ -88,6 +89,7 @@ public class SpoilerStatusDisplayItem extends StatusDisplayItem{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBind(SpoilerStatusDisplayItem item){
|
public void onBind(SpoilerStatusDisplayItem item){
|
||||||
|
itemView.setPaddingRelative(V.dp(item.fullWidth ? 16 : 64), itemView.getPaddingTop(), itemView.getPaddingEnd(), itemView.getPaddingBottom());
|
||||||
if(item.status.translationState==Status.TranslationState.SHOWN){
|
if(item.status.translationState==Status.TranslationState.SHOWN){
|
||||||
if(item.translatedTitle==null){
|
if(item.translatedTitle==null){
|
||||||
item.translatedTitle=item.status.translation.spoilerText;
|
item.translatedTitle=item.status.translation.spoilerText;
|
||||||
|
|
|
@ -35,10 +35,10 @@ import me.grishka.appkit.views.UsableRecyclerView;
|
||||||
public abstract class StatusDisplayItem{
|
public abstract class StatusDisplayItem{
|
||||||
public final String parentID;
|
public final String parentID;
|
||||||
public final BaseStatusListFragment<?> parentFragment;
|
public final BaseStatusListFragment<?> parentFragment;
|
||||||
public boolean inset;
|
public boolean fullWidth; // aka "highlighted"
|
||||||
public int index;
|
public int index;
|
||||||
|
|
||||||
public static final int FLAG_INSET=1;
|
public static final int FLAG_FULL_WIDTH=1;
|
||||||
public static final int FLAG_NO_FOOTER=1 << 1;
|
public static final int FLAG_NO_FOOTER=1 << 1;
|
||||||
public static final int FLAG_CHECKABLE=1 << 2;
|
public static final int FLAG_CHECKABLE=1 << 2;
|
||||||
public static final int FLAG_MEDIA_FORCE_HIDDEN=1 << 3;
|
public static final int FLAG_MEDIA_FORCE_HIDDEN=1 << 3;
|
||||||
|
@ -82,16 +82,14 @@ public abstract class StatusDisplayItem{
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean addFooter){
|
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean addFooter){
|
||||||
int flags=0;
|
int flags=0;
|
||||||
if(inset)
|
|
||||||
flags|=FLAG_INSET;
|
|
||||||
if(!addFooter)
|
if(!addFooter)
|
||||||
flags|=FLAG_NO_FOOTER;
|
flags|=FLAG_NO_FOOTER;
|
||||||
return buildItems(fragment, status, accountID, parentObject, knownAccounts, flags);
|
return buildItems(fragment, status, accountID, parentObject, knownAccounts, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, int flags){
|
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, int flags){
|
||||||
String parentID=parentObject.getID();
|
String parentID=parentObject.getID();
|
||||||
ArrayList<StatusDisplayItem> items=new ArrayList<>();
|
ArrayList<StatusDisplayItem> items=new ArrayList<>();
|
||||||
Status statusForContent=status.getContentStatus();
|
Status statusForContent=status.getContentStatus();
|
||||||
|
@ -99,10 +97,10 @@ public abstract class StatusDisplayItem{
|
||||||
boolean hideCounts=!AccountSessionManager.get(accountID).getLocalPreferences().showInteractionCounts;
|
boolean hideCounts=!AccountSessionManager.get(accountID).getLocalPreferences().showInteractionCounts;
|
||||||
if((flags & FLAG_NO_HEADER)==0){
|
if((flags & FLAG_NO_HEADER)==0){
|
||||||
if(status.reblog!=null){
|
if(status.reblog!=null){
|
||||||
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.user_boosted, status.account.displayName), status.account.emojis, R.drawable.ic_repeat_20px));
|
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.user_boosted, status.account.displayName), status.account.emojis, R.drawable.ic_repeat_wght700_20px));
|
||||||
}else if(status.inReplyToAccountId!=null && knownAccounts.containsKey(status.inReplyToAccountId)){
|
}else if(status.inReplyToAccountId!=null && knownAccounts.containsKey(status.inReplyToAccountId)){
|
||||||
Account account=Objects.requireNonNull(knownAccounts.get(status.inReplyToAccountId));
|
Account account=Objects.requireNonNull(knownAccounts.get(status.inReplyToAccountId));
|
||||||
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.in_reply_to, account.displayName), account.emojis, R.drawable.ic_reply_20px));
|
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.in_reply_to, account.displayName), account.emojis, R.drawable.ic_reply_wght700_20px));
|
||||||
}
|
}
|
||||||
if((flags & FLAG_CHECKABLE)!=0)
|
if((flags & FLAG_CHECKABLE)!=0)
|
||||||
items.add(header=new CheckableHeaderStatusDisplayItem(parentID, statusForContent.account, statusForContent.createdAt, fragment, accountID, statusForContent, null));
|
items.add(header=new CheckableHeaderStatusDisplayItem(parentID, statusForContent.account, statusForContent.createdAt, fragment, accountID, statusForContent, null));
|
||||||
|
@ -185,21 +183,20 @@ public abstract class StatusDisplayItem{
|
||||||
items.add(new GapStatusDisplayItem(parentID, fragment));
|
items.add(new GapStatusDisplayItem(parentID, fragment));
|
||||||
}
|
}
|
||||||
int i=1;
|
int i=1;
|
||||||
boolean inset=(flags & FLAG_INSET)!=0;
|
boolean fullWidth=(flags & FLAG_FULL_WIDTH)!=0;
|
||||||
for(StatusDisplayItem item:items){
|
for(StatusDisplayItem item:items){
|
||||||
item.inset=inset;
|
item.fullWidth=fullWidth;
|
||||||
item.index=i++;
|
item.index=i++;
|
||||||
}
|
}
|
||||||
if(items!=contentItems){
|
if(items!=contentItems){
|
||||||
for(StatusDisplayItem item:contentItems){
|
for(StatusDisplayItem item:contentItems){
|
||||||
item.inset=inset;
|
|
||||||
item.index=i++;
|
item.index=i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void buildPollItems(String parentID, BaseStatusListFragment fragment, Poll poll, Status status, List<StatusDisplayItem> items){
|
public static void buildPollItems(String parentID, BaseStatusListFragment<?> fragment, Poll poll, Status status, List<StatusDisplayItem> items){
|
||||||
int i=0;
|
int i=0;
|
||||||
for(Poll.Option opt:poll.options){
|
for(Poll.Option opt:poll.options){
|
||||||
items.add(new PollOptionStatusDisplayItem(parentID, poll, i, fragment, status));
|
items.add(new PollOptionStatusDisplayItem(parentID, poll, i, fragment, status));
|
||||||
|
|
|
@ -3,7 +3,7 @@ package org.joinmastodon.android.ui.displayitems;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.graphics.drawable.Animatable;
|
import android.graphics.drawable.Animatable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.util.TypedValue;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewStub;
|
import android.view.ViewStub;
|
||||||
|
@ -95,7 +95,9 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||||
text.setInvalidateOnEveryFrame(false);
|
text.setInvalidateOnEveryFrame(false);
|
||||||
itemView.setClickable(false);
|
itemView.setClickable(false);
|
||||||
text.setPadding(text.getPaddingLeft(), item.reduceTopPadding ? V.dp(8) : V.dp(12), text.getPaddingRight(), text.getPaddingBottom());
|
text.setPadding(text.getPaddingLeft(), item.reduceTopPadding ? V.dp(8) : V.dp(12), text.getPaddingRight(), text.getPaddingBottom());
|
||||||
text.setTextColor(UiUtils.getThemeColor(text.getContext(), item.inset ? R.attr.colorM3OnSurfaceVariant : R.attr.colorM3OnSurface));
|
itemView.setPaddingRelative(V.dp(item.fullWidth ? 0 : 48), 0, 0, 0);
|
||||||
|
text.setTextColor(UiUtils.getThemeColor(text.getContext(), R.attr.colorM3OnSurface));
|
||||||
|
text.setTextSize(TypedValue.COMPLEX_UNIT_SP, item.fullWidth ? 18 : 16);
|
||||||
updateTranslation(false);
|
updateTranslation(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ import android.graphics.Path;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.GestureDetector;
|
import android.view.GestureDetector;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.ScaleGestureDetector;
|
import android.view.ScaleGestureDetector;
|
||||||
|
@ -55,7 +54,7 @@ public class ZoomPanView extends FrameLayout implements ScaleGestureDetector.OnS
|
||||||
private float lastFlingVelocityY;
|
private float lastFlingVelocityY;
|
||||||
private float backgroundAlphaForTransition=1f;
|
private float backgroundAlphaForTransition=1f;
|
||||||
private boolean forceUpdateLayout;
|
private boolean forceUpdateLayout;
|
||||||
private int[] transitionCornerRadius;
|
private float[] transitionCornerRadius;
|
||||||
private Path transitionClipPath=new Path();
|
private Path transitionClipPath=new Path();
|
||||||
private float[] tmpFloatArray=new float[8];
|
private float[] tmpFloatArray=new float[8];
|
||||||
|
|
||||||
|
@ -72,13 +71,13 @@ public class ZoomPanView extends FrameLayout implements ScaleGestureDetector.OnS
|
||||||
@Override
|
@Override
|
||||||
public void setValue(ZoomPanView object, float value){
|
public void setValue(ZoomPanView object, float value){
|
||||||
object.rawCropAndFadeValue=value;
|
object.rawCropAndFadeValue=value;
|
||||||
if(value>0.1f)
|
if(value>0.3f)
|
||||||
object.child.setAlpha(Math.min((value-0.1f)/0.4f, 1f));
|
object.child.setAlpha(Math.min((value-0.3f)/0.2f, 1f));
|
||||||
else
|
else
|
||||||
object.child.setAlpha(0f);
|
object.child.setAlpha(0f);
|
||||||
|
|
||||||
if(value>0.3f)
|
if(value>0.5f)
|
||||||
object.setCropAnimationValue(Math.min(1f, (value-0.3f)/0.7f));
|
object.setCropAnimationValue(Math.min(1f, (value-0.5f)/0.5f));
|
||||||
else
|
else
|
||||||
object.setCropAnimationValue(0f);
|
object.setCropAnimationValue(0f);
|
||||||
|
|
||||||
|
@ -159,10 +158,10 @@ public class ZoomPanView extends FrameLayout implements ScaleGestureDetector.OnS
|
||||||
canvas.save();
|
canvas.save();
|
||||||
if(transitionCornerRadius!=null){
|
if(transitionCornerRadius!=null){
|
||||||
float radiusScale=child.getScaleX();
|
float radiusScale=child.getScaleX();
|
||||||
tmpFloatArray[0]=tmpFloatArray[1]=(float)transitionCornerRadius[0]*radiusScale*(1f-cropAnimationValue);
|
tmpFloatArray[0]=tmpFloatArray[1]=transitionCornerRadius[0]*radiusScale*(1f-cropAnimationValue);
|
||||||
tmpFloatArray[2]=tmpFloatArray[3]=(float)transitionCornerRadius[1]*radiusScale*(1f-cropAnimationValue);
|
tmpFloatArray[2]=tmpFloatArray[3]=transitionCornerRadius[1]*radiusScale*(1f-cropAnimationValue);
|
||||||
tmpFloatArray[4]=tmpFloatArray[5]=(float)transitionCornerRadius[2]*radiusScale*(1f-cropAnimationValue);
|
tmpFloatArray[4]=tmpFloatArray[5]=transitionCornerRadius[2]*radiusScale*(1f-cropAnimationValue);
|
||||||
tmpFloatArray[6]=tmpFloatArray[7]=(float)transitionCornerRadius[3]*radiusScale*(1f-cropAnimationValue);
|
tmpFloatArray[6]=tmpFloatArray[7]=transitionCornerRadius[3]*radiusScale*(1f-cropAnimationValue);
|
||||||
transitionClipPath.rewind();
|
transitionClipPath.rewind();
|
||||||
transitionClipPath.addRoundRect(interpolate(tmpRect2.left, tmpRect.left, cropAnimationValue),
|
transitionClipPath.addRoundRect(interpolate(tmpRect2.left, tmpRect.left, cropAnimationValue),
|
||||||
interpolate(tmpRect2.top, tmpRect.top, cropAnimationValue),
|
interpolate(tmpRect2.top, tmpRect.top, cropAnimationValue),
|
||||||
|
@ -213,12 +212,15 @@ public class ZoomPanView extends FrameLayout implements ScaleGestureDetector.OnS
|
||||||
return initialScale;
|
return initialScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateAndSetCornerRadius(int[] cornerRadius){
|
private void validateAndSetCornerRadius(int[] cornerRadius, float scale){
|
||||||
transitionCornerRadius=null;
|
transitionCornerRadius=null;
|
||||||
if(cornerRadius!=null && cornerRadius.length==4){
|
if(cornerRadius!=null && cornerRadius.length==4){
|
||||||
for(int corner:cornerRadius){
|
for(int corner:cornerRadius){
|
||||||
if(corner>0){
|
if(corner>0){
|
||||||
transitionCornerRadius=cornerRadius;
|
transitionCornerRadius=new float[4];
|
||||||
|
for(int i=0;i<4;i++){
|
||||||
|
transitionCornerRadius[i]=cornerRadius[i]*scale;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,7 +242,7 @@ public class ZoomPanView extends FrameLayout implements ScaleGestureDetector.OnS
|
||||||
animatingTransition=true;
|
animatingTransition=true;
|
||||||
|
|
||||||
matrix.getValues(matrixValues);
|
matrix.getValues(matrixValues);
|
||||||
validateAndSetCornerRadius(cornerRadius);
|
validateAndSetCornerRadius(cornerRadius, 1f/initialScale);
|
||||||
|
|
||||||
child.setAlpha(0f);
|
child.setAlpha(0f);
|
||||||
setupAndStartTransitionAnim(new SpringAnimation(this, CROP_AND_FADE, 1f).setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE));
|
setupAndStartTransitionAnim(new SpringAnimation(this, CROP_AND_FADE, 1f).setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE));
|
||||||
|
@ -270,7 +272,7 @@ public class ZoomPanView extends FrameLayout implements ScaleGestureDetector.OnS
|
||||||
animatingTransition=true;
|
animatingTransition=true;
|
||||||
dismissAfterTransition=true;
|
dismissAfterTransition=true;
|
||||||
rawCropAndFadeValue=1f;
|
rawCropAndFadeValue=1f;
|
||||||
validateAndSetCornerRadius(cornerRadius);
|
validateAndSetCornerRadius(cornerRadius, 1f/initialScale);
|
||||||
|
|
||||||
setupAndStartTransitionAnim(new SpringAnimation(this, CROP_AND_FADE, 0f).setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE));
|
setupAndStartTransitionAnim(new SpringAnimation(this, CROP_AND_FADE, 0f).setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE));
|
||||||
setupAndStartTransitionAnim(new SpringAnimation(child, DynamicAnimation.SCALE_X, initialScale));
|
setupAndStartTransitionAnim(new SpringAnimation(child, DynamicAnimation.SCALE_X, initialScale));
|
||||||
|
|
|
@ -1,101 +0,0 @@
|
||||||
package org.joinmastodon.android.ui.utils;
|
|
||||||
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import org.joinmastodon.android.R;
|
|
||||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
|
||||||
import org.joinmastodon.android.ui.displayitems.NotificationHeaderStatusDisplayItem;
|
|
||||||
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
import me.grishka.appkit.utils.V;
|
|
||||||
|
|
||||||
public class InsetStatusItemDecoration extends RecyclerView.ItemDecoration{
|
|
||||||
private final BaseStatusListFragment<?> listFragment;
|
|
||||||
private Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);
|
|
||||||
private int bgColor;
|
|
||||||
private int borderColor;
|
|
||||||
private RectF rect=new RectF();
|
|
||||||
|
|
||||||
public InsetStatusItemDecoration(BaseStatusListFragment<?> listFragment){
|
|
||||||
this.listFragment=listFragment;
|
|
||||||
bgColor=UiUtils.getThemeColor(listFragment.getActivity(), R.attr.colorM3SurfaceVariant);
|
|
||||||
borderColor=UiUtils.getThemeColor(listFragment.getActivity(), R.attr.colorM3OutlineVariant);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state){
|
|
||||||
List<StatusDisplayItem> displayItems=listFragment.getDisplayItems();
|
|
||||||
int pos=0;
|
|
||||||
for(int i=0; i<parent.getChildCount(); i++){
|
|
||||||
View child=parent.getChildAt(i);
|
|
||||||
RecyclerView.ViewHolder holder=parent.getChildViewHolder(child);
|
|
||||||
pos=holder.getAbsoluteAdapterPosition()-listFragment.getMainAdapterOffset();
|
|
||||||
boolean inset=holder instanceof StatusDisplayItem.Holder<?> sdi && sdi.getItem() instanceof StatusDisplayItem item && item.inset;
|
|
||||||
if(inset){
|
|
||||||
if(rect.isEmpty()){
|
|
||||||
float childY=child.getY();
|
|
||||||
if(pos>0 && displayItems.get(pos-1).getType()==StatusDisplayItem.Type.REBLOG_OR_REPLY_LINE){
|
|
||||||
childY+=V.dp(8);
|
|
||||||
}
|
|
||||||
rect.set(child.getX(), i==0 && pos>0 && displayItems.get(pos-1).inset ? V.dp(-10) : childY, child.getX()+child.getWidth(), child.getY()+child.getHeight());
|
|
||||||
}else{
|
|
||||||
rect.bottom=Math.max(rect.bottom, child.getY()+child.getHeight());
|
|
||||||
}
|
|
||||||
}else if(!rect.isEmpty()){
|
|
||||||
drawInsetBackground(parent, c);
|
|
||||||
rect.setEmpty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!rect.isEmpty()){
|
|
||||||
if(pos<displayItems.size()-1 && displayItems.get(pos+1).inset){
|
|
||||||
rect.bottom=parent.getHeight()+V.dp(10);
|
|
||||||
}
|
|
||||||
drawInsetBackground(parent, c);
|
|
||||||
rect.setEmpty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawInsetBackground(RecyclerView list, Canvas c){
|
|
||||||
paint.setStyle(Paint.Style.FILL);
|
|
||||||
paint.setColor(bgColor);
|
|
||||||
rect.left=V.dp(16);
|
|
||||||
rect.right=list.getWidth()-V.dp(16);
|
|
||||||
c.drawRoundRect(rect, V.dp(4), V.dp(4), paint);
|
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
|
||||||
paint.setStrokeWidth(V.dp(1));
|
|
||||||
paint.setColor(borderColor);
|
|
||||||
rect.inset(paint.getStrokeWidth()/2f, paint.getStrokeWidth()/2f);
|
|
||||||
c.drawRoundRect(rect, V.dp(4), V.dp(4), paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state){
|
|
||||||
List<StatusDisplayItem> displayItems=listFragment.getDisplayItems();
|
|
||||||
RecyclerView.ViewHolder holder=parent.getChildViewHolder(view);
|
|
||||||
if(holder instanceof StatusDisplayItem.Holder<?> sdi && sdi.getItem() instanceof StatusDisplayItem item){
|
|
||||||
boolean inset=item.inset;
|
|
||||||
int pos=holder.getAbsoluteAdapterPosition()-listFragment.getMainAdapterOffset();
|
|
||||||
if(inset){
|
|
||||||
boolean topSiblingInset=pos>0 && displayItems.get(pos-1).inset;
|
|
||||||
boolean bottomSiblingInset=pos<displayItems.size()-1 && displayItems.get(pos+1).inset;
|
|
||||||
StatusDisplayItem.Type type=item.getType();
|
|
||||||
if(type==StatusDisplayItem.Type.CARD_LARGE || type==StatusDisplayItem.Type.MEDIA_GRID)
|
|
||||||
outRect.left=outRect.right=V.dp(16);
|
|
||||||
else
|
|
||||||
outRect.left=outRect.right=V.dp(8);
|
|
||||||
if(!bottomSiblingInset)
|
|
||||||
outRect.bottom=V.dp(16);
|
|
||||||
if(!topSiblingInset && pos > 1 && displayItems.get(pos-1) instanceof NotificationHeaderStatusDisplayItem)
|
|
||||||
outRect.top=V.dp(-8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +1,24 @@
|
||||||
package org.joinmastodon.android.ui.utils;
|
package org.joinmastodon.android.ui.utils;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Outline;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewOutlineProvider;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.model.Attachment;
|
import org.joinmastodon.android.model.Attachment;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
|
import org.joinmastodon.android.ui.PhotoLayoutHelper;
|
||||||
import org.joinmastodon.android.ui.displayitems.MediaGridStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.MediaGridStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.drawables.BlurhashCrossfadeDrawable;
|
import org.joinmastodon.android.ui.drawables.BlurhashCrossfadeDrawable;
|
||||||
import org.joinmastodon.android.ui.drawables.PlayIconDrawable;
|
import org.joinmastodon.android.ui.drawables.PlayIconDrawable;
|
||||||
|
import org.joinmastodon.android.ui.views.MediaGridLayout;
|
||||||
|
|
||||||
import me.grishka.appkit.utils.V;
|
import me.grishka.appkit.utils.V;
|
||||||
|
|
||||||
|
@ -32,6 +36,31 @@ public class MediaAttachmentViewController{
|
||||||
private boolean didClear;
|
private boolean didClear;
|
||||||
private Status status;
|
private Status status;
|
||||||
private Attachment attachment;
|
private Attachment attachment;
|
||||||
|
private ViewOutlineProvider outlineProvider=new ViewOutlineProvider(){
|
||||||
|
@Override
|
||||||
|
public void getOutline(View view, Outline outline){
|
||||||
|
MediaGridLayout.LayoutParams lp=(MediaGridLayout.LayoutParams) MediaAttachmentViewController.this.view.getLayoutParams();
|
||||||
|
int mask=lp.tile.getRoundCornersMask();
|
||||||
|
int radius=V.dp(8);
|
||||||
|
if(mask==(PhotoLayoutHelper.CORNER_TL | PhotoLayoutHelper.CORNER_TR | PhotoLayoutHelper.CORNER_BL | PhotoLayoutHelper.CORNER_BR)){
|
||||||
|
outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), radius);
|
||||||
|
}else if(mask==(PhotoLayoutHelper.CORNER_TL | PhotoLayoutHelper.CORNER_TR)){
|
||||||
|
outline.setRoundRect(0, 0, view.getWidth(), view.getHeight()+radius, radius);
|
||||||
|
}else if(mask==(PhotoLayoutHelper.CORNER_BL | PhotoLayoutHelper.CORNER_BR)){
|
||||||
|
outline.setRoundRect(0, -radius, view.getWidth(), view.getHeight(), radius);
|
||||||
|
}else if(mask==PhotoLayoutHelper.CORNER_TL){
|
||||||
|
outline.setRoundRect(0, 0, view.getWidth()+radius, view.getHeight()+radius, radius);
|
||||||
|
}else if(mask==PhotoLayoutHelper.CORNER_TR){
|
||||||
|
outline.setRoundRect(-radius, 0, view.getWidth(), view.getHeight()+radius, radius);
|
||||||
|
}else if(mask==PhotoLayoutHelper.CORNER_BL){
|
||||||
|
outline.setRoundRect(0, -radius, view.getWidth()+radius, view.getHeight(), radius);
|
||||||
|
}else if(mask==PhotoLayoutHelper.CORNER_BR){
|
||||||
|
outline.setRoundRect(-radius, -radius, view.getWidth(), view.getHeight(), radius);
|
||||||
|
}else{
|
||||||
|
outline.setRect(0, 0, view.getWidth(), view.getHeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public MediaAttachmentViewController(Context context, MediaGridStatusDisplayItem.GridItemType type){
|
public MediaAttachmentViewController(Context context, MediaGridStatusDisplayItem.GridItemType type){
|
||||||
view=context.getSystemService(LayoutInflater.class).inflate(switch(type){
|
view=context.getSystemService(LayoutInflater.class).inflate(switch(type){
|
||||||
|
@ -53,6 +82,12 @@ public class MediaAttachmentViewController{
|
||||||
playButton.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
playButton.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||||
playButton.setBackground(new PlayIconDrawable(context));
|
playButton.setBackground(new PlayIconDrawable(context));
|
||||||
}
|
}
|
||||||
|
photo.setOutlineProvider(outlineProvider);
|
||||||
|
photo.setClipToOutline(true);
|
||||||
|
if(failedOverlay!=null){
|
||||||
|
failedOverlay.setOutlineProvider(outlineProvider);
|
||||||
|
failedOverlay.setClipToOutline(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(Attachment attachment, Status status){
|
public void bind(Attachment attachment, Status status){
|
||||||
|
|
|
@ -14,7 +14,6 @@ import android.widget.TextView;
|
||||||
|
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.fragments.ProfileFragment;
|
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||||
import org.joinmastodon.android.model.Account;
|
|
||||||
import org.joinmastodon.android.model.Card;
|
import org.joinmastodon.android.model.Card;
|
||||||
import org.joinmastodon.android.model.viewmodel.CardViewModel;
|
import org.joinmastodon.android.model.viewmodel.CardViewModel;
|
||||||
import org.joinmastodon.android.ui.OutlineProviders;
|
import org.joinmastodon.android.ui.OutlineProviders;
|
||||||
|
|
|
@ -25,6 +25,7 @@ public class FrameLayoutThatOnlyMeasuresFirstChild extends FrameLayout{
|
||||||
View child0=getChildAt(0);
|
View child0=getChildAt(0);
|
||||||
measureChild(child0, widthMeasureSpec, heightMeasureSpec);
|
measureChild(child0, widthMeasureSpec, heightMeasureSpec);
|
||||||
int vpad=getPaddingTop()+getPaddingBottom();
|
int vpad=getPaddingTop()+getPaddingBottom();
|
||||||
super.onMeasure(child0.getMeasuredWidth() | MeasureSpec.EXACTLY, (child0.getMeasuredHeight()+vpad) | MeasureSpec.EXACTLY);
|
int hpad=getPaddingLeft()+getPaddingRight();
|
||||||
|
super.onMeasure((child0.getMeasuredWidth()+hpad) | MeasureSpec.EXACTLY, (child0.getMeasuredHeight()+vpad) | MeasureSpec.EXACTLY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="?android:colorControlHighlight">
|
|
||||||
<item>
|
|
||||||
<shape>
|
|
||||||
<stroke android:width="1dp" android:color="?colorM3Outline"/>
|
|
||||||
<solid android:color="?colorM3Surface"/>
|
|
||||||
<corners android:radius="20dp"/>
|
|
||||||
</shape>
|
|
||||||
</item>
|
|
||||||
<item android:id="@android:id/mask">
|
|
||||||
<shape>
|
|
||||||
<solid android:color="#000"/>
|
|
||||||
<corners android:radius="20dp"/>
|
|
||||||
</shape>
|
|
||||||
</item>
|
|
||||||
</ripple>
|
|
|
@ -1,23 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<item>
|
|
||||||
<shape>
|
|
||||||
<solid android:color="?colorM3Surface"/>
|
|
||||||
<corners android:radius="20dp"/>
|
|
||||||
</shape>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<scale android:scaleGravity="start|fill_vertical" android:scaleWidth="100%">
|
|
||||||
<shape>
|
|
||||||
<solid android:color="@color/poll_option_progress_inset"/>
|
|
||||||
<corners android:radius="20dp"/>
|
|
||||||
</shape>
|
|
||||||
</scale>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<shape>
|
|
||||||
<stroke android:width="1dp" android:color="?colorM3Outline"/>
|
|
||||||
<corners android:radius="20dp"/>
|
|
||||||
</shape>
|
|
||||||
</item>
|
|
||||||
</layer-list>
|
|
|
@ -1,7 +1,11 @@
|
||||||
<?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>
|
||||||
<color android:color="?colorM3SecondaryContainer"/>
|
<shape>
|
||||||
|
<solid android:color="?colorM3SecondaryContainer"/>
|
||||||
|
<stroke android:color="?colorM3OutlineVariant" android:width="1dp"/>
|
||||||
|
<corners android:radius="8dp"/>
|
||||||
|
</shape>
|
||||||
</item>
|
</item>
|
||||||
<item android:gravity="left" android:width="5dp">
|
<item android:gravity="left" android:width="5dp">
|
||||||
<shape>
|
<shape>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="960"
|
||||||
|
android:viewportHeight="960">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M279,899L110,730L279,561L355,637L315,676L694,676L694,520L802,520L802,784L315,784L355,823L279,899ZM158,450L158,186L646,186L606,147L682,71L851,240L682,409L606,333L646,294L266,294L266,450L158,450Z"/>
|
||||||
|
</vector>
|
10
mastodon/src/main/res/drawable/ic_reply_wght700_20px.xml
Normal file
10
mastodon/src/main/res/drawable/ic_reply_wght700_20px.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="960"
|
||||||
|
android:viewportHeight="960"
|
||||||
|
android:autoMirrored="true">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M732,784L732,606Q732,565 704,537Q676,509 635,509L334,509L434,609L352,692L110,450L352,208L434,291L334,391L635,391Q724,391 787,454Q850,517 850,606L850,784L732,784Z"/>
|
||||||
|
</vector>
|
|
@ -4,6 +4,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingBottom="8dp"
|
android:paddingBottom="8dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
android:clipToPadding="false">
|
android:clipToPadding="false">
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
|
|
|
@ -12,19 +12,19 @@
|
||||||
android:id="@+id/reply_btn"
|
android:id="@+id/reply_btn"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:paddingLeft="8dp"
|
android:layout_marginEnd="4dp"
|
||||||
android:paddingRight="8dp"
|
android:paddingHorizontal="8dp"
|
||||||
android:background="?android:actionBarItemBackground"
|
android:background="?android:actionBarItemBackground"
|
||||||
android:minWidth="34dp">
|
android:minWidth="64dp">
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/reply"
|
android:id="@+id/reply"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center|start"
|
||||||
android:drawableStart="@drawable/ic_reply_20px"
|
android:drawableStart="@drawable/ic_reply_20px"
|
||||||
android:drawablePadding="6dp"
|
android:drawablePadding="6dp"
|
||||||
android:drawableTint="?colorM3OnSurfaceVariant"
|
android:drawableTint="?colorM3Outline"
|
||||||
android:textColor="?colorM3OnSurfaceVariant"
|
android:textColor="?colorM3Outline"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:textAppearance="@style/m3_label_medium"
|
android:textAppearance="@style/m3_label_medium"
|
||||||
android:duplicateParentState="true"
|
android:duplicateParentState="true"
|
||||||
|
@ -32,6 +32,7 @@
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<Space
|
<Space
|
||||||
|
android:id="@+id/spacer1"
|
||||||
android:layout_width="0px"
|
android:layout_width="0px"
|
||||||
android:layout_height="1px"
|
android:layout_height="1px"
|
||||||
android:layout_weight="1"/>
|
android:layout_weight="1"/>
|
||||||
|
@ -40,19 +41,19 @@
|
||||||
android:id="@+id/boost_btn"
|
android:id="@+id/boost_btn"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:paddingLeft="8dp"
|
android:layout_marginHorizontal="4dp"
|
||||||
android:paddingRight="8dp"
|
android:paddingHorizontal="8dp"
|
||||||
android:background="?android:actionBarItemBackground"
|
android:background="?android:actionBarItemBackground"
|
||||||
android:minWidth="34dp">
|
android:minWidth="64dp">
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/boost"
|
android:id="@+id/boost"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center|start"
|
||||||
android:drawableStart="@drawable/ic_repeat_selector"
|
android:drawableStart="@drawable/ic_repeat_selector"
|
||||||
android:drawablePadding="6dp"
|
android:drawablePadding="6dp"
|
||||||
android:drawableTint="?colorM3OnSurfaceVariant"
|
android:drawableTint="?colorM3Outline"
|
||||||
android:textColor="?colorM3OnSurfaceVariant"
|
android:textColor="?colorM3Outline"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:textAppearance="@style/m3_label_medium"
|
android:textAppearance="@style/m3_label_medium"
|
||||||
android:duplicateParentState="true"
|
android:duplicateParentState="true"
|
||||||
|
@ -60,6 +61,7 @@
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<Space
|
<Space
|
||||||
|
android:id="@+id/spacer2"
|
||||||
android:layout_width="0px"
|
android:layout_width="0px"
|
||||||
android:layout_height="1px"
|
android:layout_height="1px"
|
||||||
android:layout_weight="1"/>
|
android:layout_weight="1"/>
|
||||||
|
@ -68,19 +70,19 @@
|
||||||
android:id="@+id/favorite_btn"
|
android:id="@+id/favorite_btn"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:paddingLeft="8dp"
|
android:layout_marginHorizontal="4dp"
|
||||||
android:paddingRight="8dp"
|
android:paddingHorizontal="8dp"
|
||||||
android:background="?android:actionBarItemBackground"
|
android:background="?android:actionBarItemBackground"
|
||||||
android:minWidth="34dp">
|
android:minWidth="64dp">
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/favorite"
|
android:id="@+id/favorite"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center|start"
|
||||||
android:drawableStart="@drawable/ic_star_selector"
|
android:drawableStart="@drawable/ic_star_selector"
|
||||||
android:drawablePadding="6dp"
|
android:drawablePadding="6dp"
|
||||||
android:drawableTint="?colorM3OnSurfaceVariant"
|
android:drawableTint="?colorM3Outline"
|
||||||
android:textColor="?colorM3OnSurfaceVariant"
|
android:textColor="?colorM3Outline"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:textAppearance="@style/m3_label_medium"
|
android:textAppearance="@style/m3_label_medium"
|
||||||
android:duplicateParentState="true"
|
android:duplicateParentState="true"
|
||||||
|
@ -96,8 +98,8 @@
|
||||||
android:id="@+id/share_btn"
|
android:id="@+id/share_btn"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:paddingLeft="8dp"
|
android:layout_marginStart="4dp"
|
||||||
android:paddingRight="8dp"
|
android:paddingHorizontal="8dp"
|
||||||
android:background="?android:actionBarItemBackground"
|
android:background="?android:actionBarItemBackground"
|
||||||
android:minWidth="34dp">
|
android:minWidth="34dp">
|
||||||
<ImageView
|
<ImageView
|
||||||
|
@ -106,7 +108,7 @@
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:src="@drawable/ic_share_20px"
|
android:src="@drawable/ic_share_20px"
|
||||||
android:tint="?colorM3OnSurfaceVariant"
|
android:tint="?colorM3Outline"
|
||||||
android:gravity="center_vertical"/>
|
android:gravity="center_vertical"/>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:textAppearance="@style/m3_body_medium"
|
android:textAppearance="@style/m3_body_medium"
|
||||||
android:gravity="center_vertical|start"
|
android:gravity="center_vertical|start"
|
||||||
android:textColor="?colorM3OnSurfaceVariant"
|
android:textColor="?colorM3Outline"
|
||||||
android:textAlignment="viewStart"
|
android:textAlignment="viewStart"
|
||||||
tools:text="9h ago · \@Gargron@mastodon.social"/>
|
tools:text="9h ago · \@Gargron@mastodon.social"/>
|
||||||
|
|
||||||
|
|
|
@ -2,19 +2,20 @@
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingLeft="16dp"
|
android:paddingStart="40dp"
|
||||||
android:paddingRight="16dp"
|
android:paddingEnd="16dp"
|
||||||
android:paddingTop="16dp">
|
android:paddingTop="12dp"
|
||||||
|
android:layout_marginBottom="-8dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text"
|
android:id="@+id/text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="16dp"
|
||||||
android:textAppearance="@style/m3_label_large"
|
android:textAppearance="@style/m3_label_medium"
|
||||||
android:drawableStart="@drawable/ic_repeat_20px"
|
android:drawableTint="?colorM3Outline"
|
||||||
android:drawableTint="?colorM3OnSurfaceVariant"
|
android:textColor="?colorM3Outline"
|
||||||
android:textColor="?colorM3OnSurfaceVariant"
|
android:drawablePadding="8dp"
|
||||||
android:drawablePadding="6dp"
|
android:gravity="center_vertical"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:ellipsize="end"/>
|
android:ellipsize="end"/>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue