ура 1 этап работает, спааать
This commit is contained in:
parent
ce3ed67612
commit
192c7f6472
@ -1,6 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:laba1/presentation/home_page/bloc/bloc.dart';
|
||||
import 'package:laba1/presentation/home_page/home_page.dart';
|
||||
|
||||
import 'data/repositories/potter_repository.dart';
|
||||
|
||||
void main() {
|
||||
runApp(const MyApp());
|
||||
}
|
||||
@ -15,7 +19,15 @@ class MyApp extends StatelessWidget {
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.amber,
|
||||
),
|
||||
home: const MyHomePage(title: 'Кувшинов Тимур Александрович'),
|
||||
home: RepositoryProvider<PotterRepository>(
|
||||
lazy: true,
|
||||
create: (_) => PotterRepository(),
|
||||
child: BlocProvider<HomeBloc>(
|
||||
lazy: false,
|
||||
create: (context) => HomeBloc(context.read<PotterRepository>()),
|
||||
child: const MyHomePage(title: 'Кувшинов Тимур Александрович'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
16
lib/presentation/home_page/bloc/bloc.dart
Normal file
16
lib/presentation/home_page/bloc/bloc.dart
Normal file
@ -0,0 +1,16 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:laba1/data/repositories/mock_repository.dart';
|
||||
import 'package:laba1/presentation/home_page/bloc/state.dart';
|
||||
|
||||
import '../../../data/repositories/potter_repository.dart';
|
||||
import 'events.dart';
|
||||
|
||||
class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
||||
final PotterRepository repo;
|
||||
HomeBloc(this.repo) : super(const HomeState()) {
|
||||
on<HomeLoadDataEvent>(_onLoadData);
|
||||
}
|
||||
void _onLoadData(HomeLoadDataEvent event, Emitter<HomeState> emit) {
|
||||
emit(state.copyWith(data: repo.loadData()));
|
||||
}
|
||||
}
|
6
lib/presentation/home_page/bloc/events.dart
Normal file
6
lib/presentation/home_page/bloc/events.dart
Normal file
@ -0,0 +1,6 @@
|
||||
abstract class HomeEvent {
|
||||
const HomeEvent();
|
||||
}
|
||||
class HomeLoadDataEvent extends HomeEvent {
|
||||
const HomeLoadDataEvent();
|
||||
}
|
11
lib/presentation/home_page/bloc/state.dart
Normal file
11
lib/presentation/home_page/bloc/state.dart
Normal file
@ -0,0 +1,11 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
import '../../../domain/models/card.dart';
|
||||
|
||||
class HomeState extends Equatable {
|
||||
final Future<List<CardData>?>? data;
|
||||
const HomeState({this.data});
|
||||
HomeState copyWith({Future<List<CardData>?>? data}) => HomeState(data: data ?? this.data);
|
||||
@override
|
||||
List<Object?> get props => [data];
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
part of 'home_page.dart';
|
||||
|
||||
typedef OnLikeCallback = void Function(bool isLiked)?;
|
||||
typedef OnLikeCallback = void Function(String title, bool isLiked)?;
|
||||
|
||||
class _Card extends StatefulWidget {
|
||||
final String _text;
|
||||
@ -100,7 +100,7 @@ class _CardState extends State<_Card> {
|
||||
onTap: () {
|
||||
isLiked = !isLiked;
|
||||
setState(() {});
|
||||
widget.onLike?.call(isLiked);
|
||||
widget.onLike?.call(widget._text, isLiked);
|
||||
},
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 100),
|
||||
|
@ -1,62 +1,74 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:laba1/data/repositories/potter_repository.dart';
|
||||
import 'package:laba1/presentation/details_page/details_page.dart';
|
||||
|
||||
import '../../data/repositories/mock_repository.dart';
|
||||
import '../../domain/models/card.dart';
|
||||
import '../dialogs/show_dialog.dart';
|
||||
import 'bloc/bloc.dart';
|
||||
import 'bloc/events.dart';
|
||||
import 'bloc/state.dart';
|
||||
|
||||
part 'card.dart';
|
||||
|
||||
class MyHomePage extends StatelessWidget {
|
||||
class MyHomePage extends StatefulWidget {
|
||||
const MyHomePage({super.key, required this.title});
|
||||
|
||||
final String title;
|
||||
|
||||
@override
|
||||
State<MyHomePage> createState() => _MyHomePageState();
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(title),
|
||||
title: Text(widget.title),
|
||||
backgroundColor: Colors.amber,
|
||||
),
|
||||
backgroundColor: Colors.yellow,
|
||||
body: const Body());
|
||||
body: const _Body());
|
||||
}
|
||||
}
|
||||
|
||||
class Body extends StatefulWidget {
|
||||
const Body({Key? key}) : super(key: key);
|
||||
class _Body extends StatefulWidget {
|
||||
const _Body({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<Body> createState() => _BodyState();
|
||||
State<_Body> createState() => _BodyState();
|
||||
}
|
||||
|
||||
class _BodyState extends State<Body> {
|
||||
class _BodyState extends State<_Body> {
|
||||
final searchController = TextEditingController();
|
||||
late Future<List<CardData>?> data;
|
||||
final repo = PotterRepository();
|
||||
bool isLoading = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
data = repo.loadData(onError: (e) => showErrorDialog(context, error: e));
|
||||
isLoading = true;
|
||||
data.then((_) => setState(() {
|
||||
isLoading = false; // Остановить индикатор при завершении загрузки
|
||||
}));
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
context.read<HomeBloc>().add(const HomeLoadDataEvent());
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
searchController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: FutureBuilder<List<CardData>?>(
|
||||
future: data,
|
||||
Positioned.fill(
|
||||
child: BlocBuilder<HomeBloc, HomeState > (
|
||||
builder: (context, state) =>
|
||||
FutureBuilder<List<CardData>?>(
|
||||
future: state.data,
|
||||
builder: (context, snapshot) {
|
||||
var cards = Column(
|
||||
children: [],
|
||||
@ -73,53 +85,42 @@ class _BodyState extends State<Body> {
|
||||
));
|
||||
cards.children.addAll(
|
||||
snapshot.data
|
||||
?.map((e) => _Card.fromData(
|
||||
e,
|
||||
onLike: (bool isLiked) {
|
||||
_showSnackBar(context, isLiked);
|
||||
},
|
||||
onTap: () => _navToDetails(context, e),
|
||||
))
|
||||
.toList() ??
|
||||
?.map((e) =>
|
||||
_Card.fromData(
|
||||
e,
|
||||
onLike: (String title, bool isLiked) {
|
||||
_showSnackBar(context, title, isLiked);
|
||||
},
|
||||
onTap: () => _navToDetails(context, e),
|
||||
))
|
||||
.toList() ??
|
||||
[],
|
||||
);
|
||||
return !isLoading
|
||||
return snapshot.hasData
|
||||
? SingleChildScrollView(
|
||||
child: cards,
|
||||
)
|
||||
: Center(child: CircularProgressIndicator());
|
||||
},
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0, right: 8),
|
||||
child: CupertinoSearchTextField(
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(20),
|
||||
bottomRight: Radius.circular(20),
|
||||
),
|
||||
backgroundColor: Colors.amberAccent,
|
||||
controller: searchController,
|
||||
onChanged: (search) {
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
setState(() {
|
||||
data = repo.loadData(
|
||||
q: search,
|
||||
onError: (e) => showErrorDialog(context, error: e),
|
||||
);
|
||||
data.then((_) => setState(() {
|
||||
isLoading =
|
||||
false; // Остановить индикатор при завершении загрузки
|
||||
}));
|
||||
});
|
||||
},
|
||||
),),
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0, right: 8),
|
||||
child: CupertinoSearchTextField(
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(20),
|
||||
bottomRight: Radius.circular(20),
|
||||
),
|
||||
backgroundColor: Colors.amberAccent,
|
||||
controller: searchController,
|
||||
onChanged: (search) {
|
||||
//TODO
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
@ -132,12 +133,15 @@ class _BodyState extends State<Body> {
|
||||
);
|
||||
}
|
||||
|
||||
void _showSnackBar(BuildContext context, bool isLiked) {
|
||||
void _showSnackBar(BuildContext context, String title, bool isLiked) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
'Card ${isLiked ? 'liked' : 'unliked'}',
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
'$title ${isLiked ? 'liked' : 'unliked'}',
|
||||
style: Theme
|
||||
.of(context)
|
||||
.textTheme
|
||||
.bodyLarge,
|
||||
),
|
||||
backgroundColor: Colors.orangeAccent,
|
||||
duration: const Duration(seconds: 1),
|
||||
|
56
pubspec.lock
56
pubspec.lock
@ -38,6 +38,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.11.0"
|
||||
bloc:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: bloc
|
||||
sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.1.4"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -158,6 +166,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
copy_with_extension:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: copy_with_extension
|
||||
sha256: fbcf890b0c34aedf0894f91a11a579994b61b4e04080204656b582708b5b1125
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.4"
|
||||
copy_with_extension_gen:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: copy_with_extension_gen
|
||||
sha256: "51cd11094096d40824c8da629ca7f16f3b7cea5fc44132b679617483d43346b0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.4"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -198,6 +222,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
equatable:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: equatable
|
||||
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.5"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -227,6 +259,14 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_bloc:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_bloc
|
||||
sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.1.6"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@ -392,6 +432,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
nested:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: nested
|
||||
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -424,6 +472,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
provider:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: provider
|
||||
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.2"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
10
pubspec.yaml
10
pubspec.yaml
@ -36,15 +36,25 @@ dependencies:
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^1.0.2
|
||||
|
||||
# Сетевое взаимодействие
|
||||
json_annotation: ^4.8.1
|
||||
dio: ^5.4.2+1
|
||||
pretty_dio_logger: ^1.3.1
|
||||
|
||||
# BLoC
|
||||
equatable: ^2.0.5
|
||||
flutter_bloc: ^8.1.5
|
||||
copy_with_extension_gen: ^5.0.4
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
# Сетевое взаимодействие
|
||||
build_runner: ^2.4.9
|
||||
json_serializable: ^6.7.1
|
||||
|
||||
# The "flutter_lints" package below contains a set of recommended lints to
|
||||
# encourage good coding practices. The lint set provided by the package is
|
||||
# activated in the `analysis_options.yaml` file located at the root of your
|
||||
|
Loading…
x
Reference in New Issue
Block a user