Merge pull request #61 from R0m1k3/antigravity

feat: implement ChannelCard widget with EPG display, interactive hove…
This commit is contained in:
LogiFlow authored and GitHub committed 2025-12-07 00:17:07 +01:00
commit 56cc0b1694
3 files changed
+57 -25

No files matched your search

+1 -1
View File
@@ -15,7 +15,7 @@ class AppColors {
static const Color background = Color(0xFF000000);
/// Very deep grey for surfaces that need to be distinct but subtle (Apple Dark Grey)
static const Color surface = Color(0xFF2C2C2E);
static const Color surface = Color(0xFF1C1C1E);
/// Slightly lighter grey for secondary surfaces or hover states
static const Color surfaceVariant = Color(0xFF3A3A3C);
+50 -22
View File
@@ -48,7 +48,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> with SingleTi
// Glassmorphism Top Bar
return Scaffold(
extendBodyBehindAppBar: true, // Content behind app bar
backgroundColor: AppColors.background,
backgroundColor: Colors.transparent, // Transparent to show gradient
appBar: PreferredSize(
preferredSize: const Size.fromHeight(80),
child: Container(
@@ -58,19 +58,43 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> with SingleTi
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.black.withOpacity(0.9), // Darker at top
Colors.black.withOpacity(0.6), // Subtler top shadow
Colors.transparent,
],
),
),
child: Row(
child: Stack(
alignment: Alignment.center,
children: [
// 1. Side Elements (Logo & Profile) - Pushed to edges
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Logo Area
_buildLogo(),
const Spacer(),
// Search / Profile (Right Side)
Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: const Icon(Icons.search, color: Colors.white),
onPressed: () {
// Global search trigger
},
),
const SizedBox(width: 8),
const CircleAvatar(
radius: 16,
backgroundColor: Colors.white24,
child: Icon(Icons.person, size: 18, color: Colors.white),
),
],
),
],
),
// Centered Navigation Tabs (Pills)
// 2. Centered Navigation Tabs (Pills)
Container(
height: 50,
decoration: BoxDecoration(
@@ -108,27 +132,29 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> with SingleTi
}),
),
),
const Spacer(),
// Search / Profile (Right Side)
IconButton(
icon: const Icon(Icons.search, color: Colors.white),
onPressed: () {
// Global search trigger
},
),
const SizedBox(width: 8),
const CircleAvatar(
radius: 16,
backgroundColor: Colors.white24,
child: Icon(Icons.person, size: 18, color: Colors.white),
),
],
),
),
),
body: TabBarView(
body: Stack(
children: [
// Background Gradient (Apple TV Depth Effect)
Container(
decoration: const BoxDecoration(
gradient: RadialGradient(
center: Alignment(0, -0.2), // Slightly above center
radius: 1.5,
colors: [
Color(0xFF2C2C2E), // Dark Grey center (Light Source)
Color(0xFF000000), // Pure Black edges
],
stops: [0.0, 1.0],
),
),
),
// Content
TabBarView(
controller: _tabController,
physics: const NeverScrollableScrollPhysics(), // Disable swipe to avoid gesture conflicts
children: [
@@ -139,6 +165,8 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> with SingleTi
const Padding(padding: EdgeInsets.only(top: 80), child: SettingsTab()),
],
),
],
),
);
}
+6 -2
View File
@@ -52,6 +52,11 @@ class _ChannelCardState extends ConsumerState<ChannelCard>
vsync: this,
duration: const Duration(milliseconds: 1000)
)..repeat(reverse: true);
// Fetch EPG immediately when card is built
WidgetsBinding.instance.addPostFrameCallback((_) {
_fetchEpg();
});
}
@override
@@ -107,7 +112,6 @@ class _ChannelCardState extends ConsumerState<ChannelCard>
return MouseRegion(
onEnter: (_) {
setState(() => _isHovered = true);
if (!_epgLoaded) _fetchEpg();
},
onExit: (_) => setState(() => _isHovered = false),
cursor: SystemMouseCursors.click,
@@ -228,7 +232,7 @@ class _ChannelCardState extends ConsumerState<ChannelCard>
fontSize: 13,
),
),
if ((widget.currentProgram != null || _epgNow != null) && _isHovered) ...[
if ((widget.currentProgram != null || _epgNow != null)) ...[
const SizedBox(height: 2),
Text(
_epgNow ?? widget.currentProgram ?? '',