Files
neomovies-mobile/lib/presentation/screens/home/home_screen.dart
2025-07-13 14:01:29 +03:00

162 lines
5.2 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import 'package:neomovies_mobile/data/models/movie.dart';
import 'package:neomovies_mobile/presentation/providers/home_provider.dart';
import 'package:neomovies_mobile/presentation/providers/movie_list_provider.dart';
import 'package:neomovies_mobile/presentation/screens/movie_list_screen.dart';
import 'package:neomovies_mobile/presentation/widgets/movie_card.dart';
import 'package:provider/provider.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home'),
centerTitle: true,
actions: [
IconButton(
icon: const Icon(Icons.settings_outlined),
onPressed: () {
// TODO: Navigate to settings screen
},
),
],
),
body: Consumer<HomeProvider>(
builder: (context, provider, child) {
// Показываем загрузку только при первом запуске
if (provider.isLoading && provider.popularMovies.isEmpty) {
return const Center(child: CircularProgressIndicator());
}
// Показываем ошибку, если она есть
if (provider.errorMessage != null) {
return Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text(provider.errorMessage!, textAlign: TextAlign.center),
),
);
}
// Основной контент с возможностью "потянуть для обновления"
return RefreshIndicator(
onRefresh: provider.fetchAllMovies,
child: ListView(
padding: const EdgeInsets.symmetric(vertical: 8.0),
children: [
if (provider.popularMovies.isNotEmpty)
_MovieCarousel(
title: 'Popular Movies',
movies: provider.popularMovies,
category: MovieCategory.popular,
),
if (provider.upcomingMovies.isNotEmpty)
_MovieCarousel(
title: 'Latest Movies',
movies: provider.upcomingMovies,
category: MovieCategory.upcoming,
),
if (provider.topRatedMovies.isNotEmpty)
_MovieCarousel(
title: 'Top Rated Movies',
movies: provider.topRatedMovies,
category: MovieCategory.topRated,
),
],
),
);
},
),
);
}
}
// Вспомогательный виджет для карусели фильмов
class _MovieCarousel extends StatelessWidget {
final String title;
final List<Movie> movies;
final MovieCategory category;
const _MovieCarousel({
required this.title,
required this.movies,
required this.category,
});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
title,
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(height: 8),
SizedBox(
height: 280, // Maintained height for movie cards
child: ListView.builder(
scrollDirection: Axis.horizontal,
// Add one more item for the 'More' button
itemCount: movies.length + 1,
itemBuilder: (context, index) {
// If it's the last item, show the 'More' button
if (index == movies.length) {
return _buildMoreButton(context);
}
final movie = movies[index];
return Padding(
padding: EdgeInsets.only(
left: index == 0 ? 2.0 : 2.0,
),
child: MovieCard(movie: movie),
);
},
),
),
const SizedBox(height: 16), // Further reduced bottom padding
],
);
}
// A new widget for the 'More' button
Widget _buildMoreButton(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: SizedBox(
width: 150, // Same width as MovieCard
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MovieListScreen(category: category),
),
);
},
borderRadius: BorderRadius.circular(12),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.arrow_forward_ios_rounded, size: 40),
const SizedBox(height: 8),
Text(
'More',
style: Theme.of(context).textTheme.titleLarge,
),
],
),
),
),
);
}
}