Big changes

This commit is contained in:
ponzischeme89
2026-07-29 15:26:55 +12:00
parent 70914400b4
commit a265636139
73 changed files with 9593 additions and 0 deletions
+161
View File
@@ -0,0 +1,161 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- <merge> rather than a FrameLayout root: setContentView already gives us a full-screen
FrameLayout to merge into, so this saves a redundant level in the view hierarchy. -->
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.media3.ui.PlayerView
android:id="@+id/player_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
app:auto_show="true"
app:controller_layout_id="@layout/memby_player_controls"
app:hide_on_touch="true"
app:keep_content_on_player_reset="true"
app:resize_mode="fit"
app:show_buffering="never"
app:surface_type="surface_view"
app:use_controller="true" />
<!-- 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" />
<!-- App-owned subtitle controls. ExoPlayer supplies tracks and rendering only; this
overlay deliberately stays in Memby's TV design language. -->
<include layout="@layout/player_subtitle_overlay" />
<!-- Cast is metadata-only and never pauses or rebuilds the player. -->
<include layout="@layout/player_cast_overlay" />
<LinearLayout
android:id="@+id/playback_loading"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F2050708"
android:focusable="false"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/playback_loading_logo"
android:layout_width="82dp"
android:layout_height="70dp"
android:contentDescription="@string/playback_loading"
android:scaleType="fitCenter"
android:src="@drawable/emby_logo" />
<TextView
android:id="@+id/playback_loading_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:text="@string/playback_loading"
android:textColor="#FFFFFFFF"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="@+id/playback_loading_hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="7dp"
android:text="@string/playback_loading_hint"
android:textColor="#FF929AA0"
android:textSize="14sp" />
</LinearLayout>
<!-- One cheap overlay, no second ExoPlayer. The programme prepares underneath it. -->
<include layout="@layout/player_preroll" />
<!-- Deliberately outside PlayerView's controller hierarchy: a fatal error must remain
actionable after Media3 hides its transport controls. -->
<FrameLayout
android:id="@+id/playback_error"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F2050708"
android:focusable="false"
android:visibility="gone">
<LinearLayout
android:layout_width="600dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="36dp">
<ImageView
android:layout_width="72dp"
android:layout_height="62dp"
android:contentDescription="@null"
android:scaleType="fitCenter"
android:src="@drawable/emby_logo" />
<TextView
android:id="@+id/playback_error_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:gravity="center"
android:textColor="#FFFFFFFF"
android:textSize="28sp"
android:textStyle="bold" />
<TextView
android:id="@+id/playback_error_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:lineSpacingExtra="3dp"
android:textColor="#BFFFFFFF"
android:textSize="17sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:orientation="horizontal">
<Button
android:id="@+id/playback_error_retry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/next_up_primary_button"
android:focusable="true"
android:minWidth="0dp"
android:paddingStart="28dp"
android:paddingTop="10dp"
android:paddingEnd="28dp"
android:paddingBottom="10dp"
android:stateListAnimator="@null"
android:text="@string/playback_try_again"
android:textAllCaps="false"
android:textColor="@color/next_up_button_text"
android:textSize="16sp" />
<Button
android:id="@+id/playback_error_exit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:background="@drawable/next_up_secondary_button"
android:focusable="true"
android:minWidth="0dp"
android:paddingStart="28dp"
android:paddingTop="10dp"
android:paddingEnd="28dp"
android:paddingBottom="10dp"
android:stateListAnimator="@null"
android:text="@string/playback_back_to_memby"
android:textAllCaps="false"
android:textColor="@color/next_up_button_text"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
</merge>
@@ -0,0 +1,246 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This is a PlayerView controller layout (app:controller_layout_id), so it is bound to
media3-ui's exo_* ids by contract. The transport buttons reuse media3's own icons and
descriptions for the same reason; they are marked private, hence the tools:ignore. If a
media3 upgrade ever drops one, copy it into res/ here rather than un-suppressing. -->
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<View
android:id="@id/exo_controls_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
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" />
<View
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_gravity="bottom"
android:background="@drawable/player_osd_bottom_gradient" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="140dp"
android:layout_gravity="top|start"
android:layout_marginStart="48dp"
android:layout_marginTop="30dp"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:letterSpacing="0.14"
android:text="@string/player_now_playing"
android:textColor="#B8FFFFFF"
android:textSize="11sp" />
<ImageView
android:id="@+id/player_title_logo"
android:layout_width="320dp"
android:layout_height="92dp"
android:layout_marginTop="7dp"
android:adjustViewBounds="true"
android:contentDescription="@string/player_title_logo"
android:scaleType="fitStart"
android:visibility="invisible" />
<TextView
android:id="@+id/player_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:ellipsize="end"
android:maxLines="2"
android:maxWidth="600dp"
android:textColor="#FFFFFFFF"
android:textSize="28sp"
android:textStyle="bold"
android:visibility="gone" />
</LinearLayout>
<TextView
android:id="@+id/player_stream_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|end"
android:layout_marginTop="44dp"
android:layout_marginEnd="48dp"
android:background="@drawable/player_status_background"
android:letterSpacing="0.08"
android:paddingStart="13dp"
android:paddingTop="7dp"
android:paddingEnd="13dp"
android:paddingBottom="7dp"
android:textColor="#DFFFFFFF"
android:textSize="11sp"
android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="210dp"
android:layout_gravity="bottom"
android:gravity="bottom"
android:orientation="vertical"
android:paddingStart="48dp"
android:paddingEnd="48dp"
android:paddingBottom="28dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@id/exo_position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="6dp"
android:paddingEnd="6dp"
android:text="@string/player_position_separator"
android:textColor="#80FFFFFF"
android:textSize="14sp" />
<TextView
android:id="@id/exo_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#AFFFFFFF"
android:textSize="14sp" />
<TextView
android:id="@+id/player_remaining"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="@string/player_loading_duration"
android:textColor="#BFFFFFFF"
android:textSize="13sp" />
</LinearLayout>
<TextView
android:id="@+id/player_finish_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="14sp" />
</LinearLayout>
<androidx.media3.ui.DefaultTimeBar
android:id="@id/exo_progress"
android:layout_width="match_parent"
android:layout_height="34dp"
android:focusable="true"
app:ad_marker_color="#80FFFFFF"
app:bar_height="4dp"
app:buffered_color="#70FFFFFF"
app:played_ad_marker_color="#FFFFFFFF"
app:played_color="#FF52B54B"
app:scrubber_color="#FFFFFFFF"
app:scrubber_dragged_size="18dp"
app:scrubber_enabled_size="14dp"
app:touch_target_height="28dp"
app:unplayed_color="#40FFFFFF" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="72dp"
android:focusable="false">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start|center_vertical"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageButton
android:id="@+id/player_exit"
style="@style/MembyPlayerControlButton"
android:contentDescription="@string/player_back"
android:src="@drawable/ic_player_back" />
<ImageButton
android:id="@+id/player_hide_controls"
style="@style/MembyPlayerControlButton"
android:contentDescription="@string/player_hide_controls"
android:src="@drawable/ic_player_hide" />
</LinearLayout>
<LinearLayout
android:id="@id/exo_center_controls"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal">
<ImageButton
android:id="@id/exo_rew"
style="@style/MembyPlayerControlButton"
android:contentDescription="@string/exo_controls_rewind_description"
android:src="@drawable/exo_icon_rewind"
tools:ignore="PrivateResource" />
<ImageButton
android:id="@id/exo_play_pause"
style="@style/MembyPlayerPrimaryControlButton"
android:contentDescription="@string/exo_controls_play_description"
android:focusedByDefault="true"
android:src="@drawable/exo_icon_play"
tools:ignore="PrivateResource,UnusedAttribute" />
<ImageButton
android:id="@id/exo_ffwd"
style="@style/MembyPlayerControlButton"
android:contentDescription="@string/exo_controls_fastforward_description"
android:src="@drawable/exo_icon_fastforward"
tools:ignore="PrivateResource" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end|center_vertical"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageButton
android:id="@id/exo_subtitle"
style="@style/MembyPlayerControlButton"
android:contentDescription="@string/exo_controls_cc_enabled_description"
android:src="@drawable/exo_ic_subtitle_on"
tools:ignore="PrivateResource" />
<ImageButton
android:id="@id/exo_settings"
style="@style/MembyPlayerControlButton"
android:contentDescription="@string/exo_controls_settings_description"
android:src="@drawable/exo_ic_settings"
tools:ignore="PrivateResource" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</merge>
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/player_cast_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#70000000"
android:clickable="true"
android:focusable="true"
android:visibility="gone">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="340dp"
android:layout_gravity="bottom"
android:background="@drawable/player_overlay_panel_background"
android:orientation="vertical"
android:paddingStart="48dp"
android:paddingTop="25dp"
android:paddingEnd="48dp"
android:paddingBottom="22dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:letterSpacing="0.14"
android:text="@string/player_now_playing"
android:textColor="#FF52B54B"
android:textSize="11sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@string/player_cast"
android:textColor="#FFFFFFFF"
android:textSize="28sp"
android:textStyle="bold" />
<TextView
android:id="@+id/player_cast_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:text="@string/player_cast_loading"
android:textColor="#AFFFFFFF"
android:textSize="14sp" />
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="14dp"
android:layout_weight="1"
android:clipToPadding="false"
android:fillViewport="false"
android:overScrollMode="never">
<LinearLayout
android:id="@+id/player_cast_people"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="top"
android:orientation="horizontal" />
</HorizontalScrollView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/player_back_to_close"
android:textColor="#78FFFFFF"
android:textSize="12sp" />
</LinearLayout>
</FrameLayout>
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- A shallow native end-of-episode overlay. The outgoing PlayerView is scaled into the
open left side while this single prefetched episode card fades in. -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/player_next_up"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:visibility="gone">
<LinearLayout
android:layout_width="420dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:layout_marginEnd="50dp"
android:background="@drawable/next_up_banner_background"
android:orientation="vertical"
android:padding="20dp">
<ImageView
android:id="@+id/player_next_up_image"
android:layout_width="match_parent"
android:layout_height="214dp"
android:background="#FF1B2026"
android:contentDescription="@null"
android:scaleType="centerCrop" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:letterSpacing="0.14"
android:text="@string/next_up_label"
android:textColor="#FF69CD61"
android:textSize="11sp" />
<TextView
android:id="@+id/player_next_up_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:ellipsize="end"
android:maxLines="2"
android:textColor="#FFFFFFFF"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:id="@+id/player_next_up_meta"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="#BFFFFFFF"
android:textSize="13sp" />
<TextView
android:id="@+id/player_next_up_countdown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:textColor="#FF69CD61"
android:textSize="16sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal"
tools:ignore="ButtonStyle">
<Button
android:id="@+id/player_next_up_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/next_up_primary_button"
android:focusable="true"
android:minWidth="0dp"
android:paddingStart="22dp"
android:paddingTop="9dp"
android:paddingEnd="22dp"
android:paddingBottom="9dp"
android:stateListAnimator="@null"
android:text="@string/next_up_play_now"
android:textAllCaps="false"
android:textColor="@color/next_up_button_text"
android:textSize="15sp" />
<Button
android:id="@+id/player_next_up_dismiss"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:background="@drawable/next_up_secondary_button"
android:focusable="true"
android:minWidth="0dp"
android:paddingStart="22dp"
android:paddingTop="9dp"
android:paddingEnd="22dp"
android:paddingBottom="9dp"
android:stateListAnimator="@null"
android:text="@string/next_up_dismiss"
android:textAllCaps="false"
android:textColor="@color/next_up_button_text"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
+118
View File
@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/player_preroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF050708"
android:clickable="true"
android:focusable="false"
android:visibility="gone">
<LinearLayout
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>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Coming up"
android:textColor="#FFFFFFFF"
android:textSize="30sp"
android:textStyle="bold" />
<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" />
<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" />
<LinearLayout
android:id="@+id/player_preroll_today"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
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" />
<LinearLayout
android:id="@+id/player_preroll_week"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="vertical" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/player_subtitle_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#70000000"
android:clickable="true"
android:focusable="true"
android:visibility="gone">
<LinearLayout
android:layout_width="520dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:layout_marginStart="30dp"
android:background="@drawable/player_overlay_panel_background"
android:orientation="vertical"
android:paddingStart="34dp"
android:paddingTop="32dp"
android:paddingEnd="34dp"
android:paddingBottom="26dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:letterSpacing="0.14"
android:text="@string/player_playback_options"
android:textColor="#FF52B54B"
android:textSize="11sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="7dp"
android:text="@string/player_subtitles"
android:textColor="#FFFFFFFF"
android:textSize="30sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="7dp"
android:lineSpacingExtra="2dp"
android:text="@string/player_subtitle_overlay_hint"
android:textColor="#AFFFFFFF"
android:textSize="14sp" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="24dp"
android:layout_weight="1"
android:clipToPadding="false"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:letterSpacing="0.12"
android:text="@string/player_subtitle_track"
android:textColor="#8FFFFFFF"
android:textSize="11sp"
android:textStyle="bold" />
<LinearLayout
android:id="@+id/player_subtitle_tracks"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="9dp"
android:orientation="vertical" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:letterSpacing="0.12"
android:text="@string/player_text_size"
android:textColor="#8FFFFFFF"
android:textSize="11sp"
android:textStyle="bold" />
<LinearLayout
android:id="@+id/player_subtitle_sizes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="9dp"
android:orientation="vertical" />
</LinearLayout>
</ScrollView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="14dp"
android:text="@string/player_back_to_close"
android:textColor="#78FFFFFF"
android:textSize="12sp" />
</LinearLayout>
</FrameLayout>