New play button & alt text support for gifs & videos
This commit is contained in:
@@ -9,13 +9,11 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.SeekBar;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.joinmastodon.android.AudioPlayerService;
|
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.model.Status;
|
||||||
import org.joinmastodon.android.ui.OutlineProviders;
|
import org.joinmastodon.android.ui.OutlineProviders;
|
||||||
import org.joinmastodon.android.ui.drawables.AudioAttachmentBackgroundDrawable;
|
import org.joinmastodon.android.ui.drawables.AudioAttachmentBackgroundDrawable;
|
||||||
import org.joinmastodon.android.ui.drawables.SeekBarThumbDrawable;
|
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
|
|
||||||
import androidx.palette.graphics.Palette;
|
import androidx.palette.graphics.Palette;
|
||||||
@@ -106,7 +103,7 @@ public class AudioStatusDisplayItem extends StatusDisplayItem{
|
|||||||
@Override
|
@Override
|
||||||
public void onBind(AudioStatusDisplayItem item){
|
public void onBind(AudioStatusDisplayItem item){
|
||||||
int seconds=(int)item.attachment.getDuration();
|
int seconds=(int)item.attachment.getDuration();
|
||||||
String duration=formatDuration(seconds);
|
String duration=UiUtils.formatDuration(seconds);
|
||||||
AudioPlayerService service=AudioPlayerService.getInstance();
|
AudioPlayerService service=AudioPlayerService.getInstance();
|
||||||
if(service!=null && service.getAttachmentID().equals(item.attachment.id)){
|
if(service!=null && service.getAttachmentID().equals(item.attachment.id)){
|
||||||
forwardBtn.setVisibility(View.VISIBLE);
|
forwardBtn.setVisibility(View.VISIBLE);
|
||||||
@@ -171,18 +168,10 @@ public class AudioStatusDisplayItem extends StatusDisplayItem{
|
|||||||
setPlayButtonPlaying(false, true);
|
setPlayButtonPlaying(false, true);
|
||||||
forwardBtn.setVisibility(View.INVISIBLE);
|
forwardBtn.setVisibility(View.INVISIBLE);
|
||||||
rewindBtn.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(){
|
private void updatePosition(){
|
||||||
if(state!=AudioPlayerService.PlayState.PLAYING)
|
if(state!=AudioPlayerService.PlayState.PLAYING)
|
||||||
return;
|
return;
|
||||||
@@ -198,7 +187,7 @@ public class AudioStatusDisplayItem extends StatusDisplayItem{
|
|||||||
int posSeconds=(int)pos;
|
int posSeconds=(int)pos;
|
||||||
if(posSeconds!=lastPosSeconds){
|
if(posSeconds!=lastPosSeconds){
|
||||||
lastPosSeconds=posSeconds;
|
lastPosSeconds=posSeconds;
|
||||||
time.setText(formatDuration(posSeconds)+"/"+formatDuration((int)item.attachment.getDuration()));
|
time.setText(UiUtils.formatDuration(posSeconds)+"/"+UiUtils.formatDuration((int)item.attachment.getDuration()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,22 +2,27 @@ package org.joinmastodon.android.ui.utils;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
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.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
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.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;
|
||||||
|
|
||||||
public class MediaAttachmentViewController{
|
public class MediaAttachmentViewController{
|
||||||
public final View view;
|
public final View view;
|
||||||
public final MediaGridStatusDisplayItem.GridItemType type;
|
public final MediaGridStatusDisplayItem.GridItemType type;
|
||||||
public final ImageView photo;
|
public final ImageView photo;
|
||||||
public final View altButton;
|
public final View altButton;
|
||||||
|
public final TextView duration;
|
||||||
|
public final View playButton;
|
||||||
private BlurhashCrossfadeDrawable crossfadeDrawable=new BlurhashCrossfadeDrawable();
|
private BlurhashCrossfadeDrawable crossfadeDrawable=new BlurhashCrossfadeDrawable();
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private boolean didClear;
|
private boolean didClear;
|
||||||
@@ -31,8 +36,16 @@ public class MediaAttachmentViewController{
|
|||||||
}, null);
|
}, null);
|
||||||
photo=view.findViewById(R.id.photo);
|
photo=view.findViewById(R.id.photo);
|
||||||
altButton=view.findViewById(R.id.alt_button);
|
altButton=view.findViewById(R.id.alt_button);
|
||||||
|
duration=view.findViewById(R.id.duration);
|
||||||
|
playButton=view.findViewById(R.id.play_button);
|
||||||
this.type=type;
|
this.type=type;
|
||||||
this.context=context;
|
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){
|
public void bind(Attachment attachment, Status status){
|
||||||
@@ -46,6 +59,9 @@ public class MediaAttachmentViewController{
|
|||||||
if(altButton!=null){
|
if(altButton!=null){
|
||||||
altButton.setVisibility(TextUtils.isEmpty(attachment.description) ? View.GONE : View.VISIBLE);
|
altButton.setVisibility(TextUtils.isEmpty(attachment.description) ? View.GONE : View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
if(type==MediaGridStatusDisplayItem.GridItemType.VIDEO){
|
||||||
|
duration.setText(UiUtils.formatDuration((int)attachment.getDuration()));
|
||||||
|
}
|
||||||
didClear=false;
|
didClear=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -705,4 +705,12 @@ public class UiUtils{
|
|||||||
toolbar.setTitleTextAppearance(toolbar.getContext(), R.style.m3_title_medium);
|
toolbar.setTitleTextAppearance(toolbar.getContext(), R.style.m3_title_medium);
|
||||||
toolbar.setSubtitleTextAppearance(toolbar.getContext(), R.style.m3_title_small);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<solid android:color="#D9000000"/>
|
<solid android:color="#B2000000"/>
|
||||||
<corners android:radius="4dp"/>
|
<corners android:radius="4dp"/>
|
||||||
</shape>
|
</shape>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
@@ -12,17 +13,47 @@
|
|||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/play_button"
|
android:id="@+id/play_button"
|
||||||
android:layout_width="52dp"
|
android:layout_width="128dp"
|
||||||
android:layout_height="52dp"
|
android:layout_height="128dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"/>
|
||||||
android:elevation="3dp"
|
|
||||||
android:background="@drawable/play_button"/>
|
|
||||||
|
|
||||||
<View
|
<LinearLayout
|
||||||
android:layout_width="28dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="28dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom|end"
|
android:orientation="horizontal"
|
||||||
android:layout_margin="8dp"
|
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>
|
</FrameLayout>
|
||||||
@@ -14,19 +14,19 @@
|
|||||||
<!-- This is hidden from screenreaders because that same alt text is set as content description on the ImageView -->
|
<!-- This is hidden from screenreaders because that same alt text is set as content description on the ImageView -->
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/alt_button"
|
android:id="@+id/alt_button"
|
||||||
android:layout_width="40dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="22dp"
|
android:layout_height="24dp"
|
||||||
|
android:paddingLeft="8dp"
|
||||||
|
android:paddingRight="8dp"
|
||||||
android:layout_gravity="start|bottom"
|
android:layout_gravity="start|bottom"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_margin="8dp"
|
||||||
android:layout_marginRight="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:importantForAccessibility="no"
|
android:importantForAccessibility="no"
|
||||||
android:textAppearance="@style/m3_label_large"
|
android:textAppearance="@style/m3_label_large"
|
||||||
android:textColor="#FFF"
|
android:textColor="#FFF"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:includeFontPadding="false"
|
android:includeFontPadding="false"
|
||||||
android:background="@drawable/bg_image_alt_overlay"
|
android:background="@drawable/bg_image_alt_overlay"
|
||||||
android:text="ALT"/>
|
android:text="ALT"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<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"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/photo"
|
android:id="@+id/photo"
|
||||||
@@ -12,10 +13,48 @@
|
|||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/play_button"
|
android:id="@+id/play_button"
|
||||||
android:layout_width="52dp"
|
android:layout_width="128dp"
|
||||||
android:layout_height="52dp"
|
android:layout_height="128dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"/>
|
||||||
android:elevation="3dp"
|
|
||||||
android:background="@drawable/play_button"/>
|
<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>
|
</FrameLayout>
|
||||||
@@ -14,13 +14,16 @@
|
|||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/alt_button"
|
android:id="@+id/alt_button"
|
||||||
android:layout_width="40dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="22dp"
|
android:layout_height="24dp"
|
||||||
|
android:paddingLeft="8dp"
|
||||||
|
android:paddingRight="8dp"
|
||||||
android:textAppearance="@style/m3_label_large"
|
android:textAppearance="@style/m3_label_large"
|
||||||
android:textColor="#FFF"
|
android:textColor="#FFF"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:includeFontPadding="false"
|
android:includeFontPadding="false"
|
||||||
android:text="ALT"/>
|
android:text="ALT"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/alt_text_close"
|
android:id="@+id/alt_text_close"
|
||||||
|
|||||||
Reference in New Issue
Block a user