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>
98 lines
3.0 KiB
Java
98 lines
3.0 KiB
Java
package com.streamplayer;
|
|
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.TextView;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
|
|
public class EventAdapter extends RecyclerView.Adapter<EventAdapter.EventViewHolder> {
|
|
|
|
public interface OnEventClickListener {
|
|
void onEventClick(EventItem event);
|
|
}
|
|
|
|
private final List<EventItem> events = new ArrayList<>();
|
|
private final OnEventClickListener listener;
|
|
|
|
public EventAdapter(OnEventClickListener listener) {
|
|
this.listener = listener;
|
|
}
|
|
|
|
public void submitList(List<EventItem> newEvents) {
|
|
events.clear();
|
|
events.addAll(newEvents);
|
|
notifyDataSetChanged();
|
|
}
|
|
|
|
@NonNull
|
|
@Override
|
|
public EventViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
|
View view = LayoutInflater.from(parent.getContext())
|
|
.inflate(R.layout.item_event, parent, false);
|
|
return new EventViewHolder(view);
|
|
}
|
|
|
|
@Override
|
|
public void onBindViewHolder(@NonNull EventViewHolder holder, int position) {
|
|
EventItem event = events.get(position);
|
|
holder.title.setText(event.getTitle());
|
|
holder.time.setText(event.getTime());
|
|
holder.channel.setText(event.getChannelName());
|
|
holder.status.setText(buildStatusText(event));
|
|
holder.itemView.setOnClickListener(v -> {
|
|
if (listener != null) {
|
|
listener.onEventClick(event);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public int getItemCount() {
|
|
return events.size();
|
|
}
|
|
|
|
static class EventViewHolder extends RecyclerView.ViewHolder {
|
|
final TextView title;
|
|
final TextView time;
|
|
final TextView channel;
|
|
final TextView status;
|
|
|
|
EventViewHolder(@NonNull View itemView) {
|
|
super(itemView);
|
|
title = itemView.findViewById(R.id.event_title);
|
|
time = itemView.findViewById(R.id.event_time);
|
|
channel = itemView.findViewById(R.id.event_channel);
|
|
status = itemView.findViewById(R.id.event_status);
|
|
}
|
|
}
|
|
|
|
private String buildStatusText(EventItem event) {
|
|
long start = event.getStartMillis();
|
|
if (start <= 0) {
|
|
return event.getStatus();
|
|
}
|
|
long now = System.currentTimeMillis();
|
|
long diff = start - now;
|
|
if (diff > 0) {
|
|
long hours = diff / 3600000;
|
|
long minutes = (diff % 3600000) / 60000;
|
|
if (hours > 0) {
|
|
return String.format(Locale.getDefault(), "En %dh %02dm", hours, minutes);
|
|
} else {
|
|
return String.format(Locale.getDefault(), "En %d min", Math.max(1, minutes));
|
|
}
|
|
} else if (Math.abs(diff) <= 2 * 3600000L) {
|
|
return "En vivo";
|
|
} else {
|
|
return "Finalizado";
|
|
}
|
|
}
|
|
}
|