Fix media layout for inset posts

This commit is contained in:
Grishka 2022-03-22 13:34:06 +03:00
parent 7186b6387f
commit d47eb752a5
8 changed files with 56 additions and 18 deletions

View File

@ -10,7 +10,7 @@ android {
applicationId "org.joinmastodon.android" applicationId "org.joinmastodon.android"
minSdk 23 minSdk 23
targetSdk 31 targetSdk 31
versionCode 14 versionCode 15
versionName "0.1" versionName "0.1"
} }

View File

@ -2,7 +2,6 @@ package org.joinmastodon.android.fragments;
import android.app.Activity; import android.app.Activity;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Rect; import android.graphics.Rect;
@ -26,8 +25,6 @@ import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.BetterItemAnimator; import org.joinmastodon.android.ui.BetterItemAnimator;
import org.joinmastodon.android.ui.PhotoLayoutHelper; import org.joinmastodon.android.ui.PhotoLayoutHelper;
import org.joinmastodon.android.ui.TileGridLayoutManager; import org.joinmastodon.android.ui.TileGridLayoutManager;
import org.joinmastodon.android.ui.displayitems.AudioStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.ImageStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.ImageStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.PollFooterStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.PollFooterStatusDisplayItem;
@ -285,7 +282,8 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state){ public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state){
RecyclerView.ViewHolder holder=parent.getChildViewHolder(view); RecyclerView.ViewHolder holder=parent.getChildViewHolder(view);
if(holder instanceof ImageStatusDisplayItem.Holder){ if(holder instanceof ImageStatusDisplayItem.Holder){
int width=Math.min(parent.getWidth(), V.dp(ImageAttachmentFrameLayout.MAX_WIDTH)); int listWidth=getListWidthForMediaLayout();
int width=Math.min(listWidth, V.dp(ImageAttachmentFrameLayout.MAX_WIDTH));
PhotoLayoutHelper.TiledLayoutResult layout=((ImageStatusDisplayItem.Holder<?>) holder).getItem().tiledLayout; PhotoLayoutHelper.TiledLayoutResult layout=((ImageStatusDisplayItem.Holder<?>) holder).getItem().tiledLayout;
PhotoLayoutHelper.TiledLayoutResult.Tile tile=((ImageStatusDisplayItem.Holder<?>) holder).getItem().thisTile; PhotoLayoutHelper.TiledLayoutResult.Tile tile=((ImageStatusDisplayItem.Holder<?>) holder).getItem().thisTile;
if(tile.startCol+tile.colSpan<layout.columnSizes.length){ if(tile.startCol+tile.colSpan<layout.columnSizes.length){
@ -301,20 +299,20 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
} }
// ...and for its siblings, offset those on rows below first to the right where they belong // ...and for its siblings, offset those on rows below first to the right where they belong
if(tile.startCol>0 && layout.tiles[0].rowSpan>1 && tile.startRow>layout.tiles[0].startRow){ if(tile.startCol>0 && layout.tiles[0].rowSpan>1 && tile.startRow>layout.tiles[0].startRow){
int xOffset=Math.round(layout.tiles[0].width/1000f*parent.getWidth()); int xOffset=Math.round(layout.tiles[0].width/1000f*listWidth);
outRect.left=xOffset; outRect.left=xOffset;
outRect.right=-xOffset; outRect.right=-xOffset;
} }
// If the width of the media block is smaller than that of the RecyclerView, offset the views horizontally to center them // If the width of the media block is smaller than that of the RecyclerView, offset the views horizontally to center them
if(parent.getWidth()>width){ if(listWidth>width){
outRect.left+=(parent.getWidth()-V.dp(ImageAttachmentFrameLayout.MAX_WIDTH))/2; outRect.left+=(listWidth-V.dp(ImageAttachmentFrameLayout.MAX_WIDTH))/2;
if(tile.startCol>0){ if(tile.startCol>0){
int spanOffset=0; int spanOffset=0;
for(int i=0;i<tile.startCol;i++){ for(int i=0;i<tile.startCol;i++){
spanOffset+=layout.columnSizes[i]; spanOffset+=layout.columnSizes[i];
} }
outRect.left-=Math.round(spanOffset/1000f*parent.getWidth()); outRect.left-=Math.round(spanOffset/1000f*listWidth);
outRect.left+=Math.round(spanOffset/1000f*width); outRect.left+=Math.round(spanOffset/1000f*width);
} }
} }
@ -604,6 +602,10 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
} }
} }
protected int getListWidthForMediaLayout(){
return list.getWidth();
}
protected class DisplayItemsAdapter extends UsableRecyclerView.Adapter<BindableViewHolder<StatusDisplayItem>> implements ImageLoaderRecyclerAdapter{ protected class DisplayItemsAdapter extends UsableRecyclerView.Adapter<BindableViewHolder<StatusDisplayItem>> implements ImageLoaderRecyclerAdapter{
public DisplayItemsAdapter(){ public DisplayItemsAdapter(){

View File

@ -374,7 +374,6 @@ public class ComposeFragment extends ToolbarFragment implements OnBackPressedLis
while(matcher.find()){ while(matcher.find()){
if(editable.getSpans(start+matcher.start(), start+matcher.end(), ComposeAutocompleteSpan.class).length>0) if(editable.getSpans(start+matcher.start(), start+matcher.end(), ComposeAutocompleteSpan.class).length>0)
continue; continue;
Log.w("11", "found: "+matcher);
ComposeAutocompleteSpan span; ComposeAutocompleteSpan span;
if(TextUtils.isEmpty(matcher.group(4))){ // not an emoji if(TextUtils.isEmpty(matcher.group(4))){ // not an emoji
span=new ComposeHashtagOrMentionSpan(); span=new ComposeHashtagOrMentionSpan();

View File

@ -5,6 +5,7 @@ import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.RectF; import android.graphics.RectF;
import android.media.Image;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
@ -14,6 +15,7 @@ import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.model.Notification; import org.joinmastodon.android.model.Notification;
import org.joinmastodon.android.model.Poll; import org.joinmastodon.android.model.Poll;
import org.joinmastodon.android.model.Status; import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.PhotoLayoutHelper;
import org.joinmastodon.android.ui.displayitems.AccountCardStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.AccountCardStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.ImageStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.ImageStatusDisplayItem;
@ -59,6 +61,13 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
HeaderStatusDisplayItem titleItem=extraText!=null ? new HeaderStatusDisplayItem(n.id, n.account, n.createdAt, this, accountID, null, extraText) : null; HeaderStatusDisplayItem titleItem=extraText!=null ? new HeaderStatusDisplayItem(n.id, n.account, n.createdAt, this, accountID, null, extraText) : null;
if(n.status!=null){ if(n.status!=null){
ArrayList<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, n.status, accountID, n, knownAccounts, titleItem!=null, titleItem==null); ArrayList<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, n.status, accountID, n, knownAccounts, titleItem!=null, titleItem==null);
if(titleItem!=null){
for(StatusDisplayItem item:items){
if(item instanceof ImageStatusDisplayItem){
((ImageStatusDisplayItem) item).horizontalInset=V.dp(32);
}
}
}
if(titleItem!=null) if(titleItem!=null)
items.add(0, titleItem); items.add(0, titleItem);
return items; return items;
@ -205,7 +214,21 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
pad=V.dp(16); pad=V.dp(16);
else else
pad=V.dp(12); pad=V.dp(12);
outRect.left=outRect.right=pad; boolean insetLeft=true, insetRight=true;
if(holder instanceof ImageStatusDisplayItem.Holder){
PhotoLayoutHelper.TiledLayoutResult layout=((ImageStatusDisplayItem.Holder<?>) holder).getItem().tiledLayout;
PhotoLayoutHelper.TiledLayoutResult.Tile tile=((ImageStatusDisplayItem.Holder<?>) holder).getItem().thisTile;
// only inset those items that are on the edges of the layout
insetLeft=tile.startCol==0;
insetRight=tile.startCol+tile.colSpan==layout.columnSizes.length;
// inset all items in the bottom row
if(tile.startRow+tile.rowSpan==layout.rowSizes.length)
bottomSiblingInset=false;
}
if(insetLeft)
outRect.left=pad;
if(insetRight)
outRect.right=pad;
if(!topSiblingInset) if(!topSiblingInset)
outRect.top=pad; outRect.top=pad;
if(!bottomSiblingInset) if(!bottomSiblingInset)

View File

@ -21,6 +21,7 @@ import org.joinmastodon.android.events.FinishReportFragmentsEvent;
import org.joinmastodon.android.fragments.StatusListFragment; import org.joinmastodon.android.fragments.StatusListFragment;
import org.joinmastodon.android.model.Account; import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.Status; import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.PhotoLayoutHelper;
import org.joinmastodon.android.ui.displayitems.AudioStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.AudioStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.ImageStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.ImageStatusDisplayItem;
@ -121,16 +122,20 @@ public class ReportAddPostsChoiceFragment extends StatusListFragment{
return; return;
outRect.left=V.dp(40); outRect.left=V.dp(40);
if(holder instanceof ImageStatusDisplayItem.Holder){ if(holder instanceof ImageStatusDisplayItem.Holder){
ImageStatusDisplayItem.Holder<ImageStatusDisplayItem> imgHolder=(ImageStatusDisplayItem.Holder<ImageStatusDisplayItem>) holder; ImageStatusDisplayItem.Holder<?> imgHolder=(ImageStatusDisplayItem.Holder<?>) holder;
PhotoLayoutHelper.TiledLayoutResult layout=imgHolder.getItem().tiledLayout;
PhotoLayoutHelper.TiledLayoutResult.Tile tile=imgHolder.getItem().thisTile;
String siblingID; String siblingID;
if(holder.getAbsoluteAdapterPosition()<parent.getAdapter().getItemCount()-1){ if(holder.getAbsoluteAdapterPosition()<parent.getAdapter().getItemCount()-1){
siblingID=displayItems.get(holder.getAbsoluteAdapterPosition()-getMainAdapterOffset()+1).parentID; siblingID=displayItems.get(holder.getAbsoluteAdapterPosition()-getMainAdapterOffset()+1).parentID;
}else{ }else{
siblingID=null; siblingID=null;
} }
if(tile.startCol>0)
outRect.left=0;
outRect.left+=V.dp(16); outRect.left+=V.dp(16);
outRect.right=V.dp(16); outRect.right=V.dp(16);
if(!imgHolder.getItemID().equals(siblingID) || imgHolder.getItem().thisTile.startRow+imgHolder.getItem().thisTile.rowSpan==imgHolder.getItem().tiledLayout.rowSizes.length) if(!imgHolder.getItemID().equals(siblingID) || tile.startRow+tile.rowSpan==layout.rowSizes.length)
outRect.bottom=V.dp(16); outRect.bottom=V.dp(16);
}else if(holder instanceof AudioStatusDisplayItem.Holder){ }else if(holder instanceof AudioStatusDisplayItem.Holder){
outRect.bottom=V.dp(16); outRect.bottom=V.dp(16);
@ -222,7 +227,13 @@ 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, true, false); List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, true, false);
for(StatusDisplayItem item:items){
if(item instanceof ImageStatusDisplayItem){
((ImageStatusDisplayItem) item).horizontalInset=V.dp(40+32);
}
}
return items;
} }
protected void drawDivider(View child, View bottomSibling, RecyclerView.ViewHolder holder, RecyclerView.ViewHolder siblingHolder, RecyclerView parent, Canvas c, Paint paint){ protected void drawDivider(View child, View bottomSibling, RecyclerView.ViewHolder holder, RecyclerView.ViewHolder siblingHolder, RecyclerView parent, Canvas c, Paint paint){

View File

@ -27,6 +27,7 @@ public abstract class ImageStatusDisplayItem extends StatusDisplayItem{
public final Status status; public final Status status;
public final PhotoLayoutHelper.TiledLayoutResult tiledLayout; public final PhotoLayoutHelper.TiledLayoutResult tiledLayout;
public final PhotoLayoutHelper.TiledLayoutResult.Tile thisTile; public final PhotoLayoutHelper.TiledLayoutResult.Tile thisTile;
public int horizontalInset;
public ImageStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Attachment photo, Status status, int index, int totalPhotos, PhotoLayoutHelper.TiledLayoutResult tiledLayout, PhotoLayoutHelper.TiledLayoutResult.Tile thisTile){ public ImageStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Attachment photo, Status status, int index, int totalPhotos, PhotoLayoutHelper.TiledLayoutResult tiledLayout, PhotoLayoutHelper.TiledLayoutResult.Tile thisTile){
super(parentID, parentFragment); super(parentID, parentFragment);
@ -63,7 +64,7 @@ public abstract class ImageStatusDisplayItem extends StatusDisplayItem{
@Override @Override
public void onBind(ImageStatusDisplayItem item){ public void onBind(ImageStatusDisplayItem item){
layout.setLayout(item.tiledLayout, item.thisTile); layout.setLayout(item.tiledLayout, item.thisTile, item.horizontalInset);
crossfadeDrawable.setSize(item.attachment.getWidth(), item.attachment.getHeight()); crossfadeDrawable.setSize(item.attachment.getWidth(), item.attachment.getHeight());
crossfadeDrawable.setBlurhashDrawable(item.attachment.blurhashPlaceholder); crossfadeDrawable.setBlurhashDrawable(item.attachment.blurhashPlaceholder);
crossfadeDrawable.setCrossfadeAlpha(item.status.spoilerRevealed ? 0f : 1f); crossfadeDrawable.setCrossfadeAlpha(item.status.spoilerRevealed ? 0f : 1f);

View File

@ -16,6 +16,7 @@ public class ImageAttachmentFrameLayout extends FrameLayout{
private PhotoLayoutHelper.TiledLayoutResult tileLayout; private PhotoLayoutHelper.TiledLayoutResult tileLayout;
private PhotoLayoutHelper.TiledLayoutResult.Tile tile; private PhotoLayoutHelper.TiledLayoutResult.Tile tile;
private int horizontalInset;
public ImageAttachmentFrameLayout(@NonNull Context context){ public ImageAttachmentFrameLayout(@NonNull Context context){
super(context); super(context);
@ -35,7 +36,7 @@ public class ImageAttachmentFrameLayout extends FrameLayout{
super.onMeasure(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return; return;
} }
int w=Math.min(((View)getParent()).getMeasuredWidth(), V.dp(MAX_WIDTH)); int w=Math.min(((View)getParent()).getMeasuredWidth()-horizontalInset, V.dp(MAX_WIDTH));
int actualHeight=Math.round(tile.height/1000f*w)+V.dp(1)*(tile.rowSpan-1); int actualHeight=Math.round(tile.height/1000f*w)+V.dp(1)*(tile.rowSpan-1);
int actualWidth=Math.round(tile.width/1000f*w); int actualWidth=Math.round(tile.width/1000f*w);
if(tile.startCol+tile.colSpan<tileLayout.columnSizes.length) if(tile.startCol+tile.colSpan<tileLayout.columnSizes.length)
@ -45,8 +46,9 @@ public class ImageAttachmentFrameLayout extends FrameLayout{
super.onMeasure(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec);
} }
public void setLayout(PhotoLayoutHelper.TiledLayoutResult layout, PhotoLayoutHelper.TiledLayoutResult.Tile tile){ public void setLayout(PhotoLayoutHelper.TiledLayoutResult layout, PhotoLayoutHelper.TiledLayoutResult.Tile tile, int horizontalInset){
tileLayout=layout; tileLayout=layout;
this.tile=tile; this.tile=tile;
this.horizontalInset=horizontalInset;
} }
} }

View File

@ -10,7 +10,7 @@
<string name="ok">OK</string> <string name="ok">OK</string>
<string name="preparing_auth">Preparing for authentication…</string> <string name="preparing_auth">Preparing for authentication…</string>
<string name="finishing_auth">Finishing authentication…</string> <string name="finishing_auth">Finishing authentication…</string>
<string name="user_boosted">%s boosted</string> <string name="user_boosted">boosted your toot</string>
<string name="in_reply_to">In reply to %s</string> <string name="in_reply_to">In reply to %s</string>
<string name="notifications">Notifications</string> <string name="notifications">Notifications</string>