Reply lines
This commit is contained in:
parent
ace0072118
commit
de763ab6f7
@ -349,7 +349,11 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
|||||||
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){
|
||||||
parent.getDecoratedBoundsWithMargins(child, tmpRect);
|
parent.getDecoratedBoundsWithMargins(child, tmpRect);
|
||||||
tmpRect.offset(0, Math.round(child.getTranslationY()));
|
tmpRect.offset(0, Math.round(child.getTranslationY()));
|
||||||
float y=tmpRect.bottom-V.dp(.5f);
|
float y=tmpRect.bottom;
|
||||||
|
int strokeWidth=V.dp(0.5f);
|
||||||
|
if(strokeWidth%2==1){
|
||||||
|
y-=0.5f;
|
||||||
|
}
|
||||||
paint.setAlpha(Math.round(255*child.getAlpha()));
|
paint.setAlpha(Math.round(255*child.getAlpha()));
|
||||||
c.drawLine(0, y, parent.getWidth(), y, paint);
|
c.drawLine(0, y, parent.getWidth(), y, paint);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package org.joinmastodon.android.fragments;
|
package org.joinmastodon.android.fragments;
|
||||||
|
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -22,6 +24,7 @@ import org.joinmastodon.android.model.StatusContext;
|
|||||||
import org.joinmastodon.android.ui.OutlineProviders;
|
import org.joinmastodon.android.ui.OutlineProviders;
|
||||||
import org.joinmastodon.android.ui.displayitems.ExtendedFooterStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.ExtendedFooterStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem;
|
||||||
|
import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.SpoilerStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.SpoilerStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.TextStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.TextStatusDisplayItem;
|
||||||
@ -31,7 +34,9 @@ import org.parceler.Parcels;
|
|||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import me.grishka.appkit.Nav;
|
import me.grishka.appkit.Nav;
|
||||||
import me.grishka.appkit.api.SimpleCallback;
|
import me.grishka.appkit.api.SimpleCallback;
|
||||||
@ -49,6 +54,7 @@ public class ThreadFragment extends StatusListFragment{
|
|||||||
private ImageView replyButtonAva;
|
private ImageView replyButtonAva;
|
||||||
private TextView replyButtonText;
|
private TextView replyButtonText;
|
||||||
private int lastBottomInset;
|
private int lastBottomInset;
|
||||||
|
private Paint replyLinePaint=new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState){
|
public void onCreate(Bundle savedInstanceState){
|
||||||
@ -68,7 +74,7 @@ public class ThreadFragment extends StatusListFragment{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
||||||
List<StatusDisplayItem> items=super.buildDisplayItems(s);
|
List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, StatusDisplayItem.FLAG_NO_IN_REPLY_TO);
|
||||||
if(s.id.equals(mainStatus.id)){
|
if(s.id.equals(mainStatus.id)){
|
||||||
for(StatusDisplayItem item:items){
|
for(StatusDisplayItem item:items){
|
||||||
item.fullWidth=true;
|
item.fullWidth=true;
|
||||||
@ -158,6 +164,8 @@ public class ThreadFragment extends StatusListFragment{
|
|||||||
showContent();
|
showContent();
|
||||||
if(!loaded)
|
if(!loaded)
|
||||||
footerProgress.setVisibility(View.VISIBLE);
|
footerProgress.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
list.addItemDecoration(new ReplyLinesItemDecoration());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onStatusCreated(Status status){
|
protected void onStatusCreated(Status status){
|
||||||
@ -223,4 +231,78 @@ public class ThreadFragment extends StatusListFragment{
|
|||||||
public int getSnackbarOffset(){
|
public int getSnackbarOffset(){
|
||||||
return replyContainer.getHeight()-lastBottomInset;
|
return replyContainer.getHeight()-lastBottomInset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawDivider(View child, View bottomSibling, RecyclerView.ViewHolder holder, RecyclerView.ViewHolder siblingHolder, RecyclerView parent, Canvas c, Paint paint){
|
||||||
|
if(holder instanceof StatusDisplayItem.Holder<?> statusHolder && siblingHolder instanceof StatusDisplayItem.Holder<?> siblingStatusHolder){
|
||||||
|
Status siblingStatus=getStatusByID(siblingStatusHolder.getItemID());
|
||||||
|
if(statusHolder.getItemID().equals(siblingStatus.inReplyToId) && siblingStatus!=mainStatus && !statusHolder.getItemID().equals(mainStatus.id))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.drawDivider(child, bottomSibling, holder, siblingHolder, parent, c, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Status findPreviousStatus(String id){
|
||||||
|
for(int i=0;i<data.size();i++){
|
||||||
|
if(data.get(i).id.equals(id))
|
||||||
|
return i>0 ? data.get(i-1) : null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Status findNextStatus(String id){
|
||||||
|
for(int i=0;i<data.size();i++){
|
||||||
|
if(data.get(i).id.equals(id))
|
||||||
|
return i<data.size()-1 ? data.get(i+1) : null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ReplyLinesItemDecoration extends RecyclerView.ItemDecoration{
|
||||||
|
private Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state){
|
||||||
|
String currentID=null;
|
||||||
|
boolean connectUp=false, connectToRoot=false, connectReply=false;
|
||||||
|
paint.setColor(UiUtils.getThemeColor(getActivity(), R.attr.colorM3OutlineVariant));
|
||||||
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
|
paint.setStrokeWidth(V.dp(2));
|
||||||
|
paint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
for(int i=0;i<parent.getChildCount();i++){
|
||||||
|
View child=parent.getChildAt(i);
|
||||||
|
if(!(parent.getChildViewHolder(child) instanceof StatusDisplayItem.Holder<?> holder) || holder.getItemID().equals(mainStatus.id))
|
||||||
|
continue;
|
||||||
|
String itemID=holder.getItemID();
|
||||||
|
if(!Objects.equals(currentID, itemID)){
|
||||||
|
currentID=itemID;
|
||||||
|
Status current=getStatusByID(currentID);
|
||||||
|
Status previous=findPreviousStatus(currentID);
|
||||||
|
Status next=findNextStatus(currentID);
|
||||||
|
|
||||||
|
connectUp=previous!=null && previous.id.equals(current.inReplyToId);
|
||||||
|
connectToRoot=mainStatus.id.equals(current.inReplyToId);
|
||||||
|
connectReply=next!=null && itemID.equals(next.inReplyToId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!connectUp && !connectToRoot && !connectReply)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
float lineX=V.dp(36);
|
||||||
|
c.save();
|
||||||
|
c.clipRect(child.getX(), child.getY(), child.getX()+child.getWidth(), child.getY()+child.getHeight());
|
||||||
|
if(holder instanceof HeaderStatusDisplayItem.Holder){
|
||||||
|
if(connectUp || connectToRoot){
|
||||||
|
c.drawLine(lineX, child.getY()-V.dp(2), lineX, child.getY()+V.dp(14), paint);
|
||||||
|
}
|
||||||
|
if(connectReply){
|
||||||
|
c.drawLine(lineX, child.getY()+V.dp(62), lineX, child.getY()+child.getHeight()+V.dp(2), paint);
|
||||||
|
}
|
||||||
|
}else if(connectReply){
|
||||||
|
c.drawLine(lineX, child.getY(), lineX, child.getY()+child.getHeight(), paint);
|
||||||
|
}
|
||||||
|
c.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ public abstract class StatusDisplayItem{
|
|||||||
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;
|
||||||
public static final int FLAG_NO_HEADER=1 << 4;
|
public static final int FLAG_NO_HEADER=1 << 4;
|
||||||
|
public static final int FLAG_NO_IN_REPLY_TO=1 << 5;
|
||||||
|
|
||||||
public StatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment){
|
public StatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment){
|
||||||
this.parentID=parentID;
|
this.parentID=parentID;
|
||||||
@ -98,7 +99,7 @@ public abstract class StatusDisplayItem{
|
|||||||
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_wght700_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) && (flags & FLAG_NO_IN_REPLY_TO)==0){
|
||||||
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_wght700_20px));
|
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.in_reply_to, account.displayName), account.emojis, R.drawable.ic_reply_wght700_20px));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user