App v0.2.27 and gateway 0.1.23
Skip Intro from Emby's own chapter markers, trickplay seek previews from BIF files, a server-composed home hero ranked on Radarr/Sonarr dates and review scores, and My Alerts as its own page behind the user picker. Related titles now degrade at every step instead of returning empty, and the "+" is back on Manage users so a second viewer can be added from the launcher. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
4a4df7a73c
commit
80c304d86b
@@ -27,6 +27,11 @@
|
||||
appears once matters more than one that appears on every press. -->
|
||||
<include layout="@layout/player_seek_indicator" />
|
||||
|
||||
<!-- The offer to skip the opening titles. Declared here so the banners and overlays
|
||||
below cover it: it lives in the bottom-end corner and belongs to the first two
|
||||
minutes of an episode, where none of them has anything to say yet. -->
|
||||
<include layout="@layout/player_skip_intro" />
|
||||
|
||||
<!-- The ten-minute cue. Declared before the next-up banner so that banner covers it
|
||||
if the two ever coincide: what comes next matters more than how long is left. -->
|
||||
<include layout="@layout/player_time_remaining" />
|
||||
|
||||
@@ -17,44 +17,71 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/time_remaining_cue_background"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="18dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingEnd="22dp"
|
||||
android:paddingBottom="12dp">
|
||||
|
||||
<!-- The frame the skip will land on, from Emby's preview thumbnails. It is gone
|
||||
rather than blank when a title has none, or before the first one arrives: the
|
||||
chip below it is a complete answer on its own, and a thumbnail-shaped hole
|
||||
over somebody's film says only that something is missing.
|
||||
|
||||
The height is what settles the size, and it is a compromise with the source:
|
||||
Emby generates these 320px wide, so 120dp is about a third larger than native
|
||||
on a 1080p set — big enough to read a scene across a room, and not so big that
|
||||
the upscaling is what the viewer notices. The width here is only the 16:9
|
||||
placeholder the chip is laid out at before the frames' real shape is known. -->
|
||||
<ImageView
|
||||
android:id="@+id/player_seek_glyph"
|
||||
android:layout_width="26dp"
|
||||
android:layout_height="26dp"
|
||||
android:id="@+id/player_seek_preview"
|
||||
android:layout_width="214dp"
|
||||
android:layout_height="120dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:background="#FF000000"
|
||||
android:contentDescription="@null"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_player_forward" />
|
||||
android:visibility="gone" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="14dp"
|
||||
android:orientation="vertical">
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/player_seek_amount"
|
||||
<ImageView
|
||||
android:id="@+id/player_seek_glyph"
|
||||
android:layout_width="26dp"
|
||||
android:layout_height="26dp"
|
||||
android:contentDescription="@null"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_player_forward" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#FFFFFFFF"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="Forward 30 seconds" />
|
||||
android:layout_marginStart="14dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/player_seek_position"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:textColor="#99FFFFFF"
|
||||
android:textSize="13sp"
|
||||
tools:text="12:34 / 1:45:00" />
|
||||
<TextView
|
||||
android:id="@+id/player_seek_amount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#FFFFFFFF"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="Forward 30 seconds" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/player_seek_position"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:textColor="#99FFFFFF"
|
||||
android:textSize="13sp"
|
||||
tools:text="12:34 / 1:45:00" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- The offer to jump past an episode's opening titles.
|
||||
|
||||
It sits over somebody's film, so it is one control and nothing else: no panel, no
|
||||
scrim, no explanation. The bottom-end corner is where every television client puts
|
||||
this, which is most of why it needs no label saying what it is — and it clears the
|
||||
transport row's own 48dp inset and 72dp strip, so raising the controls does not put
|
||||
the two on top of each other.
|
||||
|
||||
The whole view is gone rather than invisible while it has nothing to offer, because a
|
||||
button-shaped hole in the corner of a film says only that something is missing. -->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/player_skip_intro"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginEnd="48dp"
|
||||
android:layout_marginBottom="112dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<!-- The row is what is focusable, not the pieces in it: a remote has one idea of
|
||||
"this", and two focusable children would be two stops on the way past a single
|
||||
button. Focusable at all, unlike the timing cues and the alert bar beside it,
|
||||
because this one is meant to be pressed and focus is the only way a remote can say
|
||||
so. PlayerActivity gives it focus as it appears and hands focus back to the video
|
||||
when it goes. -->
|
||||
<LinearLayout
|
||||
android:id="@+id/player_skip_intro_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/next_up_primary_button"
|
||||
android:focusable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="14dp"
|
||||
android:paddingTop="11dp"
|
||||
android:paddingEnd="24dp"
|
||||
android:paddingBottom="11dp">
|
||||
|
||||
<!-- How long is left to press it. duplicateParentState is load-bearing: the pill
|
||||
inverts to white on focus, and without the parent's state reaching this the
|
||||
ring would keep drawing white on white. -->
|
||||
<com.ponzischeme89.memby.ui.player.SkipIntroCountdownView
|
||||
android:id="@+id/player_skip_intro_countdown"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:duplicateParentState="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/player_skip_intro_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:duplicateParentState="true"
|
||||
android:text="@string/player_skip_intro"
|
||||
android:textColor="@color/next_up_button_text"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="Skip intro" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
@@ -59,6 +59,12 @@
|
||||
</plurals>
|
||||
<string name="player_seek_forward">Forward %1$s</string>
|
||||
<string name="player_seek_back">Back %1$s</string>
|
||||
<!-- "Intro" rather than "the opening titles": it is the word every other television
|
||||
client uses for this button, and a button is read at a glance or not at all. -->
|
||||
<string name="player_skip_intro">Skip intro</string>
|
||||
<string name="player_skip_intro_skipped">Intro skipped</string>
|
||||
<!-- Spoken for the ring, which is a shape and says nothing on its own. -->
|
||||
<string name="player_skip_intro_countdown">%1$s left</string>
|
||||
<string name="next_up_label">NEXT UP</string>
|
||||
<string name="next_up_play_now">Play now</string>
|
||||
<string name="next_up_dismiss">Dismiss</string>
|
||||
|
||||
Reference in New Issue
Block a user