delete likes in liked screen
This commit is contained in:
@@ -119,8 +119,10 @@ List<SingleChildWidget> get viewModels {
|
|||||||
),
|
),
|
||||||
ChangeNotifierProvider(
|
ChangeNotifierProvider(
|
||||||
create:
|
create:
|
||||||
(context) =>
|
(context) => LikedTendersViewModel(
|
||||||
LikedTendersViewModel(likedTendersRepository: context.read()),
|
likedTendersRepository: context.read(),
|
||||||
|
tendersRepository: context.read(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
ChangeNotifierProvider(
|
ChangeNotifierProvider(
|
||||||
create:
|
create:
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ import 'package:tm_app/data/services/liked_tenders_service.dart';
|
|||||||
import 'package:tm_app/data/services/model/liked_tenders_response/liked_tenders_response.dart';
|
import 'package:tm_app/data/services/model/liked_tenders_response/liked_tenders_response.dart';
|
||||||
|
|
||||||
class LikedTendersRepository {
|
class LikedTendersRepository {
|
||||||
final LikedTendersService likedTendersService;
|
final LikedTendersService _likedTendersService;
|
||||||
LikedTendersRepository({required this.likedTendersService});
|
LikedTendersRepository({required LikedTendersService likedTendersService})
|
||||||
|
: _likedTendersService = likedTendersService;
|
||||||
|
|
||||||
Future<Result<LikedTendersResponse>> getLikedTenders({
|
Future<Result<LikedTendersResponse>> getLikedTenders({
|
||||||
int offset = 0,
|
int offset = 0,
|
||||||
int limit = 20,
|
int limit = 20,
|
||||||
}) {
|
}) {
|
||||||
return likedTendersService.getLikedTenders(offset: offset, limit: limit);
|
return _likedTendersService.getLikedTenders(offset: offset, limit: limit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:tm_app/core/utils/result.dart';
|
import 'package:tm_app/core/utils/result.dart';
|
||||||
import 'package:tm_app/data/repositories/liked_tenders_repository.dart';
|
import 'package:tm_app/data/repositories/liked_tenders_repository.dart';
|
||||||
|
import 'package:tm_app/data/repositories/tenders_repository.dart';
|
||||||
import 'package:tm_app/data/services/model/liked_tender_feedback/liked_tender_feedback.dart';
|
import 'package:tm_app/data/services/model/liked_tender_feedback/liked_tender_feedback.dart';
|
||||||
import 'package:tm_app/data/services/model/liked_tenders_response/liked_tenders_response.dart';
|
import 'package:tm_app/data/services/model/liked_tenders_response/liked_tenders_response.dart';
|
||||||
|
|
||||||
|
import '../data/services/model/feedback_response/feedback_response.dart';
|
||||||
|
|
||||||
class LikedTendersViewModel with ChangeNotifier {
|
class LikedTendersViewModel with ChangeNotifier {
|
||||||
final LikedTendersRepository likedTendersRepository;
|
final LikedTendersRepository _likedTendersRepository;
|
||||||
LikedTendersViewModel({required this.likedTendersRepository}) {
|
final TendersRepository _tendersRepository;
|
||||||
getLikedTenders(reset: true);
|
LikedTendersViewModel({
|
||||||
}
|
required LikedTendersRepository likedTendersRepository,
|
||||||
|
required TendersRepository tendersRepository,
|
||||||
|
}) : _likedTendersRepository = likedTendersRepository,
|
||||||
|
_tendersRepository = tendersRepository;
|
||||||
|
|
||||||
bool isLoading = false;
|
bool isLoading = false;
|
||||||
bool isLoadingMore = false;
|
bool isLoadingMore = false;
|
||||||
@@ -21,7 +27,7 @@ class LikedTendersViewModel with ChangeNotifier {
|
|||||||
|
|
||||||
int currentPage = 1;
|
int currentPage = 1;
|
||||||
|
|
||||||
Future<void> getLikedTenders({bool reset = false}) async {
|
Future<void> getLikedTenders({bool reset = false}) async {
|
||||||
if (!reset && (isLoadingMore || !hasMore)) {
|
if (!reset && (isLoadingMore || !hasMore)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -44,7 +50,7 @@ Future<void> getLikedTenders({bool reset = false}) async {
|
|||||||
|
|
||||||
errorMessage = null;
|
errorMessage = null;
|
||||||
|
|
||||||
final result = await likedTendersRepository.getLikedTenders(
|
final result = await _likedTendersRepository.getLikedTenders(
|
||||||
offset: _offset,
|
offset: _offset,
|
||||||
limit: _limit,
|
limit: _limit,
|
||||||
);
|
);
|
||||||
@@ -83,8 +89,7 @@ Future<void> getLikedTenders({bool reset = false}) async {
|
|||||||
isLoading = false;
|
isLoading = false;
|
||||||
isLoadingMore = false;
|
isLoadingMore = false;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<void> loadMoreIfNeeded() async {
|
Future<void> loadMoreIfNeeded() async {
|
||||||
if (isLoadingMore || !hasMore) {
|
if (isLoadingMore || !hasMore) {
|
||||||
@@ -100,24 +105,49 @@ Future<void> getLikedTenders({bool reset = false}) async {
|
|||||||
await getLikedTenders(reset: true);
|
await getLikedTenders(reset: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeTenderById(String id) {
|
void removeTenderById(String id) async {
|
||||||
final current = data;
|
final current = data;
|
||||||
final list = current?.data?.feedback;
|
final list = current?.data?.feedback;
|
||||||
if (current == null || list == null) {
|
if (current == null || list == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Store original list to restore if error occurs
|
||||||
|
final originalList = List<LikedTenderFeedback>.of(list);
|
||||||
final updatedList = List<LikedTenderFeedback>.of(list)
|
final updatedList = List<LikedTenderFeedback>.of(list)
|
||||||
..removeWhere((e) => e.id == id);
|
..removeWhere((e) => e.tenderId == id);
|
||||||
|
|
||||||
final updatedMeta = current.data?.meta?.copyWith(total: updatedList.length);
|
// Temporarily update UI
|
||||||
|
data = current.copyWith(
|
||||||
|
data: current.data?.copyWith(feedback: updatedList),
|
||||||
|
);
|
||||||
|
notifyListeners();
|
||||||
|
|
||||||
|
final result = await _tendersRepository.toggleFeedback(
|
||||||
|
tenderId: id,
|
||||||
|
feedbackType: 'like',
|
||||||
|
);
|
||||||
|
|
||||||
|
switch (result) {
|
||||||
|
case Ok<FeedbackResponse>():
|
||||||
|
final updatedMeta = current.data?.meta?.copyWith(
|
||||||
|
total: updatedList.length,
|
||||||
|
);
|
||||||
data = current.copyWith(
|
data = current.copyWith(
|
||||||
data: current.data?.copyWith(
|
data: current.data?.copyWith(
|
||||||
feedback: updatedList,
|
feedback: updatedList,
|
||||||
meta: updatedMeta,
|
meta: updatedMeta,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
break;
|
||||||
|
case Error<FeedbackResponse>():
|
||||||
|
// Restore original list if error occurs
|
||||||
|
data = current.copyWith(
|
||||||
|
data: current.data?.copyWith(feedback: originalList),
|
||||||
|
);
|
||||||
|
errorMessage = result.error.toString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,7 +152,9 @@ class MobileHomePage extends StatelessWidget {
|
|||||||
textColor: AppColors.grey80,
|
textColor: AppColors.grey80,
|
||||||
enableTap: true,
|
enableTap: true,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
LikedTendersRouteData().push(context);
|
LikedTendersRouteData().push(context).then((value) {
|
||||||
|
homeViewModel.init();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -61,7 +61,9 @@ class _LikedTendersDesktopPageState extends State<LikedTendersDesktopPage> {
|
|||||||
final feedback = viewModel.data?.data?.feedback ?? [];
|
final feedback = viewModel.data?.data?.feedback ?? [];
|
||||||
|
|
||||||
if (feedback.isEmpty) {
|
if (feedback.isEmpty) {
|
||||||
return const Center(child: Text('Nothing to show'));
|
return const Center(
|
||||||
|
child: Text('You haven’t liked any tenders yet.'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final currentPage = viewModel.currentPage;
|
final currentPage = viewModel.currentPage;
|
||||||
@@ -140,8 +142,11 @@ class _LikedTendersDesktopPageState extends State<LikedTendersDesktopPage> {
|
|||||||
final pageNumber = index + 1;
|
final pageNumber = index + 1;
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text('Page $pageNumber'),
|
title: Text('Page $pageNumber'),
|
||||||
onTap: () =>
|
onTap:
|
||||||
Navigator.pop(context, pageNumber),
|
() => Navigator.pop(
|
||||||
|
context,
|
||||||
|
pageNumber,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -71,10 +71,13 @@ class _LikedTendersMobilePageState extends State<LikedTendersMobilePage> {
|
|||||||
final feedback = viewModel.data?.data?.feedback ?? [];
|
final feedback = viewModel.data?.data?.feedback ?? [];
|
||||||
|
|
||||||
if (feedback.isEmpty) {
|
if (feedback.isEmpty) {
|
||||||
return const Center(child: Text('Nothing to show'));
|
return const Center(
|
||||||
|
child: Text('You haven’t liked any tenders yet.'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final itemCount = feedback.length + (viewModel.isLoadingMore ? 1 : 0);
|
final itemCount =
|
||||||
|
feedback.length + (viewModel.isLoadingMore ? 1 : 0);
|
||||||
|
|
||||||
return RefreshIndicator(
|
return RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
@@ -93,16 +96,18 @@ class _LikedTendersMobilePageState extends State<LikedTendersMobilePage> {
|
|||||||
return Padding(
|
return Padding(
|
||||||
padding: EdgeInsets.only(bottom: 20.0.h()),
|
padding: EdgeInsets.only(bottom: 20.0.h()),
|
||||||
child: Dismissible(
|
child: Dismissible(
|
||||||
key: ValueKey(item.id ?? index),
|
key: ValueKey(item.tenderId ?? index),
|
||||||
direction: DismissDirection.endToStart,
|
direction: DismissDirection.endToStart,
|
||||||
background: Container(
|
background: Container(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
padding: EdgeInsets.symmetric(horizontal: 20.0.w()),
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 20.0.w(),
|
||||||
|
),
|
||||||
child: SvgPicture.asset(AssetsManager.trash),
|
child: SvgPicture.asset(AssetsManager.trash),
|
||||||
),
|
),
|
||||||
onDismissed: (_) {
|
onDismissed: (_) {
|
||||||
if (item.id != null) {
|
if (item.tenderId != null) {
|
||||||
viewModel.removeTenderById(item.id!);
|
viewModel.removeTenderById(item.tenderId!);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: LikedListItem(tender: item.tender!),
|
child: LikedListItem(tender: item.tender!),
|
||||||
|
|||||||
@@ -1,13 +1,31 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tm_app/core/utils/size_config.dart';
|
import 'package:tm_app/core/utils/size_config.dart';
|
||||||
import 'package:tm_app/views/shared/responsive_builder.dart';
|
import 'package:tm_app/view_models/liked_tenders_view_model.dart';
|
||||||
import 'package:tm_app/views/liked_tenders/pages/liked_tenders_desktop_page.dart';
|
import 'package:tm_app/views/liked_tenders/pages/liked_tenders_desktop_page.dart';
|
||||||
import 'package:tm_app/views/liked_tenders/pages/liked_tenders_mobile_page.dart';
|
import 'package:tm_app/views/liked_tenders/pages/liked_tenders_mobile_page.dart';
|
||||||
import 'package:tm_app/views/liked_tenders/pages/liked_tenders_tablet_page.dart';
|
import 'package:tm_app/views/liked_tenders/pages/liked_tenders_tablet_page.dart';
|
||||||
|
import 'package:tm_app/views/shared/responsive_builder.dart';
|
||||||
|
|
||||||
class LikedTendersScreen extends StatelessWidget {
|
class LikedTendersScreen extends StatefulWidget {
|
||||||
const LikedTendersScreen({super.key});
|
const LikedTendersScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<LikedTendersScreen> createState() => _LikedTendersScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LikedTendersScreenState extends State<LikedTendersScreen> {
|
||||||
|
late final LikedTendersViewModel viewModel;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
viewModel = context.read<LikedTendersViewModel>();
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||||
|
viewModel.getLikedTenders(reset: true);
|
||||||
|
});
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
SizeConfig.init(context);
|
SizeConfig.init(context);
|
||||||
|
|||||||
@@ -68,7 +68,9 @@ class _LikedTendersTabletPageState extends State<LikedTendersTabletPage> {
|
|||||||
final feedback = viewModel.data?.data?.feedback ?? [];
|
final feedback = viewModel.data?.data?.feedback ?? [];
|
||||||
|
|
||||||
if (feedback.isEmpty) {
|
if (feedback.isEmpty) {
|
||||||
return const Center(child: Text('Nothing to show'));
|
return const Center(
|
||||||
|
child: Text('You haven’t liked any tenders yet.'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final currentPage = viewModel.currentPage;
|
final currentPage = viewModel.currentPage;
|
||||||
|
|||||||
Reference in New Issue
Block a user