lab7 done

This commit is contained in:
Dasha 2024-12-11 02:50:15 +04:00
parent 1d3c9fd4f4
commit 197bc0cca6
9 changed files with 84 additions and 224 deletions

View File

@ -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<String, dynamic> json) => _$CatDataDtoFromJson(json);
}

View File

@ -17,4 +17,8 @@ CatDataDto _$CatDataDtoFromJson(Map<String, dynamic> 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(),
);

View File

@ -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;
}
}

View File

@ -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<dynamic> response = await _dio.get<dynamic>(
url,
queryParameters: {
//'min_weight': minWeight,
'name': q,
'offset': offset,
},

View File

@ -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<CatsRepository>(
lazy: true,
create: (_) => CatsRepository(),
child: BlocProvider<HomeBloc>(
lazy: false,
create: (context) => HomeBloc(context.read<CatsRepository>()),
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<CatsRepository>(

View File

@ -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

View File

@ -29,7 +29,7 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
final updatedData = event.nextPage != null && data != null
? HomeData(
data: [...state.data?.data ?? [], ...data.data!],
nextPage: (event.nextPage! + 1),
nextPage: (event.nextPage! + 20),
)
: data;

View File

@ -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<int>(0),
)
: const Icon(
Icons.favorite_border,
key: ValueKey<int>(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,
width: 180,
child: Stack(
children: [
Positioned.fill(
child: Image.network(
widget.imageUrl ?? '',
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,20 +100,11 @@ 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,
@ -216,5 +124,5 @@ class _Card extends StatelessWidget {
),
),
);
}*/
}
}

View File

@ -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<HomeBloc>().add(HomeLoadDataEvent(search: search)));
},
),
),
BlocBuilder<HomeBloc, HomeState>(
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<HomeBloc, HomeState>(
builder: (context, state) => state.isPaginationLoading
? const CircularProgressIndicator()
: const SizedBox.shrink(),
),
],
),
);
}*/
Future<void> _onRefresh() {
context.read<HomeBloc>().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),
));
});