From 72affbaf2543a564a717a98c7faf3508006985c5 Mon Sep 17 00:00:00 2001 From: shirotame Date: Sat, 5 Oct 2024 00:59:39 +0400 Subject: [PATCH] add search support --- lib/data/repositories/anime_repository.dart | 12 ++-- lib/views/home_page/home_page.dart | 64 ++++++++++++++------- 2 files changed, 51 insertions(+), 25 deletions(-) diff --git a/lib/data/repositories/anime_repository.dart b/lib/data/repositories/anime_repository.dart index 8f363fc..a7d81bf 100644 --- a/lib/data/repositories/anime_repository.dart +++ b/lib/data/repositories/anime_repository.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:dio/dio.dart'; import 'package:flutter_project/data/mappers/animes_mapper.dart'; import 'package:flutter_project/data/repositories/api_interface.dart'; @@ -11,12 +13,13 @@ class AnimeRepository extends ApiInterface { static const String _baseUrl = "https://api.jikan.moe"; @override - Future?> loadData() async { + Future?> loadData({String? q}) async { try { - const String url = "$_baseUrl/v4/top/anime?sfw&limit=10"; + const String url = "$_baseUrl/v4/anime?sfw"; - final Response response = - await _dio.get>(url); + final Response response = await _dio.get>( + url, + queryParameters: q != null ? {'q': q} : null); final AnimesDto dto = AnimesDto.fromJson(response.data as Map); @@ -25,6 +28,7 @@ class AnimeRepository extends ApiInterface { return data; } on DioException catch (e) { + log("Exception. ${e.message.toString()}", error: e); return null; } } diff --git a/lib/views/home_page/home_page.dart b/lib/views/home_page/home_page.dart index d5d619b..79b9521 100644 --- a/lib/views/home_page/home_page.dart +++ b/lib/views/home_page/home_page.dart @@ -1,6 +1,5 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; import 'package:flutter_project/data/repositories/anime_repository.dart'; import 'package:flutter_project/domain/models/card.dart'; import 'package:flutter_project/views/details_page/details_page.dart'; @@ -28,31 +27,54 @@ class _HomePageState extends State { } } -class Body extends StatelessWidget { +class Body extends StatefulWidget { const Body({super.key}); @override - Widget build(BuildContext context) { - final data = AnimeRepository().loadData(); + State createState() => _BodyState(); +} - return Center( - child: FutureBuilder( - future: data, - builder: (context, snapshot) => SingleChildScrollView( - child: snapshot.hasData - ? Column( - children: snapshot.data - ?.map((data) => _Card.withData( - data, - onLike: (String title, bool isLiked) => - _showSnackBar(context, isLiked, title), - onTap: () => _navToDetails(context, data), - )) - .toList() ?? - []) - : const CircularProgressIndicator(), +class _BodyState extends State { + final AnimeRepository repo = AnimeRepository(); + var data = AnimeRepository().loadData(); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Padding( + padding: EdgeInsets.only(left: 16, right: 16, top: 10, bottom: 10), + child: CupertinoSearchTextField( + onChanged: (search) { + setState(() { + data = repo.loadData(q: search); + }); + }, + ), ), - ), + Expanded( + child: Center( + child: FutureBuilder?>( + future: data, + builder: (context, snapshot) => SingleChildScrollView( + child: snapshot.hasData + ? Column( + children: snapshot.data + ?.map((data) => _Card.withData( + data, + onLike: (String title, bool isLiked) => + _showSnackBar( + context, isLiked, title), + onTap: () => _navToDetails(context, data), + )) + .toList() ?? + []) + : const CircularProgressIndicator(), + ), + ), + ), + ), + ], ); }