From 76dcbb954b9725947243f3af4ce015336c4074e9 Mon Sep 17 00:00:00 2001 From: Yourdax Date: Wed, 11 Dec 2024 06:12:20 +0400 Subject: [PATCH] =?UTF-8?q?lab5=20=D0=B2=D1=80=D0=BE=D0=B4=D0=B5=20done?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/data/dtos/quotes_dto.dart | 4 +- lib/data/dtos/quotes_dto.g.dart | 2 +- lib/data/mappers/quotes_mapper.dart | 2 +- lib/data/repositories/quotes_repository.dart | 20 +++++- lib/main.dart | 76 ++++++++++++++------ 5 files changed, 74 insertions(+), 30 deletions(-) diff --git a/lib/data/dtos/quotes_dto.dart b/lib/data/dtos/quotes_dto.dart index 7898b28..cc7a6e1 100644 --- a/lib/data/dtos/quotes_dto.dart +++ b/lib/data/dtos/quotes_dto.dart @@ -13,11 +13,11 @@ class QuotesDto { @JsonSerializable(createToJson: false) class QuoteDataDto { - final String? text; + final String? body; final String? author; final String? imageUrl; - const QuoteDataDto({this.text, this.author, this.imageUrl}); + const QuoteDataDto({this.body, this.author, this.imageUrl}); factory QuoteDataDto.fromJson(Map json) => _$QuoteDataDtoFromJson(json); } \ No newline at end of file diff --git a/lib/data/dtos/quotes_dto.g.dart b/lib/data/dtos/quotes_dto.g.dart index 4d2d045..f212c61 100644 --- a/lib/data/dtos/quotes_dto.g.dart +++ b/lib/data/dtos/quotes_dto.g.dart @@ -13,7 +13,7 @@ QuotesDto _$QuotesDtoFromJson(Map json) => QuotesDto( ); QuoteDataDto _$QuoteDataDtoFromJson(Map json) => QuoteDataDto( - text: json['text'] as String?, + body: json['body'] as String?, author: json['author'] as String?, imageUrl: json['imageUrl'] as String?, ); diff --git a/lib/data/mappers/quotes_mapper.dart b/lib/data/mappers/quotes_mapper.dart index edd9769..95dec55 100644 --- a/lib/data/mappers/quotes_mapper.dart +++ b/lib/data/mappers/quotes_mapper.dart @@ -6,7 +6,7 @@ const _imagePlaceholder = extension QuoteDtoToModel on QuoteDataDto { Quote toDomain() => Quote( - text ?? 'Без текста', + body ?? 'Без текста', author ?? 'Неизвестный автор', imageUrl ?? _imagePlaceholder, ); diff --git a/lib/data/repositories/quotes_repository.dart b/lib/data/repositories/quotes_repository.dart index ddd37a9..ef5ef7a 100644 --- a/lib/data/repositories/quotes_repository.dart +++ b/lib/data/repositories/quotes_repository.dart @@ -13,19 +13,32 @@ class QuotesRepository extends ApiInterface { requestBody: true, )) ..options.headers = { - 'Authorization': 'Bearer 82ccaa45c8344de4ac008b2487d33361', // Add the API key here + 'Authorization': 'Bearer 82ccaa45c8344de4ac008b2487d33361', }; static const String _baseUrl = 'https://favqs.com/api'; @override - Future?> loadData({String? q, OnErrorCallback? onError}) async { + Future?> loadData({String? q, String? author, OnErrorCallback? onError}) async { try { + final Map queryParams = {}; + + // Добавляем фильтрацию по тексту цитаты + if (q != null && q.isNotEmpty) { + queryParams['filter'] = q; // Фильтруем по слову + } + + // Добавляем фильтрацию по автору + if (author != null && author.isNotEmpty) { + queryParams['type'] = 'author'; + queryParams['filter'] = author; + } + const String url = '$_baseUrl/quotes'; final Response response = await _dio.get>( url, - queryParameters: q != null ? {'filter[text_cont]': q} : null, + queryParameters: queryParams.isNotEmpty ? queryParams : null, ); final QuotesDto dto = QuotesDto.fromJson(response.data as Map); @@ -37,3 +50,4 @@ class QuotesRepository extends ApiInterface { } } } + diff --git a/lib/main.dart b/lib/main.dart index 16e6a8a..b759f5c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -44,48 +44,70 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - final TextEditingController searchController = TextEditingController(); final List _quotes = []; final List _filteredQuotes = []; final QuotesRepository _quotesRepository = QuotesRepository(); + final TextEditingController searchController = TextEditingController(); + final TextEditingController authorController = TextEditingController(); + @override void initState() { super.initState(); _loadQuotes(); searchController.addListener(() { - _filterQuotes(searchController.text); + _loadQuotes(); + }); + + authorController.addListener(() { + _loadQuotes(); }); } + // Метод для загрузки цитат с учетом обоих фильтров Future _loadQuotes() async { - final quotes = await _quotesRepository.loadData(onError: (error) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Ошибка загрузки: $error')), - ); - }); + final query = searchController.text; + final author = authorController.text; + + final quotes = await _quotesRepository.loadData( + q: query, // Поиск по цитате + author: author, // Поиск по автору + onError: (error) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Ошибка загрузки: $error')), + ); + }, + ); + if (quotes != null) { setState(() { + _quotes.clear(); _quotes.addAll(quotes); - _filteredQuotes.addAll(quotes); + _filterQuotes(); }); } + print('Загружено цитат: ${_quotes.length}'); + print('Отфильтрованные цитаты: ${_filteredQuotes.length}'); } - void _filterQuotes(String query) { + // Фильтрация цитат по введенным значениям + void _filterQuotes() { setState(() { - if (query.isEmpty) { - _filteredQuotes.clear(); - _filteredQuotes.addAll(_quotes); - } else { - _filteredQuotes.clear(); - _filteredQuotes.addAll( - _quotes.where((quote) => - quote.text.toLowerCase().contains(query.toLowerCase()) || - quote.author.toLowerCase().contains(query.toLowerCase())), - ); + _filteredQuotes.clear(); // Очистите список фильтрации + _filteredQuotes.addAll(_quotes); // Изначально показываем все цитаты + + // Применяем фильтрацию по цитате + if (searchController.text.isNotEmpty) { + _filteredQuotes.retainWhere((quote) => + quote.text.toLowerCase().contains(searchController.text.toLowerCase())); + } + + // Применяем фильтрацию по автору + if (authorController.text.isNotEmpty) { + _filteredQuotes.retainWhere((quote) => + quote.author.toLowerCase().contains(authorController.text.toLowerCase())); } }); } @@ -95,8 +117,6 @@ class _MyHomePageState extends State { return Scaffold( appBar: AppBar( title: const Text('Цитаты'), - backgroundColor: Theme.of(context).colorScheme.primaryContainer, - foregroundColor: Theme.of(context).colorScheme.onPrimaryContainer, ), body: Column( children: [ @@ -105,11 +125,21 @@ class _MyHomePageState extends State { child: TextField( controller: searchController, decoration: const InputDecoration( - labelText: 'Поиск', + labelText: 'Поиск по цитате', prefixIcon: Icon(Icons.search), ), ), ), + Padding( + padding: const EdgeInsets.all(16.0), + child: TextField( + controller: authorController, + decoration: const InputDecoration( + labelText: 'Поиск по автору', + prefixIcon: Icon(Icons.person), + ), + ), + ), Expanded( child: _filteredQuotes.isEmpty ? const Center( @@ -121,7 +151,7 @@ class _MyHomePageState extends State { : ListView.builder( itemCount: _filteredQuotes.length, itemBuilder: (context, index) { - final quote = _filteredQuotes[index]; + final quote = _filteredQuotes[index]; // Используем _filteredQuotes для отображения return Card( margin: const EdgeInsets.symmetric( vertical: 8.0,