Discover stuff

This commit is contained in:
Grishka
2022-03-02 12:38:14 +03:00
parent bb9cf5f5df
commit 9f0b55918d
41 changed files with 1435 additions and 71 deletions

View File

@@ -0,0 +1,43 @@
package org.joinmastodon.android.ui;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;
import org.joinmastodon.android.ui.utils.UiUtils;
import androidx.annotation.AttrRes;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import me.grishka.appkit.utils.V;
public class DividerItemDecoration extends RecyclerView.ItemDecoration{
private Paint paint=new Paint();
private int paddingStart, paddingEnd;
public DividerItemDecoration(Context context, @AttrRes int color, float thicknessDp, int paddingStartDp, int paddingEndDp){
paint.setColor(UiUtils.getThemeColor(context, color));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(V.dp(thicknessDp));
paddingStart=V.dp(paddingStartDp);
paddingEnd=V.dp(paddingEndDp);
}
@Override
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state){
boolean isRTL=parent.getLayoutDirection()==View.LAYOUT_DIRECTION_RTL;
int padLeft=isRTL ? paddingEnd : paddingStart;
int padRight=isRTL ? paddingStart : paddingEnd;
int totalItems=parent.getAdapter().getItemCount();
for(int i=0;i<parent.getChildCount();i++){
View child=parent.getChildAt(i);
int pos=parent.getChildAdapterPosition(child);
if(pos<totalItems-1){
float y=Math.round(child.getY()+child.getHeight()-paint.getStrokeWidth()/2f);
paint.setAlpha(Math.round(255f*child.getAlpha()));
c.drawLine(padLeft+child.getX(), y, child.getX()+child.getWidth()-padRight, y, paint);
}
}
}
}

View File

@@ -1,10 +1,15 @@
package org.joinmastodon.android.ui;
import android.graphics.Outline;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewOutlineProvider;
import me.grishka.appkit.utils.V;
public class OutlineProviders{
private static SparseArray<ViewOutlineProvider> roundedRects=new SparseArray<>();
private OutlineProviders(){
//no instance
}
@@ -16,4 +21,26 @@ public class OutlineProviders{
outline.setAlpha(view.getAlpha());
}
};
public static ViewOutlineProvider roundedRect(int dp){
ViewOutlineProvider provider=roundedRects.get(dp);
if(provider!=null)
return provider;
provider=new RoundRectOutlineProvider(V.dp(dp));
roundedRects.put(dp, provider);
return provider;
}
private static class RoundRectOutlineProvider extends ViewOutlineProvider{
private final int radius;
private RoundRectOutlineProvider(int radius){
this.radius=radius;
}
@Override
public void getOutline(View view, Outline outline){
outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), radius);
}
}
}

View File

@@ -0,0 +1,12 @@
package org.joinmastodon.android.ui;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class SimpleViewHolder extends RecyclerView.ViewHolder{
public SimpleViewHolder(@NonNull View itemView){
super(itemView);
}
}

View File

@@ -1,7 +1,6 @@
package org.joinmastodon.android.ui.displayitems;
import android.app.Activity;
import android.app.Fragment;
import android.graphics.Outline;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
@@ -24,6 +23,7 @@ import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.Attachment;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.text.HtmlParser;
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.parceler.Parcels;
@@ -50,7 +50,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
super(parentID, parentFragment);
this.user=user;
this.createdAt=createdAt;
avaRequest=new UrlImageLoaderRequest(user.avatar);
avaRequest=new UrlImageLoaderRequest(user.avatar, V.dp(50), V.dp(50));
this.accountID=accountID;
parsedName=new SpannableStringBuilder(user.displayName);
this.status=status;

View File

@@ -3,7 +3,6 @@ package org.joinmastodon.android.ui.displayitems;
import android.app.Activity;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.util.StateSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
@@ -12,6 +11,7 @@ import org.joinmastodon.android.R;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.model.Poll;
import org.joinmastodon.android.ui.text.HtmlParser;
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
import java.util.Locale;

View File

@@ -11,6 +11,7 @@ import org.joinmastodon.android.R;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.model.Emoji;
import org.joinmastodon.android.ui.text.HtmlParser;
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
import org.joinmastodon.android.ui.utils.UiUtils;
import java.util.List;

View File

@@ -11,6 +11,7 @@ import android.widget.TextView;
import org.joinmastodon.android.R;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
import org.joinmastodon.android.ui.views.LinkedTextView;
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;

View File

