PIbd-31_IevlewaMD_PMD/lib/details_page/detail_page.dart
2024-11-08 13:07:43 +04:00

259 lines
8.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:pmd_labs/card_data.dart';
import 'package:pmd_labs/data/dto/album_dto.dart';
import 'package:pmd_labs/data/repositories/album_repository.dart';
class DetailsPage extends StatefulWidget {
final CardData data;
const DetailsPage(this.data, {super.key});
@override
_DetailsPageState createState() => _DetailsPageState();
}
class _DetailsPageState extends State<DetailsPage> {
late Future<AlbumDataDto> _albumInfoFuture;
late AlbumRepository _repository;
@override
void initState() {
super.initState();
_repository = AlbumRepository();
if (widget.data.imageUrl == null) {
print("Данные не полностью переданы!");
} else {
_albumInfoFuture = _fetchAlbumInfo();
}
}
Future<AlbumDataDto> _fetchAlbumInfo() async {
AlbumDataImagesJPGDto imagesJPGDto = AlbumDataImagesJPGDto(
image_url: widget.data.imageUrl,
);
AlbumDataImagesDto imagesDto = AlbumDataImagesDto(
jpg: imagesJPGDto,
);
AlbumDataDto albumDto = AlbumDataDto(
title: widget.data.title,
artist: widget.data.artist,
images: imagesDto,
);
await _repository.getAlbumInfo(albumDto);
return albumDto;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: const Color(0xFF231a24),
title: Text(
widget.data.title,
style: Theme
.of(context)
.textTheme
.headlineLarge
?.copyWith(color: Colors.orange),
),
),
body: Container(
color: const Color(0xFF403042),
child: FutureBuilder<AlbumDataDto>(
future: _albumInfoFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}', style: Theme
.of(context)
.textTheme
.bodyLarge));
} else if (!snapshot.hasData || snapshot.data == null) {
return const Center(child: Text(
'No data available', style: TextStyle(color: Colors.white)));
} else {
AlbumDataDto albumDetails = snapshot.data!;
return SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(
20)),
child: Image.network( widget.data.imageUrl ?? '',
height: 300,
width: double.infinity,
fit: BoxFit.cover,
),
),
),
// Bloc для названия, исполнителя, года и жанров
_buildInfoBlock(albumDetails),
// Bloc для треков
_buildTracksBlock(albumDetails),
// Bloc для саммари
_buildSummaryBlock(albumDetails),
],
),
);
}
},
),
),
);
}
Widget _buildInfoBlock(AlbumDataDto albumDetails) {
return Container(
width: MediaQuery
.of(context)
.size
.width,
margin: const EdgeInsets.only(top: 16, left: 5, right: 5),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color(0xFF231a24),
border: Border.all(color: Colors.orange),
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: [
Text(
widget.data.title,
style: Theme
.of(context)
.textTheme
.headlineLarge
?.copyWith(color: Colors.orange),
),
Text(
'Artist:',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.orange),
),
Text(
'${albumDetails.artist}',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.white),
),
SizedBox(height: 8.0), // Отступ между блоками
Text(
'Year:',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.orange),
),
Text(
'${albumDetails.year}',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.white),
),
SizedBox(height: 8.0), // Отступ между блоками
Text(
'Genres:',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.orange),
),
Text(
'${albumDetails.genres?.join(', ')}',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.white),
),
],
),
);
}
Widget _buildTracksBlock(AlbumDataDto albumDetails) {
return Container(
width: MediaQuery
.of(context)
.size
.width,
margin: const EdgeInsets.only(top: 16, left: 5, right: 5),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color(0xFF231a24),
border: Border.all(color: Colors.orange),
borderRadius: BorderRadius.circular(10),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Tracks:',
style: Theme
.of(context)
.textTheme
.headlineSmall
?.copyWith(color: Colors.orange),
),
SizedBox(height: 8.0),
...albumDetails.tracks!.map((track) =>
Padding(
padding: const EdgeInsets.only(bottom: 4.0),
child: Row(
children: [
const Icon(
Icons.favorite_border_outlined,
color: Colors.purple,
),
const SizedBox(width: 8.0),
// Отступ между иконкой и текстом
Text(
track,
style: Theme
.of(context)
.textTheme
.bodyMedium
?.copyWith(color: Colors.white),
),
],
),
)),
],
),
);
}
Widget _buildSummaryBlock(AlbumDataDto albumDetails) {
return Container(
width: MediaQuery
.of(context)
.size
.width,
margin: const EdgeInsets.only(top: 16, left: 5, right: 5),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color(0xFF231a24),
border: Border.all(color: Colors.orange),
borderRadius: BorderRadius.circular(10),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Summary:',
style: Theme
.of(context)
.textTheme
.headlineSmall
?.copyWith(color: Colors.orange),
),
SizedBox(height: 8.0), // Отступ между заголовком и текстом
Text(
'${albumDetails.summary}',
style: Theme
.of(context)
.textTheme
.bodyMedium
?.copyWith(color: Colors.white),
),
],
),
);
}
}