Publish current app and server

This commit is contained in:
ponzischeme89
2026-08-02 22:10:19 +12:00
parent a265636139
commit 1ed180c739
203 changed files with 23933 additions and 2788 deletions
+25 -1
View File
@@ -18,6 +18,18 @@
app:surface_type="surface_view"
app:use_controller="true" />
<!-- Channel + programme identity. It is owned by the activity rather than the
controller, so it can appear briefly without opening the transport controls. -->
<include layout="@layout/player_playback_identity" />
<!-- 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" />
<!-- Finale context has priority over the ordinary start cue and is physically stacked
above it. Both remain non-focusable lower thirds. -->
<include layout="@layout/player_season_finale" />
<!-- Above the video, below the loading overlay: a slide that is still starting has
nothing to say about what comes next. -->
<include layout="@layout/player_next_up_banner" />
@@ -29,6 +41,17 @@
<!-- Cast is metadata-only and never pauses or rebuilds the player. -->
<include layout="@layout/player_cast_overlay" />
<!-- Service alerts, the same bar the launcher shows. Declared before the loading and
error overlays so those cover it: a notice about the library is not what someone
staring at a failed stream needs. Never focusable, so it cannot take the remote
away from the transport controls. -->
<androidx.compose.ui.platform.ComposeView
android:id="@+id/player_service_alerts"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:focusable="false" />
<LinearLayout
android:id="@+id/playback_loading"
android:layout_width="match_parent"
@@ -66,7 +89,8 @@
android:textSize="14sp" />
</LinearLayout>
<!-- One cheap overlay, no second ExoPlayer. The programme prepares underneath it. -->
<!-- The existing PlayerView is temporarily hosted inside this overlay, then returned
here at full-screen size after the countdown. No second player or stream is used. -->
<include layout="@layout/player_preroll" />
<!-- Deliberately outside PlayerView's controller hierarchy: a fatal error must remain
@@ -14,24 +14,31 @@
android:background="@android:color/transparent" />
<View
android:layout_width="match_parent"
android:layout_height="210dp"
android:layout_gravity="top"
android:background="@drawable/player_osd_top_gradient" />
android:layout_width="720dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@drawable/player_osd_left_gradient" />
<View
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_height="230dp"
android:layout_gravity="bottom"
android:background="@drawable/player_osd_bottom_gradient" />
<!-- Pause is a deliberate browsing moment, rather than just the ordinary OSD frozen
over a frame. It carries the movie context while the transport row below remains
the single, familiar place to resume or seek. -->
<include layout="@layout/player_pause_overlay" />
<LinearLayout
android:id="@+id/player_now_playing_group"
android:layout_width="wrap_content"
android:layout_height="140dp"
android:layout_height="wrap_content"
android:layout_gravity="top|start"
android:layout_marginStart="48dp"
android:layout_marginTop="30dp"
android:gravity="center_vertical"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical">
<TextView
@@ -60,6 +67,8 @@
android:ellipsize="end"
android:maxLines="2"
android:maxWidth="600dp"
android:includeFontPadding="true"
android:lineSpacingExtra="2dp"
android:textColor="#FFFFFFFF"
android:textSize="28sp"
android:textStyle="bold"
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/player_pause_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:visibility="gone">
<View
android:layout_width="820dp"
android:layout_height="match_parent"
android:background="@drawable/player_pause_scrim" />
<LinearLayout
android:layout_width="760dp"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:layout_marginStart="48dp"
android:layout_marginBottom="62dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/player_pause_poster"
android:layout_width="164dp"
android:layout_height="246dp"
android:background="@drawable/player_pause_poster_background"
android:clipToOutline="true"
android:contentDescription="@string/player_pause_poster"
android:outlineProvider="background"
android:scaleType="centerCrop" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:letterSpacing="0.18"
android:text="@string/player_paused"
android:textColor="#FF6BCB63"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/player_pause_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:ellipsize="end"
android:maxLines="2"
android:textColor="#FFFFFFFF"
android:textSize="34sp"
android:textStyle="bold" />
<TextView
android:id="@+id/player_pause_overview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="14dp"
android:ellipsize="end"
android:lineSpacingExtra="3dp"
android:maxLines="5"
android:textColor="#DDE7EBEE"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:text="@string/player_pause_resume_hint"
android:textColor="#B8FFFFFF"
android:textSize="13sp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- A short, non-focusable station ident shown over the first five seconds of content. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/player_playback_identity"
android:layout_width="wrap_content"
android:layout_height="54dp"
android:layout_gravity="start|top"
android:layout_marginStart="48dp"
android:layout_marginTop="34dp"
android:alpha="0"
android:focusable="false"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="gone">
<ImageView
android:layout_width="42dp"
android:layout_height="38dp"
android:contentDescription="@string/player_preroll_brand_logo"
android:scaleType="fitCenter"
android:src="@drawable/emby_logo" />
<TextView
android:id="@+id/player_playback_identity_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="14dp"
android:ellipsize="end"
android:gravity="start|center_vertical"
android:maxLines="1"
android:maxWidth="520dp"
android:shadowColor="#E0000000"
android:shadowDx="0"
android:shadowDy="2"
android:shadowRadius="5"
android:textColor="#FFFFFFFF"
android:textSize="25sp"
android:textStyle="bold" />
</LinearLayout>
+130 -92
View File
@@ -5,114 +5,152 @@
android:layout_height="match_parent"
android:background="#FF050708"
android:clickable="true"
android:clipChildren="false"
android:focusable="false"
android:visibility="gone">
<ImageView
android:id="@+id/player_preroll_brand"
android:layout_width="58dp"
android:layout_height="50dp"
android:layout_gravity="start|top"
android:layout_marginStart="44dp"
android:layout_marginTop="28dp"
android:contentDescription="@string/player_preroll_brand_logo"
android:scaleType="fitCenter"
android:src="@drawable/emby_logo" />
<LinearLayout
android:id="@+id/player_preroll_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="64dp"
android:paddingTop="54dp"
android:paddingEnd="64dp"
android:paddingBottom="54dp">
<!-- Reserved for the eventual pre-roll media asset. Keeping this a plain View is
virtually free and lets the real programme buffer beneath the overlay. -->
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginEnd="52dp"
android:layout_weight="1.62"
android:background="@drawable/player_preroll_video_background">
<ImageView
android:layout_width="74dp"
android:layout_height="64dp"
android:layout_gravity="start|bottom"
android:layout_marginStart="28dp"
android:layout_marginBottom="25dp"
android:alpha="0.24"
android:contentDescription="@null"
android:scaleType="fitCenter"
android:src="@drawable/emby_logo" />
<TextView
android:id="@+id/player_preroll_countdown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_marginEnd="28dp"
android:layout_marginBottom="28dp"
android:background="@drawable/player_status_background"
android:paddingStart="18dp"
android:paddingTop="10dp"
android:paddingEnd="18dp"
android:paddingBottom="10dp"
android:text="@string/player_preroll_countdown_initial"
android:textColor="#FFFFFFFF"
android:textSize="15sp"
android:textStyle="bold" />
</FrameLayout>
android:clipChildren="false"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingStart="44dp"
android:paddingTop="84dp"
android:paddingEnd="44dp"
android:paddingBottom="22dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
android:layout_width="match_parent"
android:layout_height="224dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Coming up"
android:textColor="#FFFFFFFF"
android:textSize="30sp"
android:textStyle="bold" />
<FrameLayout
android:id="@+id/player_preroll_video_host"
android:layout_width="398dp"
android:layout_height="224dp"
android:layout_marginEnd="38dp"
android:background="@drawable/player_preroll_video_background"
android:clipToOutline="true"
android:foreground="@drawable/player_preroll_video_frame"
android:outlineProvider="background">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="From your Sonarr calendar"
android:textColor="#FF8E979D"
android:textSize="13sp" />
<LinearLayout
android:id="@+id/player_preroll_countdown_container"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_marginEnd="18dp"
android:layout_marginBottom="16dp"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/player_preroll_today_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:text="AIRING TODAY"
android:textAllCaps="true"
android:textColor="#FF55B94D"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="@string/player_preroll_starting_in"
android:textAllCaps="true"
android:textColor="#CCFFFFFF"
android:textSize="9sp"
android:textStyle="bold" />
<com.ponzischeme89.memby.ui.player.PrerollCountdownView
android:id="@+id/player_preroll_countdown"
android:layout_width="66dp"
android:layout_height="66dp"
android:contentDescription="@string/player_preroll_countdown_initial" />
</LinearLayout>
</FrameLayout>
<LinearLayout
android:id="@+id/player_preroll_today"
android:layout_width="match_parent"
android:id="@+id/player_preroll_schedule_panel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="vertical" />
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/player_preroll_week_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="22dp"
android:text="THIS WEEK"
android:textAllCaps="true"
android:textColor="#FF8E979D"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="NOW"
android:textColor="#FF64C85A"
android:textSize="11sp"
android:textStyle="bold" />
<LinearLayout
android:id="@+id/player_preroll_week"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="vertical" />
<TextView
android:id="@+id/player_preroll_now_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="7dp"
android:ellipsize="end"
android:maxLines="2"
android:text="Northbound · The Crossing"
android:textColor="#FFFFFFFF"
android:textSize="26sp"
android:textStyle="bold" />
<TextView
android:id="@+id/player_preroll_now_metadata"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="S02E04 · 48 mins"
android:textColor="#FFD0D6DB"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/player_preroll_now_overview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:ellipsize="end"
android:maxLines="3"
android:text="The crew follows a signal beyond the last charted crossing and finds the shore waiting for them."
android:textColor="#FFB1BAC1"
android:textSize="13sp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="4dp"
android:paddingEnd="4dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="UPCOMING"
android:textColor="#FF64C85A"
android:textSize="11sp"
android:textStyle="bold" />
</LinearLayout>
<GridLayout
android:id="@+id/player_preroll_calendar"
android:layout_width="match_parent"
android:layout_height="170dp"
android:layout_marginTop="5dp"
android:columnCount="4"
android:rowCount="2"
android:useDefaultMargins="false" />
</LinearLayout>
</FrameLayout>
@@ -0,0 +1,66 @@
<?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="80dp"
android:background="@drawable/player_preroll_card_background"
android:clipToOutline="true"
android:outlineProvider="background">
<ImageView
android:id="@+id/player_preroll_card_artwork"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@null"
android:scaleType="centerCrop" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/player_preroll_card_scrim" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingStart="10dp"
android:paddingTop="8dp"
android:paddingEnd="9dp"
android:paddingBottom="8dp">
<TextView
android:id="@+id/player_preroll_card_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAllCaps="true"
android:textColor="#FF64C85A"
android:textSize="8sp"
android:textStyle="bold" />
<TextView
android:id="@+id/player_preroll_card_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="#FFFFFFFF"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:id="@+id/player_preroll_card_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="#FFD0D6DB"
android:textSize="9sp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/player_preroll_card_frame" />
</FrameLayout>
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Finale context is a separate, higher-priority lower third. It sits above the normal
start/time cue so both can be read together and never takes focus from playback. -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/player_season_finale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|start"
android:layout_marginStart="52dp"
android:layout_marginBottom="120dp"
android:clipChildren="false"
android:clipToPadding="false"
android:focusable="false"
android:visibility="gone">
<LinearLayout
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:paddingEnd="18dp">
<View
android:layout_width="3dp"
android:layout_height="32dp"
android:background="#FFFFB454" />
<ImageView
android:layout_width="30dp"
android:layout_height="27dp"
android:layout_marginStart="10dp"
android:contentDescription="@null"
android:scaleType="fitCenter"
android:src="@drawable/emby_logo" />
<TextView
android:id="@+id/player_season_finale_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:letterSpacing="0.16"
android:paddingTop="9dp"
android:paddingBottom="9dp"
android:text="@string/player_season_finale_label"
android:textColor="#FFFFC778"
android:textSize="10sp"
android:textStyle="bold" />
<TextView
android:id="@+id/player_season_finale_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:ellipsize="end"
android:maxLines="1"
android:paddingTop="9dp"
android:paddingBottom="9dp"
android:textColor="#FFFFFFFF"
android:textSize="14sp"
android:textStyle="bold"
tools:text="Signal Hill · Season 2 finale" />
</LinearLayout>
</FrameLayout>
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- The ten-minute lower third. A single non-focusable strip pinned to the lower left,
inside the TV overscan margin, that rolls up from below its own baseline and rolls
back down again. It never takes the remote and never covers the transport controls. -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/player_time_remaining"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|start"
android:layout_marginStart="52dp"
android:layout_marginBottom="72dp"
android:clipChildren="false"
android:clipToPadding="false"
android:focusable="false"
android:visibility="gone">
<LinearLayout
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:paddingStart="0dp"
android:paddingEnd="18dp">
<!-- Keep the cue recognisably Memby even when it appears independently of the
transport OSD. The accent rule still distinguishes ordinary timing cues. -->
<View
android:layout_width="3dp"
android:layout_height="26dp"
android:background="#FF69CD61" />
<ImageView
android:layout_width="27dp"
android:layout_height="24dp"
android:layout_marginStart="10dp"
android:contentDescription="@null"
android:scaleType="fitCenter"
android:src="@drawable/emby_logo" />
<TextView
android:id="@+id/player_time_remaining_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:letterSpacing="0.16"
android:paddingTop="7dp"
android:paddingBottom="7dp"
android:text="@string/player_time_remaining_label"
android:textColor="#99FFFFFF"
android:textSize="10sp" />
<TextView
android:id="@+id/player_time_remaining_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:paddingTop="7dp"
android:paddingBottom="7dp"
android:textColor="#FFFFFFFF"
android:textSize="14sp"
android:textStyle="bold"
tools:text="10 mins" />
</LinearLayout>
</FrameLayout>