Add v7.0: Tabs UI and Real-Time Events

Major Features:
- Dual tab interface (Channels and Events) with visible focus
- Real-time event status calculation (Live, Upcoming, Finished)
- Smart caching system for events (24-hour cache)
- Argentina timezone support (America/Argentina/Buenos_Aires)

UI/TV Improvements:
- Focusable tabs with bg_tab_selector for D-pad navigation
- Visual feedback with highlighted borders on focused tabs
- Consistent design between tabs and content cards
- Enhanced TV navigation experience

Real-Time Event System:
- EventRepository: Centralized event management with 24h cache
- EventAdapter: Optimized RecyclerView for event listings
- EventItem: Structured data model for events
- Dynamic status calculation (remaining time, live duration, completion)
- Automatic link normalization to global2.php

Technical Implementation:
- activity_main.xml: Complete dual-tab layout
- item_event.xml: Dedicated event item layout with RecyclerView
- bg_tab_selector.xml: Tab states (selected, focused, pressed)
- MainActivity.java: Tab switching and event management
- Automatic URL processing for seamless PlayerActivity integration

Time Zone Features:
- Argentina local time (America/Argentina/Buenos_Aires)
- Real-time status updates without page refresh
- "En Xh Ym" for upcoming events
- "En vivo durante 2h" status for live events
- "Finalizado" status for completed events

Solutions:
- Fixed web page "En vivo" not updating issue
- Provides always-current event status in app
- Direct event-to-player navigation without manual intervention
- Improved TV navigation with clear visual feedback

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-14 21:44:04 +00:00
parent ab43ce7794
commit 96c4c360ee
7 changed files with 556 additions and 13 deletions

View File

@@ -14,7 +14,7 @@
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
android:text="Selecciona un canal"
android:text="StreamPlayer"
android:textColor="@color/white"
android:textSize="22sp"
android:textStyle="bold"
@@ -22,6 +22,45 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/tabs_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:gravity="center"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title">
<Button
android:id="@+id/tab_channels"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_weight="1"
android:background="@drawable/bg_tab_selector"
android:focusable="true"
android:focusableInTouchMode="true"
android:text="Canales"
android:textAllCaps="false" />
<Button
android:id="@+id/tab_events"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/bg_tab_selector"
android:focusable="true"
android:focusableInTouchMode="true"
android:text="Eventos"
android:textAllCaps="false" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/channel_grid"
android:layout_width="0dp"
@@ -32,7 +71,47 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title"
app:layout_constraintTop_toBottomOf="@id/tabs_container"
tools:listitem="@layout/item_channel" />
<LinearLayout
android:id="@+id/events_container"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="12dp"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tabs_container">
<ProgressBar
android:id="@+id/events_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
<TextView
android:id="@+id/events_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="16dp"
android:textColor="@color/white"
android:textSize="16sp"
android:visibility="gone"
tools:text="No se pudieron cargar los eventos" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/events_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:clipToPadding="false"
android:paddingBottom="12dp"
tools:listitem="@layout/item_event" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>