From 197bc0cca6247b4f37161beda9a2be4f115cfc30 Mon Sep 17 00:00:00 2001 From: Dasha Date: Wed, 11 Dec 2024 02:50:15 +0400 Subject: [PATCH] lab7 done --- lib/data/dtos/cats_dto.dart | 12 +- lib/data/dtos/cats_dto.g.dart | 4 + lib/data/mappers/cats_mapper.dart | 38 ++++- lib/data/repositories/cats_repository.dart | 2 - lib/main.dart | 36 +---- .../details_page/details_page.dart | 6 +- lib/presentation/home_page/bloc/bloc.dart | 2 +- lib/presentation/home_page/card.dart | 148 ++++-------------- lib/presentation/home_page/home_page.dart | 60 +------ 9 files changed, 84 insertions(+), 224 deletions(-) diff --git a/lib/data/dtos/cats_dto.dart b/lib/data/dtos/cats_dto.dart index a086a7e..5aad2cd 100644 --- a/lib/data/dtos/cats_dto.dart +++ b/lib/data/dtos/cats_dto.dart @@ -18,8 +18,18 @@ class CatDataDto { final String? name; final String? origin; final String? length; + @JsonKey(name: 'min_weight') + final int? minWeight; + @JsonKey(name: 'max_weight') + final int? maxWeight; + @JsonKey(name: 'min_life_expectancy') + final int? minLifeExpectancy; + @JsonKey(name: 'max_life_expectancy') + final int? maxLifeExpectancy; - const CatDataDto({this.imageLink, this.name, this.origin, this.length}); + + const CatDataDto({this.imageLink, this.name, this.origin, this.length, + this.minWeight, this.maxWeight, this.minLifeExpectancy, this.maxLifeExpectancy}); factory CatDataDto.fromJson(Map json) => _$CatDataDtoFromJson(json); } diff --git a/lib/data/dtos/cats_dto.g.dart b/lib/data/dtos/cats_dto.g.dart index 1a18577..3d1248a 100644 --- a/lib/data/dtos/cats_dto.g.dart +++ b/lib/data/dtos/cats_dto.g.dart @@ -17,4 +17,8 @@ CatDataDto _$CatDataDtoFromJson(Map json) => CatDataDto( name: json['name'] as String?, origin: json['origin'] as String?, length: json['length'] as String?, + minWeight: (json['min_weight'] as num?)?.toInt(), + maxWeight: (json['min_weight'] as num?)?.toInt(), + minLifeExpectancy: (json['min_life_expectancy'] as num?)?.toInt(), + maxLifeExpectancy: (json['max_life_expectancy'] as num?)?.toInt(), ); diff --git a/lib/data/mappers/cats_mapper.dart b/lib/data/mappers/cats_mapper.dart index f340bd1..a4fd7c6 100644 --- a/lib/data/mappers/cats_mapper.dart +++ b/lib/data/mappers/cats_mapper.dart @@ -16,16 +16,38 @@ extension CatDataDtoToModel on CatDataDto { CardData toDomain() => CardData( name ?? 'UNKNOWN', imageUrl: imageLink ?? _imagePlaceholder, - descriptionText: _makeDescriptionText(origin, length), + descriptionText: _makeDescriptionText(origin, length, minWeight, + maxWeight, minLifeExpectancy, maxLifeExpectancy), + id: name, ); - String _makeDescriptionText(String? origin, String? length) { - return origin != null || length != null - ? 'Origin: $origin \nLength: $length' - : origin != null - ? 'Origin: $origin' - : length != null - ? 'Length: $length' + String _makeDescriptionText(String? origin, String? length, int? minWeight, + int? maxWeight, int? minLifeExpectancy, int? maxLifeExpectancy) { + String description = ''; + + if (origin != null) { + description += '\nOrigin: $origin'; + } + if (length != null) { + description += '\nLength: $length'; + } + + minWeight != null && maxWeight != null + ? description += '\nWeight: $minWeight - $maxWeight pounds' + : minWeight != null + ? description += '\nMin weight: $minWeight pounds' + : maxWeight != null + ? description += '\nMax weight: $maxWeight pounds' + : ''; + + minLifeExpectancy != null && maxLifeExpectancy != null + ? description += '\nLife expectancy: $minLifeExpectancy - $maxLifeExpectancy years' + : minLifeExpectancy != null + ? description += '\nMin life expectancy: $minLifeExpectancy years' + : maxLifeExpectancy != null + ? description += '\nMax life expectancy: $maxLifeExpectancy years' : ''; + + return description; } } diff --git a/lib/data/repositories/cats_repository.dart b/lib/data/repositories/cats_repository.dart index b64ea6b..14a268e 100644 --- a/lib/data/repositories/cats_repository.dart +++ b/lib/data/repositories/cats_repository.dart @@ -20,7 +20,6 @@ class CatsRepository extends ApiInterface { OnErrorCallback? onError, String? q, int offset = 0, - //int minWeight=1, }) async { try { const String url = '/v1/cats?min_weight=1'; @@ -28,7 +27,6 @@ class CatsRepository extends ApiInterface { final Response response = await _dio.get( url, queryParameters: { - //'min_weight': minWeight, 'name': q, 'offset': offset, }, diff --git a/lib/main.dart b/lib/main.dart index d3ec840..b0451dc 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,37 +1,3 @@ -/*import 'package:flutter/material.dart'; -import 'package:pmu/data/repositories/cats_repository.dart'; -import 'package:pmu/presentation/home_page/home_page.dart'; -import 'package:pmu/presentation/home_page/bloc/bloc.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; - -void main() { - runApp(const MyApp()); -} - -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple.shade300), - useMaterial3: true, - ), - home: RepositoryProvider( - lazy: true, - create: (_) => CatsRepository(), - child: BlocProvider( - lazy: false, - create: (context) => HomeBloc(context.read()), - child: const MyHomePage(title: 'Энциклопедия кошек'), - ), - ), - ); - } -}*/ import 'dart:io'; import 'package:flutter/material.dart'; @@ -65,7 +31,7 @@ class MyApp extends StatelessWidget { supportedLocales: AppLocale.supportedLocales, debugShowCheckedModeBanner: false, theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.orangeAccent), + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurpleAccent), useMaterial3: true, ), home: RepositoryProvider( diff --git a/lib/presentation/details_page/details_page.dart b/lib/presentation/details_page/details_page.dart index d0d6285..defaaa1 100644 --- a/lib/presentation/details_page/details_page.dart +++ b/lib/presentation/details_page/details_page.dart @@ -11,9 +11,9 @@ class DetailsPage extends StatelessWidget { return Scaffold( appBar: AppBar(), body: Padding( - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.all(10), child: Column( - crossAxisAlignment: CrossAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Center( child: Image.network( @@ -21,7 +21,7 @@ class DetailsPage extends StatelessWidget { ), ), const SizedBox(height: 20), - Text(data.text, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), + Text(data.text, style: const TextStyle(fontSize: 26, fontWeight: FontWeight.w400)), const SizedBox(height: 10), Text(data.descriptionText, style: const TextStyle(fontSize: 22, color: Colors.black87)), // Add more details here as needed diff --git a/lib/presentation/home_page/bloc/bloc.dart b/lib/presentation/home_page/bloc/bloc.dart index 1c7f1a4..46a9f70 100644 --- a/lib/presentation/home_page/bloc/bloc.dart +++ b/lib/presentation/home_page/bloc/bloc.dart @@ -29,7 +29,7 @@ class HomeBloc extends Bloc { final updatedData = event.nextPage != null && data != null ? HomeData( data: [...state.data?.data ?? [], ...data.data!], - nextPage: (event.nextPage! + 1), + nextPage: (event.nextPage! + 20), ) : data; diff --git a/lib/presentation/home_page/card.dart b/lib/presentation/home_page/card.dart index 1cf4d98..4449040 100644 --- a/lib/presentation/home_page/card.dart +++ b/lib/presentation/home_page/card.dart @@ -46,94 +46,10 @@ class _Card extends StatelessWidget { onTap: onTap, child: Container( margin: const EdgeInsets.all(16), - constraints: const BoxConstraints(minHeight: 240), - decoration: BoxDecoration( - color: Colors.grey, - borderRadius: BorderRadius.circular(20), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(.5), - spreadRadius: 4, - offset: const Offset(0, 5), - blurRadius: 8, - ), - ], - ), - child: Column( - children: [ - Align( - alignment: Alignment.bottomRight, - child: Padding( - padding: const EdgeInsets.only( - left: 8, right: 16, bottom: 16, top: 10), - child: GestureDetector( - onTap: () => onLike?.call(id, text, isLiked), - child: AnimatedSwitcher( - duration: const Duration(milliseconds: 200), - child: isLiked - ? const Icon( - Icons.favorite, - color: Colors.redAccent, - key: ValueKey(0), - ) - : const Icon( - Icons.favorite_border, - key: ValueKey(1), - ), - ), - ), - ), - ), - ClipRRect( - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(20), - topRight: Radius.circular(20), - ), - child: SizedBox( - height: 160, - width: double.infinity, - child: Stack( - children: [ - Positioned.fill( - child: Image.network( - imageUrl ?? '', - fit: BoxFit.contain, - errorBuilder: (_, __, ___) => const Placeholder(), - ), - ), - ], - ), - ), - ), - Padding( - padding: - const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - text, - style: Theme.of(context).textTheme.headlineSmall, - textAlign: TextAlign.center, - ), - ], - ), - ), - ], - ), - ), - ); - } - /*Widget build(BuildContext context) { - return GestureDetector( - onTap: onTap, - child: Container( - margin: const EdgeInsets.all(16), - constraints: const BoxConstraints(minHeight: 140), + constraints: const BoxConstraints(minHeight: 200), decoration: BoxDecoration( color: Colors.white70, borderRadius: BorderRadius.circular(20), - border: Border.all(color: Colors.grey), boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(.5), @@ -148,33 +64,34 @@ class _Card extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ ClipRRect( - borderRadius: const BorderRadius.only( - bottomLeft: Radius.circular(20), - topLeft: Radius.circular(20), + borderRadius: const BorderRadius.all( + Radius.circular(20) ), child: SizedBox( height: double.infinity, - width: 140, - child: Image.network( - widget.imageUrl ?? '', - fit: BoxFit.cover, - errorBuilder: (_, __, ___) => const Placeholder(), + width: 180, + child: Stack( + children: [ + Positioned.fill( + child: Image.network( + imageUrl ?? '', + fit: BoxFit.cover, + errorBuilder: (_, __, ___) => const Placeholder(), + ), + ), + ], ), ), ), Expanded( child: Padding( - padding: const EdgeInsets.only(left: 16.0), + padding: const EdgeInsets.only(left: 18.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - widget.text, - style: TextStyle(fontSize: 23), - ), - Text( - widget.descriptionText, - style: TextStyle(fontSize: 19), + text, + style: Theme.of(context).textTheme.headlineSmall, ), ], ), @@ -183,30 +100,21 @@ class _Card extends StatelessWidget { Align( alignment: Alignment.bottomRight, child: Padding( - padding: const EdgeInsets.only( - left: 8.0, - right: 16.0, - bottom: 16.0, - ), + padding: const EdgeInsets.only(left: 5, right: 16, bottom: 16), child: GestureDetector( - onTap: () { - setState(() { - isLiked = !isLiked; - }); - widget.onLike?.call(widget.text, isLiked); - }, + onTap: () => onLike?.call(id, text, isLiked), child: AnimatedSwitcher( - duration: const Duration(milliseconds: 300), + duration: const Duration(milliseconds: 200), child: isLiked ? const Icon( - Icons.favorite, - color: Colors.purpleAccent, - key: ValueKey(0), - ) + Icons.favorite, + color: Colors.purpleAccent, + key: ValueKey(0), + ) : const Icon( - Icons.favorite_border, - key: ValueKey(1), - ), + Icons.favorite_border, + key: ValueKey(1), + ), ), ), ), @@ -216,5 +124,5 @@ class _Card extends StatelessWidget { ), ), ); - }*/ + } } diff --git a/lib/presentation/home_page/home_page.dart b/lib/presentation/home_page/home_page.dart index 073c35b..fcdca7f 100644 --- a/lib/presentation/home_page/home_page.dart +++ b/lib/presentation/home_page/home_page.dart @@ -177,6 +177,11 @@ class _BodyState extends State<_Body> { nextPage: nextPage, )); }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.deepPurple[200], + foregroundColor: Colors.black87, + textStyle: TextStyle(fontSize: 20), + ), child: Text(context.locale.next), ), ], @@ -187,59 +192,6 @@ class _BodyState extends State<_Body> { ), ); } - /*Widget build(BuildContext context) { - return Padding( - padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), - child: Column( - children: [ - Padding( - padding: const EdgeInsets.all(12), - child: CupertinoSearchTextField( - controller: searchController, - onChanged: (search) { - Debounce.run(() => context.read().add(HomeLoadDataEvent(search: search))); - }, - ), - ), - BlocBuilder( - builder: (context, state) => state.error != null - ? Text( - state.error ?? '', - style: Theme.of(context).textTheme.headlineSmall?.copyWith(color: Colors.red), - ) - : state.isLoading - ? const CircularProgressIndicator() - : Expanded( - child: RefreshIndicator( - onRefresh: _onRefresh, - child: ListView.builder( - controller: scrollController, - padding: EdgeInsets.zero, - itemCount: state.data?.data?.length ?? 0, - itemBuilder: (context, index) { - final data = state.data?.data?[index]; - return data != null - ? _Card.fromData( - data, - onLike: (title, isLiked) => - _showSnackBar(context, title, isLiked), - onTap: () => _navToDetails(context, data), - ) - : const SizedBox.shrink(); - }, - ), - ), - ), - ), - BlocBuilder( - builder: (context, state) => state.isPaginationLoading - ? const CircularProgressIndicator() - : const SizedBox.shrink(), - ), - ], - ), - ); - }*/ Future _onRefresh() { context.read().add(HomeLoadDataEvent(search: searchController.text)); @@ -267,7 +219,7 @@ class _BodyState extends State<_Body> { 'You ${isLiked ? 'like!' : 'disliked :('} $title ', style: Theme.of(context).textTheme.bodyLarge, ), - backgroundColor: Colors.red, + backgroundColor: Colors.deepPurpleAccent[100], duration: const Duration(seconds: 1), )); });