Надо починить лайки
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 67 KiB |
BIN
assets/launcher.jpeg
Normal file
After Width: | Height: | Size: 104 KiB |
BIN
assets/launcher.png
Normal file
After Width: | Height: | Size: 81 KiB |
10
assets/svg/ru.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<svg width="210" height="210" viewBox="0 0 210 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<mask id="mask0_2_16" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="210" height="210">
|
||||||
|
<circle cx="105" cy="105" r="105" fill="#D9D9D9"/>
|
||||||
|
</mask>
|
||||||
|
<g mask="url(#mask0_2_16)">
|
||||||
|
<rect width="210" height="70" fill="white"/>
|
||||||
|
<rect y="70" width="210" height="70" fill="#92BCEC"/>
|
||||||
|
<rect y="140" width="210" height="70" fill="#FF6A59"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 464 B |
16
assets/svg/uk.svg
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<svg width="210" height="210" viewBox="0 0 210 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<mask id="mask0_2_33" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="210" height="210">
|
||||||
|
<circle cx="105" cy="105" r="105" fill="#D9D9D9"/>
|
||||||
|
</mask>
|
||||||
|
<g mask="url(#mask0_2_33)">
|
||||||
|
<rect x="-45.178" y="-2.80414" width="291.632" height="210" fill="#92BCEC"/>
|
||||||
|
<path d="M-53.9021 235.549L302.849 -25.8606" stroke="white" stroke-width="31.1573"/>
|
||||||
|
<path d="M252.507 234.39L-93.4718 -29.2878" stroke="white" stroke-width="31.1573"/>
|
||||||
|
<line x1="103.131" y1="-35.8309" x2="103.131" y2="240.846" stroke="white" stroke-width="43.6202"/>
|
||||||
|
<path d="M-97.8338 118.086L246.454 118.086" stroke="white" stroke-width="43.6202"/>
|
||||||
|
<line x1="309.671" y1="-33.314" x2="-59.2315" y2="238.377" stroke="#FF6A59" stroke-width="9.34718"/>
|
||||||
|
<path d="M-65.6983 -7.13381L301.914 270.757" stroke="#FF6A59" stroke-width="9.34718"/>
|
||||||
|
<line x1="103.131" y1="-45.8012" x2="103.131" y2="260.786" stroke="#FF6A59" stroke-width="24.9258"/>
|
||||||
|
<path d="M-62.6261 118.086L308.145 118.086" stroke="#FF6A59" stroke-width="24.9258"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
3
devtools_options.yaml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
description: This file stores settings for Dart & Flutter DevTools.
|
||||||
|
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
|
||||||
|
extensions:
|
12
lib/components/resources.g.dart
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/// Generate by [asset_generator](https://github.com/fluttercandies/flutter_asset_generator) library.
|
||||||
|
/// PLEASE DO NOT EDIT MANUALLY.
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
class R {
|
||||||
|
const R._();
|
||||||
|
|
||||||
|
/// ![preview](file://D:\code\pmu_nikita\PMU-PIbd-31-Potapov-N-S\assets\svg\ru.svg)
|
||||||
|
static const String ASSETS_SVG_RU_SVG = 'assets/svg/ru.svg';
|
||||||
|
|
||||||
|
/// ![preview](file://D:\code\pmu_nikita\PMU-PIbd-31-Potapov-N-S\assets\svg\uk.svg)
|
||||||
|
static const String ASSETS_SVG_UK_SVG = 'assets/svg/uk.svg';
|
||||||
|
}
|
12
lib/components/resoures.g.dart
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/// Generate by [asset_generator](https://github.com/fluttercandies/flutter_asset_generator) library.
|
||||||
|
/// PLEASE DO NOT EDIT MANUALLY.
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
class R {
|
||||||
|
const R._();
|
||||||
|
|
||||||
|
/// ![preview](file://D:\code\pmu_labs\pmu_labs_3_course\assets\svg\ru.svg)
|
||||||
|
static const String ASSETS_SVG_RU_SVG = 'assets/svg/ru.svg';
|
||||||
|
|
||||||
|
/// ![preview](file://D:\code\pmu_labs\pmu_labs_3_course\assets\svg\uk.svg)
|
||||||
|
static const String ASSETS_SVG_UK_SVG = 'assets/svg/uk.svg';
|
||||||
|
}
|
@ -21,7 +21,6 @@ extension UserDtoToModel on UserDto {
|
|||||||
? "https://avatar.iran.liara.run/public/boy"
|
? "https://avatar.iran.liara.run/public/boy"
|
||||||
: "https://avatar.iran.liara.run/public/girl")
|
: "https://avatar.iran.liara.run/public/girl")
|
||||||
.toString(),
|
.toString(),
|
||||||
isLiked: false,
|
|
||||||
age: age,
|
age: age,
|
||||||
distance: distance);
|
distance: distance);
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ class MockRepository extends ApiInterface {
|
|||||||
imageUrl: "https://placehold.co/600x400/png",
|
imageUrl: "https://placehold.co/600x400/png",
|
||||||
age: 21,
|
age: 21,
|
||||||
distance: 24.5,
|
distance: 24.5,
|
||||||
isLiked: false),
|
),
|
||||||
const CardData(
|
const CardData(
|
||||||
name: "Константин",
|
name: "Константин",
|
||||||
surname: "Злобин",
|
surname: "Злобин",
|
||||||
@ -21,7 +21,7 @@ class MockRepository extends ApiInterface {
|
|||||||
imageUrl: "https://placehold.co/600x400/png",
|
imageUrl: "https://placehold.co/600x400/png",
|
||||||
age: 24,
|
age: 24,
|
||||||
distance: 478.3,
|
distance: 478.3,
|
||||||
isLiked: false)
|
)
|
||||||
], pageNumber: 0);
|
], pageNumber: 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,21 @@
|
|||||||
class CardData {
|
class CardData {
|
||||||
|
|
||||||
final String? name;
|
final String? name;
|
||||||
final String? surname;
|
final String? surname;
|
||||||
final String? description;
|
final String? description;
|
||||||
final String? imageUrl;
|
final String? imageUrl;
|
||||||
final int? age;
|
final int? age;
|
||||||
final double? distance;
|
final double? distance;
|
||||||
final bool? isLiked;
|
|
||||||
|
final String? id;
|
||||||
|
|
||||||
|
|
||||||
const CardData(
|
const CardData(
|
||||||
{this.name,
|
{this.name,
|
||||||
this.surname,
|
this.surname,
|
||||||
this.description,
|
this.description,
|
||||||
this.imageUrl,
|
this.imageUrl,
|
||||||
this.isLiked,
|
|
||||||
this.age,
|
this.age,
|
||||||
this.distance});
|
this.distance,
|
||||||
|
this.id});
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:pmu/data/repositories/api_repository.dart';
|
import 'package:pmu/data/repositories/api_repository.dart';
|
||||||
import 'package:pmu/presentation/home_page/bloc/bloc.dart';
|
import 'package:pmu/presentation/home_page/bloc/bloc.dart';
|
||||||
import 'package:pmu/presentation/home_page/home_page.dart';
|
import 'package:pmu/presentation/home_page/home_page.dart';
|
||||||
|
import 'package:pmu/presentation/like/bloc.dart';
|
||||||
|
import 'package:pmu/presentation/locale/bloc.dart';
|
||||||
|
import 'package:pmu/presentation/locale/state.dart';
|
||||||
|
|
||||||
|
import 'components/locale/l10n/app_locale.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const MyApp());
|
runApp(const MyApp());
|
||||||
@ -13,15 +20,33 @@ class MyApp extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider<LocaleBloc>(
|
||||||
|
lazy: false,
|
||||||
|
create: (context) => LocaleBloc(Locale(Platform.localeName)),
|
||||||
|
child: BlocBuilder<LocaleBloc, LocaleState>(
|
||||||
|
builder: (context, state) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
title: 'LoveSearch',
|
title: 'LoveSearch',
|
||||||
|
locale: state.currentLocale,
|
||||||
|
localizationsDelegates: AppLocale.localizationsDelegates,
|
||||||
|
supportedLocales: AppLocale.supportedLocales,
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
home: RepositoryProvider<ApiRepository>(
|
home: RepositoryProvider<ApiRepository>(
|
||||||
lazy: true,
|
lazy: true,
|
||||||
create: (_) => ApiRepository(),
|
create: (_) => ApiRepository(),
|
||||||
|
child: BlocProvider<LikeBloc>(
|
||||||
|
lazy: true,
|
||||||
|
create: (context) => LikeBloc(),
|
||||||
child: BlocProvider<HomeBloc>(
|
child: BlocProvider<HomeBloc>(
|
||||||
lazy: false,
|
lazy: false,
|
||||||
create: (context) => HomeBloc(context.read<ApiRepository>()),
|
create: (context) =>
|
||||||
child: const HomePage())),
|
HomeBloc(context.read<ApiRepository>()),
|
||||||
|
child: const HomePage()),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
|
||||||
|
import '../../components/resoures.g.dart';
|
||||||
|
|
||||||
abstract class SvgObjects {
|
abstract class SvgObjects {
|
||||||
static void init() {
|
static void init() {
|
||||||
final pics = <String>[
|
final pics = <String>[
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
part of 'home_page.dart';
|
part of 'home_page.dart';
|
||||||
|
|
||||||
typedef OnLikeCallback = void Function(String title, bool isLiked)?;
|
typedef OnLikeCallback = void Function(String? id, String title, bool isLiked)?;
|
||||||
|
|
||||||
const double NORMAL_ICON_SCALE = 2.0;
|
const double NORMAL_ICON_SCALE = 2.0;
|
||||||
const double SCALED_ICON_SCALE = 2.5;
|
const double SCALED_ICON_SCALE = 2.5;
|
||||||
|
|
||||||
class _Card extends StatefulWidget {
|
class _Card extends StatelessWidget {
|
||||||
final String? description;
|
final String? description;
|
||||||
final String? imageUrl;
|
final String? imageUrl;
|
||||||
final bool? isLiked;
|
final bool isLiked;
|
||||||
|
final String? id;
|
||||||
final String? name;
|
final String? name;
|
||||||
final String? surname;
|
final String? surname;
|
||||||
|
|
||||||
@ -20,34 +21,28 @@ class _Card extends StatefulWidget {
|
|||||||
this.surname,
|
this.surname,
|
||||||
this.description,
|
this.description,
|
||||||
this.imageUrl,
|
this.imageUrl,
|
||||||
this.isLiked,
|
this.isLiked = false,
|
||||||
this.onLike,
|
this.onLike,
|
||||||
this.onTap});
|
this.onTap,
|
||||||
|
this.id});
|
||||||
|
|
||||||
factory _Card.fromData(CardData data,
|
factory _Card.fromData(CardData data,
|
||||||
{OnLikeCallback onLike, VoidCallback? onTap}) =>
|
{OnLikeCallback onLike, VoidCallback? onTap, bool isLiked = false}) =>
|
||||||
_Card(
|
_Card(
|
||||||
name: data.name,
|
name: data.name,
|
||||||
surname: data.surname,
|
surname: data.surname,
|
||||||
description: data.description,
|
description: data.description,
|
||||||
imageUrl: data.imageUrl,
|
imageUrl: data.imageUrl,
|
||||||
isLiked: data.isLiked,
|
isLiked: isLiked,
|
||||||
onLike: onLike,
|
onLike: onLike,
|
||||||
onTap: onTap);
|
onTap: onTap,
|
||||||
|
id: data.id,
|
||||||
@override
|
);
|
||||||
State<_Card> createState() => _CardState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _CardState extends State<_Card> {
|
|
||||||
bool isLiked = false;
|
|
||||||
|
|
||||||
double iconScale = NORMAL_ICON_SCALE;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: widget.onTap,
|
onTap: onTap,
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.all(10),
|
margin: const EdgeInsets.all(10),
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
@ -77,7 +72,7 @@ class _CardState extends State<_Card> {
|
|||||||
children: [
|
children: [
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Text(
|
child: Text(
|
||||||
(widget.name ?? "") + (" ") + (widget.surname ?? ""),
|
(name ?? "") + (" ") + (surname ?? ""),
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 30,
|
fontSize: 30,
|
||||||
@ -93,7 +88,7 @@ class _CardState extends State<_Card> {
|
|||||||
children: [
|
children: [
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.description ?? "",
|
description ?? "",
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
@ -104,43 +99,40 @@ class _CardState extends State<_Card> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (widget.imageUrl != null)
|
if (imageUrl != null)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Image.network(widget.imageUrl!,
|
child: Image.network(imageUrl!,
|
||||||
height: 500,
|
height: 500,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
fit: BoxFit.fitWidth),
|
fit: BoxFit.fitWidth),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(4.0),
|
padding: const EdgeInsets.all(4.0),
|
||||||
|
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () => {
|
onTap: () => onLike?.call(id, description!, isLiked),
|
||||||
setState(() {
|
|
||||||
isLiked = !isLiked;
|
|
||||||
widget.onLike?.call(widget.name ?? "", isLiked);
|
|
||||||
})
|
|
||||||
},
|
|
||||||
child: AnimatedScale(
|
|
||||||
scale: iconScale,
|
|
||||||
duration: const Duration(milliseconds: 250),
|
|
||||||
child: AnimatedSwitcher(
|
child: AnimatedSwitcher(
|
||||||
duration: const Duration(milliseconds: 250),
|
duration: const Duration(milliseconds: 250),
|
||||||
child: isLiked
|
child: !isLiked
|
||||||
? const Icon(
|
? const Icon(
|
||||||
|
Icons.favorite_border,
|
||||||
|
color: Colors.black,
|
||||||
|
key: ValueKey<int>(0),
|
||||||
|
)
|
||||||
|
: const Icon(
|
||||||
Icons.favorite,
|
Icons.favorite,
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
key: ValueKey(1),
|
key: ValueKey<int>(1),
|
||||||
)
|
),
|
||||||
: const Icon(Icons.favorite_border,
|
),
|
||||||
color: Colors.black, key: ValueKey(1)))),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
@ -2,11 +2,20 @@ import 'package:flutter/cupertino.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:pmu/components/debounce.dart';
|
import 'package:pmu/components/debounce.dart';
|
||||||
|
import 'package:pmu/components/extensions/content_x.dart';
|
||||||
import 'package:pmu/domain/models/card.dart';
|
import 'package:pmu/domain/models/card.dart';
|
||||||
|
import 'package:pmu/presentation/common/svg_objects.dart';
|
||||||
import 'package:pmu/presentation/detail_pages/card_detail_page.dart';
|
import 'package:pmu/presentation/detail_pages/card_detail_page.dart';
|
||||||
import 'package:pmu/presentation/home_page/bloc/bloc.dart';
|
import 'package:pmu/presentation/home_page/bloc/bloc.dart';
|
||||||
import 'package:pmu/presentation/home_page/bloc/events.dart';
|
import 'package:pmu/presentation/home_page/bloc/events.dart';
|
||||||
import 'package:pmu/presentation/home_page/bloc/state.dart';
|
import 'package:pmu/presentation/home_page/bloc/state.dart';
|
||||||
|
import 'package:pmu/presentation/locale/bloc.dart';
|
||||||
|
import 'package:pmu/presentation/locale/events.dart';
|
||||||
|
import 'package:pmu/presentation/locale/state.dart';
|
||||||
|
|
||||||
|
import '../like/bloc.dart';
|
||||||
|
import '../like/events.dart';
|
||||||
|
import '../like/state.dart';
|
||||||
|
|
||||||
part 'card.dart';
|
part 'card.dart';
|
||||||
|
|
||||||
@ -39,6 +48,7 @@ class _BodyState extends State<_Body> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
context.read<HomeBloc>().add(const HomeLoadDataEvent());
|
context.read<HomeBloc>().add(const HomeLoadDataEvent());
|
||||||
|
context.read<LikeBloc>().add(const LoadLikesEvent());
|
||||||
});
|
});
|
||||||
|
|
||||||
scrollController.addListener(_onNextPageListener);
|
scrollController.addListener(_onNextPageListener);
|
||||||
@ -72,10 +82,15 @@ class _BodyState extends State<_Body> {
|
|||||||
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
|
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Row(
|
||||||
padding: const EdgeInsets.all(12),
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 4,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: CupertinoSearchTextField(
|
child: CupertinoSearchTextField(
|
||||||
controller: searchController,
|
controller: searchController,
|
||||||
|
placeholder: context.locale.search,
|
||||||
onChanged: (search) {
|
onChanged: (search) {
|
||||||
Debounce.run(() => context
|
Debounce.run(() => context
|
||||||
.read<HomeBloc>()
|
.read<HomeBloc>()
|
||||||
@ -83,6 +98,26 @@ class _BodyState extends State<_Body> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () =>
|
||||||
|
context.read<LocaleBloc>().add(const ChangeLocaleEvent()),
|
||||||
|
child: SizedBox.square(
|
||||||
|
dimension: 50,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
child: BlocBuilder<LocaleBloc, LocaleState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
return state.currentLocale.languageCode == 'ru'
|
||||||
|
? const SvgRu()
|
||||||
|
: const SvgUk();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
BlocBuilder<HomeBloc, HomeState>(
|
BlocBuilder<HomeBloc, HomeState>(
|
||||||
builder: (context, state) => state.error != null
|
builder: (context, state) => state.error != null
|
||||||
? Text(
|
? Text(
|
||||||
@ -94,7 +129,9 @@ class _BodyState extends State<_Body> {
|
|||||||
)
|
)
|
||||||
: state.isLoading
|
: state.isLoading
|
||||||
? const CircularProgressIndicator()
|
? const CircularProgressIndicator()
|
||||||
: Expanded(
|
: BlocBuilder<LikeBloc, LikeState>(
|
||||||
|
builder: (context, likeState) {
|
||||||
|
return Expanded(
|
||||||
child: RefreshIndicator(
|
child: RefreshIndicator(
|
||||||
onRefresh: _onRefresh,
|
onRefresh: _onRefresh,
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
@ -106,14 +143,19 @@ class _BodyState extends State<_Body> {
|
|||||||
return data != null
|
return data != null
|
||||||
? _Card.fromData(
|
? _Card.fromData(
|
||||||
data,
|
data,
|
||||||
onLike: (title, isLiked) => _showSnackBar(
|
onLike: _onLike,
|
||||||
context, title, isLiked),
|
isLiked: likeState.likedIds
|
||||||
onTap: () => _navToDetails(context, data),
|
?.contains(data.id) ==
|
||||||
|
true,
|
||||||
|
onTap: () =>
|
||||||
|
_navToDetails(context, data),
|
||||||
)
|
)
|
||||||
: const SizedBox.shrink();
|
: const SizedBox.shrink();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
BlocBuilder<HomeBloc, HomeState>(
|
BlocBuilder<HomeBloc, HomeState>(
|
||||||
@ -126,6 +168,13 @@ class _BodyState extends State<_Body> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onLike(String? id, String title, bool isLiked) {
|
||||||
|
if (id != null) {
|
||||||
|
context.read<LikeBloc>().add(ChangeLikeEvent(id));
|
||||||
|
_showSnackBar(context, title, !isLiked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _onRefresh() {
|
Future<void> _onRefresh() {
|
||||||
context
|
context
|
||||||
.read<HomeBloc>()
|
.read<HomeBloc>()
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:pmu/presentation/like/events.dart';
|
||||||
import 'package:pmu/presentation/like/state.dart';
|
import 'package:pmu/presentation/like/state.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
import 'events.dart';
|
|
||||||
|
|
||||||
const String _likedPrefsKey = 'liked';
|
const String _likedPrefsKey = 'liked';
|
||||||
|
|
||||||
|
@ -57,7 +57,6 @@ dependencies:
|
|||||||
|
|
||||||
flutter_icons:
|
flutter_icons:
|
||||||
android: "ic_launcher"
|
android: "ic_launcher"
|
||||||
ios: true
|
|
||||||
image_path: "assets/launcher.jpeg"
|
image_path: "assets/launcher.jpeg"
|
||||||
min_sdk_android: 21
|
min_sdk_android: 21
|
||||||
|
|
||||||
|