New play button & alt text support for gifs & videos

This commit is contained in:
Grishka 2023-03-23 03:15:15 +03:00
parent 30b0d226b5
commit c833c03dc3
9 changed files with 201 additions and 41 deletions

View File

@ -9,13 +9,11 @@ import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import org.joinmastodon.android.AudioPlayerService;
@ -25,7 +23,6 @@ import org.joinmastodon.android.model.Attachment;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.OutlineProviders;
import org.joinmastodon.android.ui.drawables.AudioAttachmentBackgroundDrawable;
import org.joinmastodon.android.ui.drawables.SeekBarThumbDrawable;
import org.joinmastodon.android.ui.utils.UiUtils;
import androidx.palette.graphics.Palette;
@ -106,7 +103,7 @@ public class AudioStatusDisplayItem extends StatusDisplayItem{
@Override
public void onBind(AudioStatusDisplayItem item){
int seconds=(int)item.attachment.getDuration();
String duration=formatDuration(seconds);
String duration=UiUtils.formatDuration(seconds);
AudioPlayerService service=AudioPlayerService.getInstance();
if(service!=null && service.getAttachmentID().equals(item.attachment.id)){
forwardBtn.setVisibility(View.VISIBLE);
@ -171,18 +168,10 @@ public class AudioStatusDisplayItem extends StatusDisplayItem{
setPlayButtonPlaying(false, true);
forwardBtn.setVisibility(View.INVISIBLE);
rewindBtn.setVisibility(View.INVISIBLE);
time.setText(formatDuration((int)item.attachment.getDuration()));
time.setText(UiUtils.formatDuration((int)item.attachment.getDuration()));
}
}
@SuppressLint("DefaultLocale")
private String formatDuration(int seconds){
if(seconds>=3600)
return String.format("%d:%02d:%02d", seconds/3600, seconds%3600/60, seconds%60);
else
return String.format("%d:%02d", seconds/60, seconds%60);
}
private void updatePosition(){
if(state!=AudioPlayerService.PlayState.PLAYING)
return;
@ -198,7 +187,7 @@ public class AudioStatusDisplayItem extends StatusDisplayItem{
int posSeconds=(int)pos;
if(posSeconds!=lastPosSeconds){
lastPosSeconds=posSeconds;
time.setText(formatDuration(posSeconds)+"/"+formatDuration((int)item.attachment.getDuration()));
time.setText(UiUtils.formatDuration(posSeconds)+"/"+UiUtils.formatDuration((int)item.attachment.getDuration()));
}
}

View File

@ -0,0 +1,74 @@
package org.joinmastodon.android.ui.drawables;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import me.grishka.appkit.utils.V;
public class PlayIconDrawable extends Drawable{
private final Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);
private final Path path=new Path();
public PlayIconDrawable(Context context){
paint.setShadowLayer(V.dp(32), 0, 0, 0x80000000);
paint.setColor(0xffffffff);
path.moveTo(19.15f,32.5f);
path.lineTo(32.5f,24.0f);
path.lineTo(19.15f,15.5f);
path.moveTo(24.0f,44.0f);
path.quadTo(19.9f,44.0f,16.25f,42.42f);
path.quadTo(12.6f,40.85f,9.88f,38.13f);
path.quadTo(7.15f,35.4f,5.58f,31.75f);
path.quadTo(4.0f,28.1f,4.0f,24.0f);
path.quadTo(4.0f,19.85f,5.58f,16.2f);
path.quadTo(7.15f,12.55f,9.88f,9.85f);
path.quadTo(12.6f,7.15f,16.25f,5.58f);
path.quadTo(19.9f,4.0f,24.0f,4.0f);
path.quadTo(28.15f,4.0f,31.8f,5.58f);
path.quadTo(35.45f,7.15f,38.15f,9.85f);
path.quadTo(40.85f,12.55f,42.42f,16.2f);
path.quadTo(44.0f,19.85f,44.0f,24.0f);
path.quadTo(44.0f,28.1f,42.42f,31.75f);
path.quadTo(40.85f,35.4f,38.15f,38.13f);
path.quadTo(35.45f,40.85f,31.8f,42.42f);
path.quadTo(28.15f,44.0f,24.0f,44.0f);
Matrix matrix=new Matrix();
float density=context.getResources().getDisplayMetrics().density;
matrix.postScale(density*1.3333f, density*1.3333f);
path.transform(matrix);
}
@Override
public void draw(@NonNull Canvas c){
c.save();
Rect bounds=getBounds();
c.translate(bounds.width()/2f-V.dp(32), bounds.height()/2f-V.dp(32));
c.drawPath(path, paint);
c.restore();
}
@Override
public void setAlpha(int alpha){
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter){
}
@Override
public int getOpacity(){
return PixelFormat.TRANSPARENT;
}
}

View File

@ -2,22 +2,27 @@ package org.joinmastodon.android.ui.utils;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import org.joinmastodon.android.R;
import org.joinmastodon.android.model.Attachment;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.displayitems.MediaGridStatusDisplayItem;
import org.joinmastodon.android.ui.drawables.BlurhashCrossfadeDrawable;
import org.joinmastodon.android.ui.drawables.PlayIconDrawable;
public class MediaAttachmentViewController{
public final View view;
public final MediaGridStatusDisplayItem.GridItemType type;
public final ImageView photo;
public final View altButton;
public final TextView duration;
public final View playButton;
private BlurhashCrossfadeDrawable crossfadeDrawable=new BlurhashCrossfadeDrawable();
private final Context context;
private boolean didClear;
@ -31,8 +36,16 @@ public class MediaAttachmentViewController{
}, null);
photo=view.findViewById(R.id.photo);
altButton=view.findViewById(R.id.alt_button);
duration=view.findViewById(R.id.duration);
playButton=view.findViewById(R.id.play_button);
this.type=type;
this.context=context;
if(playButton!=null){
// https://developer.android.com/topic/performance/hardware-accel#drawing-support
if(Build.VERSION.SDK_INT<28)
playButton.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
playButton.setBackground(new PlayIconDrawable(context));
}
}
public void bind(Attachment attachment, Status status){
@ -46,6 +59,9 @@ public class MediaAttachmentViewController{
if(altButton!=null){
altButton.setVisibility(TextUtils.isEmpty(attachment.description) ? View.GONE : View.VISIBLE);
}
if(type==MediaGridStatusDisplayItem.GridItemType.VIDEO){
duration.setText(UiUtils.formatDuration((int)attachment.getDuration()));
}
didClear=false;
}

View File

@ -705,4 +705,12 @@ public class UiUtils{
toolbar.setTitleTextAppearance(toolbar.getContext(), R.style.m3_title_medium);
toolbar.setSubtitleTextAppearance(toolbar.getContext(), R.style.m3_title_small);
}
@SuppressLint("DefaultLocale")
public static String formatDuration(int seconds){
if(seconds>=3600)
return String.format("%d:%02d:%02d", seconds/3600, seconds%3600/60, seconds%60);
else
return String.format("%d:%02d", seconds/60, seconds%60);
}
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#D9000000"/>
<solid android:color="#B2000000"/>
<corners android:radius="4dp"/>
</shape>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@ -12,17 +13,47 @@
<View
android:id="@+id/play_button"
android:layout_width="52dp"
android:layout_height="52dp"
android:layout_gravity="center"
android:elevation="3dp"
android:background="@drawable/play_button"/>
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_gravity="center"/>
<View
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_gravity="bottom|end"
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="8dp"
android:background="@drawable/ic_gif"/>
android:layout_gravity="start|bottom">
<!-- This is hidden from screenreaders because that same alt text is set as content description on the ImageView -->
<TextView
android:id="@+id/alt_button"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:layout_marginEnd="2dp"
android:importantForAccessibility="no"
android:textAppearance="@style/m3_label_large"
android:textColor="#FFF"
android:gravity="center"
android:includeFontPadding="false"
android:background="@drawable/bg_image_alt_overlay"
android:text="ALT"
tools:ignore="HardcodedText" />
<TextView
android:layout_width="wrap_content"
android:layout_height="24dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:layout_marginEnd="2dp"
android:importantForAccessibility="no"
android:textAppearance="@style/m3_label_large"
android:textColor="#FFF"
android:gravity="center"
android:includeFontPadding="false"
android:background="@drawable/bg_image_alt_overlay"
android:text="GIF"
tools:ignore="HardcodedText" />
</LinearLayout>
</FrameLayout>

View File

@ -14,19 +14,19 @@
<!-- This is hidden from screenreaders because that same alt text is set as content description on the ImageView -->
<TextView
android:id="@+id/alt_button"
android:layout_width="40dp"
android:layout_height="22dp"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:layout_gravity="start|bottom"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_margin="8dp"
android:importantForAccessibility="no"
android:textAppearance="@style/m3_label_large"
android:textColor="#FFF"
android:gravity="center"
android:includeFontPadding="false"
android:background="@drawable/bg_image_alt_overlay"
android:text="ALT"/>
android:text="ALT"
tools:ignore="HardcodedText" />
</FrameLayout>

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools">
<ImageView
android:id="@+id/photo"
@ -12,10 +13,48 @@
<View
android:id="@+id/play_button"
android:layout_width="52dp"
android:layout_height="52dp"
android:layout_gravity="center"
android:elevation="3dp"
android:background="@drawable/play_button"/>
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_gravity="center"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="8dp"
android:layout_gravity="start|bottom">
<!-- This is hidden from screenreaders because that same alt text is set as content description on the ImageView -->
<TextView
android:id="@+id/alt_button"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:layout_marginEnd="2dp"
android:importantForAccessibility="no"
android:textAppearance="@style/m3_label_large"
android:textColor="#FFF"
android:gravity="center"
android:includeFontPadding="false"
android:background="@drawable/bg_image_alt_overlay"
android:text="ALT"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:layout_marginEnd="2dp"
android:importantForAccessibility="no"
android:textAppearance="@style/m3_label_large"
android:textColor="#FFF"
android:gravity="center"
android:includeFontPadding="false"
android:background="@drawable/bg_image_alt_overlay"
android:fontFeatureSettings="'tnum'"
tools:text="1:23"/>
</LinearLayout>
</FrameLayout>

View File

@ -14,13 +14,16 @@
<TextView
android:id="@+id/alt_button"
android:layout_width="40dp"
android:layout_height="22dp"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:textAppearance="@style/m3_label_large"
android:textColor="#FFF"
android:gravity="center"
android:includeFontPadding="false"
android:text="ALT"/>
android:text="ALT"
tools:ignore="HardcodedText" />
<ImageButton
android:id="@+id/alt_text_close"