259 lines
8.0 KiB
Dart
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),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
}
|