@@ -2325,8 +2325,8 @@ public class TabLayout extends HorizontalScrollView {
/** A {@link LinearLayout} containing {@link Tab} instances for use with {@link TabLayout}. */
public final class TabView extends LinearLayout {
private Tab tab;
private TextView textView;
private ImageView iconView;
public TextView textView;
public ImageView iconView;
@Nullable private View badgeAnchorView;
// @Nullable private BadgeDrawable badgeDrawable;

View File

@@ -1,4 +1,4 @@
package org.joinmastodon.android.ui.displayitems;
package org.joinmastodon.android.ui.utils;
import android.graphics.drawable.Drawable;
import android.text.Spanned;
@@ -12,7 +12,7 @@ import java.util.stream.Collectors;
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
class CustomEmojiHelper{
public class CustomEmojiHelper{
public List<List<CustomEmojiSpan>> spans=new ArrayList<>();
public List<ImageLoaderRequest> requests=new ArrayList<>();

View File

@@ -13,12 +13,14 @@ import android.os.Looper;
import android.provider.OpenableColumns;
import android.text.Spanned;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.joinmastodon.android.E;
import org.joinmastodon.android.MastodonApp;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.accounts.SetAccountBlocked;
import org.joinmastodon.android.api.requests.accounts.SetAccountFollowed;
import org.joinmastodon.android.api.requests.accounts.SetAccountMuted;
import org.joinmastodon.android.api.requests.statuses.DeleteStatus;
import org.joinmastodon.android.events.StatusDeletedEvent;
@@ -200,7 +202,7 @@ public class UiUtils{
public static void confirmToggleBlockUser(Activity activity, String accountID, Account account, boolean currentlyBlocked, Consumer<Relationship> resultCallback){
showConfirmationAlert(activity, activity.getString(currentlyBlocked ? R.string.confirm_unblock_title : R.string.confirm_block_title),
activity.getString(currentlyBlocked ? R.string.confirm_unblock : R.string.confirm_block, account.displayName),
activity.getString(currentlyBlocked ? R.string.do_block : R.string.do_unblock), ()->{
activity.getString(currentlyBlocked ? R.string.do_unblock : R.string.do_block), ()->{
new SetAccountBlocked(account.id, !currentlyBlocked)
.setCallback(new Callback<>(){
@Override
@@ -258,4 +260,39 @@ public class UiUtils{
.exec(accountID);
});
}
public static void setRelationshipToActionButton(Relationship relationship, Button button){
if(relationship.blocking){
button.setText(R.string.button_blocked);
}else if(relationship.muting){
button.setText(R.string.button_muted);
}else{
button.setText(relationship.following ? R.string.button_following : R.string.button_follow);
}
}
public static void performAccountAction(Activity activity, Account account, String accountID, Relationship relationship, Button button, Consumer<Boolean> progressCallback, Consumer<Relationship> resultCallback){
if(relationship.blocking){
confirmToggleBlockUser(activity, accountID, account, true, resultCallback);
}else if(relationship.muting){
confirmToggleMuteUser(activity, accountID, account, true, resultCallback);
}else{
progressCallback.accept(true);
new SetAccountFollowed(account.id, !relationship.following)
.setCallback(new Callback<>(){
@Override
public void onSuccess(Relationship result){
resultCallback.accept(result);
progressCallback.accept(false);
}
@Override
public void onError(ErrorResponse error){
error.showToast(activity);
progressCallback.accept(false);
}
})
.exec(accountID);
}
}
}

View File

@@ -0,0 +1,94 @@
package org.joinmastodon.android.ui.views;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
import org.joinmastodon.android.R;
import org.joinmastodon.android.model.History;
import org.joinmastodon.android.ui.utils.UiUtils;
import java.util.List;
import me.grishka.appkit.utils.V;
public class HashtagChartView extends View{
private Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);
private Path strokePath=new Path(), fillPath=new Path();
private CornerPathEffect pathEffect=new CornerPathEffect(V.dp(3));
private float[] relativeOffsets=new float[7];
public HashtagChartView(Context context){
this(context, null);
}
public HashtagChartView(Context context, AttributeSet attrs){
this(context, attrs, 0);
}
public HashtagChartView(Context context, AttributeSet attrs, int defStyle){
super(context, attrs, defStyle);
paint.setStrokeWidth(V.dp(1.71f));
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeJoin(Paint.Join.ROUND);
}
public void setData(List<History> data){
int max=0;
for(History h:data){
max=Math.max(h.accounts, max);
}
if(relativeOffsets.length!=data.size())
relativeOffsets=new float[data.size()];
int i=0;
for(History h:data){
relativeOffsets[i]=(float)h.accounts/max;
i++;
}
updatePath();
}
private void updatePath(){
if(getWidth()<1)
return;
strokePath.rewind();
fillPath.rewind();
float step=(getWidth()-V.dp(2))/(float)(relativeOffsets.length-1);
float maxH=getHeight()-V.dp(2);
float x=getWidth()-V.dp(1);
strokePath.moveTo(x, maxH-maxH*relativeOffsets[0]+V.dp(1));
fillPath.moveTo(getWidth(), getHeight()-V.dp(1));
fillPath.lineTo(x, maxH-maxH*relativeOffsets[0]+V.dp(1));
for(int i=1;i<relativeOffsets.length;i++){
float offset=relativeOffsets[i];
x-=step;
float y=maxH-maxH*offset+V.dp(1);
strokePath.lineTo(x, y);
fillPath.lineTo(x, y);
}
fillPath.lineTo(V.dp(1), getHeight()-V.dp(1));
fillPath.close();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh){
super.onSizeChanged(w, h, oldw, oldh);
updatePath();
}
@Override
protected void onDraw(Canvas canvas){
paint.setStyle(Paint.Style.FILL);
paint.setColor(UiUtils.getThemeColor(getContext(), R.attr.colorAccentLightest));
paint.setPathEffect(null);
canvas.drawPath(fillPath, paint);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(UiUtils.getThemeColor(getContext(), android.R.attr.colorAccent));
paint.setPathEffect(pathEffect);
canvas.drawPath(strokePath, paint);
}
}