Merge pull request 'update notification tab data when clicking on navigation bars' (#169) from navigate_notification_update into main
Reviewed-on: https://repo.ravanertebat.com/TM/tm_app/pulls/169
This commit is contained in:
@@ -8,6 +8,8 @@ import 'package:tm_app/view_models/home_view_model.dart';
|
|||||||
import 'package:tm_app/view_models/tenders_view_model.dart';
|
import 'package:tm_app/view_models/tenders_view_model.dart';
|
||||||
import 'package:tm_app/views/shared/responsive_builder.dart';
|
import 'package:tm_app/views/shared/responsive_builder.dart';
|
||||||
|
|
||||||
|
import '../../../view_models/notification_view_model.dart';
|
||||||
|
|
||||||
class AppShellScreen extends StatelessWidget {
|
class AppShellScreen extends StatelessWidget {
|
||||||
const AppShellScreen({required this.navigationShell, super.key});
|
const AppShellScreen({required this.navigationShell, super.key});
|
||||||
|
|
||||||
@@ -32,6 +34,9 @@ class AppShellScreen extends StatelessWidget {
|
|||||||
if (index == 1) {
|
if (index == 1) {
|
||||||
context.read<TendersViewModel>().init(context);
|
context.read<TendersViewModel>().init(context);
|
||||||
}
|
}
|
||||||
|
if (index == 3) {
|
||||||
|
context.read<NotificationViewModel>().init();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,19 +5,38 @@ import 'package:tm_app/data/repositories/notification_repository.dart';
|
|||||||
import 'package:tm_app/data/services/model/notification__response/notification_response_model.dart';
|
import 'package:tm_app/data/services/model/notification__response/notification_response_model.dart';
|
||||||
import 'package:tm_app/views/notification/strings/notification_strings.dart';
|
import 'package:tm_app/views/notification/strings/notification_strings.dart';
|
||||||
|
|
||||||
|
|
||||||
class NotificationViewModel with ChangeNotifier {
|
class NotificationViewModel with ChangeNotifier {
|
||||||
final NotificationsRepository _repository;
|
final NotificationsRepository _repository;
|
||||||
|
|
||||||
NotificationViewModel({required NotificationsRepository repositoryViewModel})
|
NotificationViewModel({required NotificationsRepository repositoryViewModel})
|
||||||
: _repository = repositoryViewModel {
|
: _repository = repositoryViewModel {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
getNotifications();
|
init();
|
||||||
getUnreadNotifications();
|
|
||||||
getImportantNotifications();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init() async {
|
||||||
|
clearData();
|
||||||
|
await getNotifications();
|
||||||
|
await getUnreadNotifications();
|
||||||
|
await getImportantNotifications();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearData() {
|
||||||
|
allNotificationResponse = null;
|
||||||
|
unreadNotificationResponse = null;
|
||||||
|
importantNotificationResponse = null;
|
||||||
|
_errorMessage = null;
|
||||||
|
currentPageAll = 1;
|
||||||
|
totalPagesAll = 0;
|
||||||
|
currentPageUnread = 1;
|
||||||
|
totalPagesUnread = 0;
|
||||||
|
currentPageImportant = 1;
|
||||||
|
totalPagesImportant = 0;
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
static const int _pageSize = 10;
|
static const int _pageSize = 10;
|
||||||
|
|
||||||
String? _errorMessage;
|
String? _errorMessage;
|
||||||
@@ -47,8 +66,10 @@ class NotificationViewModel with ChangeNotifier {
|
|||||||
int currentPageImportant = 1;
|
int currentPageImportant = 1;
|
||||||
int totalPagesImportant = 0;
|
int totalPagesImportant = 0;
|
||||||
|
|
||||||
|
Future<void> getNotifications({
|
||||||
Future<void> getNotifications({int page = 1, bool isPagination = false}) async {
|
int page = 1,
|
||||||
|
bool isPagination = false,
|
||||||
|
}) async {
|
||||||
if (isPagination) {
|
if (isPagination) {
|
||||||
isMoreLoadingAll = true;
|
isMoreLoadingAll = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -57,7 +78,10 @@ class NotificationViewModel with ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
final int offset = (page - 1) * _pageSize;
|
final int offset = (page - 1) * _pageSize;
|
||||||
final result = await _repository.getNotifications(limit: _pageSize, offset: offset);
|
final result = await _repository.getNotifications(
|
||||||
|
limit: _pageSize,
|
||||||
|
offset: offset,
|
||||||
|
);
|
||||||
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case Ok<NotificationResponseModel>():
|
case Ok<NotificationResponseModel>():
|
||||||
@@ -66,9 +90,7 @@ class NotificationViewModel with ChangeNotifier {
|
|||||||
final old = allNotificationResponse?.data?.notifications ?? [];
|
final old = allNotificationResponse?.data?.notifications ?? [];
|
||||||
final fresh = data.data?.notifications ?? [];
|
final fresh = data.data?.notifications ?? [];
|
||||||
allNotificationResponse = data.copyWith(
|
allNotificationResponse = data.copyWith(
|
||||||
data: data.data?.copyWith(
|
data: data.data?.copyWith(notifications: [...old, ...fresh]),
|
||||||
notifications: [...old, ...fresh],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
allNotificationResponse = data;
|
allNotificationResponse = data;
|
||||||
@@ -91,7 +113,10 @@ class NotificationViewModel with ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getUnreadNotifications({int page = 1, bool isPagination = false}) async {
|
Future<void> getUnreadNotifications({
|
||||||
|
int page = 1,
|
||||||
|
bool isPagination = false,
|
||||||
|
}) async {
|
||||||
if (isPagination) {
|
if (isPagination) {
|
||||||
isMoreLoadingUnread = true;
|
isMoreLoadingUnread = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -100,7 +125,10 @@ class NotificationViewModel with ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
final int offset = (page - 1) * _pageSize;
|
final int offset = (page - 1) * _pageSize;
|
||||||
final result = await _repository.getUnreadNotifications(limit: _pageSize, offset: offset);
|
final result = await _repository.getUnreadNotifications(
|
||||||
|
limit: _pageSize,
|
||||||
|
offset: offset,
|
||||||
|
);
|
||||||
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case Ok<NotificationResponseModel>():
|
case Ok<NotificationResponseModel>():
|
||||||
@@ -109,9 +137,7 @@ class NotificationViewModel with ChangeNotifier {
|
|||||||
final old = unreadNotificationResponse?.data?.notifications ?? [];
|
final old = unreadNotificationResponse?.data?.notifications ?? [];
|
||||||
final fresh = data.data?.notifications ?? [];
|
final fresh = data.data?.notifications ?? [];
|
||||||
unreadNotificationResponse = data.copyWith(
|
unreadNotificationResponse = data.copyWith(
|
||||||
data: data.data?.copyWith(
|
data: data.data?.copyWith(notifications: [...old, ...fresh]),
|
||||||
notifications: [...old, ...fresh],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
unreadNotificationResponse = data;
|
unreadNotificationResponse = data;
|
||||||
@@ -132,7 +158,10 @@ class NotificationViewModel with ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getImportantNotifications({int page = 1, bool isPagination = false}) async {
|
Future<void> getImportantNotifications({
|
||||||
|
int page = 1,
|
||||||
|
bool isPagination = false,
|
||||||
|
}) async {
|
||||||
if (isPagination) {
|
if (isPagination) {
|
||||||
isMoreLoadingImportant = true;
|
isMoreLoadingImportant = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -142,7 +171,10 @@ class NotificationViewModel with ChangeNotifier {
|
|||||||
|
|
||||||
final int offset = (page - 1) * _pageSize;
|
final int offset = (page - 1) * _pageSize;
|
||||||
|
|
||||||
final result = await _repository.getUnreadNotifications(limit: _pageSize, offset: offset);
|
final result = await _repository.getUnreadNotifications(
|
||||||
|
limit: _pageSize,
|
||||||
|
offset: offset,
|
||||||
|
);
|
||||||
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case Ok<NotificationResponseModel>():
|
case Ok<NotificationResponseModel>():
|
||||||
@@ -151,9 +183,7 @@ class NotificationViewModel with ChangeNotifier {
|
|||||||
final old = importantNotificationResponse?.data?.notifications ?? [];
|
final old = importantNotificationResponse?.data?.notifications ?? [];
|
||||||
final fresh = data.data?.notifications ?? [];
|
final fresh = data.data?.notifications ?? [];
|
||||||
importantNotificationResponse = data.copyWith(
|
importantNotificationResponse = data.copyWith(
|
||||||
data: data.data?.copyWith(
|
data: data.data?.copyWith(notifications: [...old, ...fresh]),
|
||||||
notifications: [...old, ...fresh],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
importantNotificationResponse = data;
|
importantNotificationResponse = data;
|
||||||
@@ -165,7 +195,6 @@ class NotificationViewModel with ChangeNotifier {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Error<NotificationResponseModel>():
|
case Error<NotificationResponseModel>():
|
||||||
|
|
||||||
_errorMessage = result.error.toString();
|
_errorMessage = result.error.toString();
|
||||||
|
|
||||||
_updateImportantFromAll();
|
_updateImportantFromAll();
|
||||||
@@ -179,10 +208,11 @@ class NotificationViewModel with ChangeNotifier {
|
|||||||
|
|
||||||
void _updateImportantFromAll() {
|
void _updateImportantFromAll() {
|
||||||
final all = allNotificationResponse?.data?.notifications ?? [];
|
final all = allNotificationResponse?.data?.notifications ?? [];
|
||||||
final filtered = (all.where((n) {
|
final filtered =
|
||||||
final p = n.priority ?? '';
|
(all.where((n) {
|
||||||
return p.toLowerCase() == 'important';
|
final p = n.priority ?? '';
|
||||||
}).toList());
|
return p.toLowerCase() == 'important';
|
||||||
|
}).toList());
|
||||||
|
|
||||||
if (allNotificationResponse != null) {
|
if (allNotificationResponse != null) {
|
||||||
importantNotificationResponse = allNotificationResponse!.copyWith(
|
importantNotificationResponse = allNotificationResponse!.copyWith(
|
||||||
@@ -229,13 +259,16 @@ class NotificationViewModel with ChangeNotifier {
|
|||||||
case Ok<Map<String, dynamic>>():
|
case Ok<Map<String, dynamic>>():
|
||||||
final response = result.value;
|
final response = result.value;
|
||||||
final success = response['success'] as bool? ?? false;
|
final success = response['success'] as bool? ?? false;
|
||||||
final message = response['message'] as String? ?? NotificationStrings.unknownResponse;
|
final message =
|
||||||
|
response['message'] as String? ??
|
||||||
|
NotificationStrings.unknownResponse;
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
if (allNotificationResponse?.data?.notifications != null) {
|
if (allNotificationResponse?.data?.notifications != null) {
|
||||||
final updatedNotifications = allNotificationResponse!.data!.notifications!
|
final updatedNotifications =
|
||||||
.map((n) => n.copyWith(seen: true))
|
allNotificationResponse!.data!.notifications!
|
||||||
.toList();
|
.map((n) => n.copyWith(seen: true))
|
||||||
|
.toList();
|
||||||
|
|
||||||
allNotificationResponse = allNotificationResponse!.copyWith(
|
allNotificationResponse = allNotificationResponse!.copyWith(
|
||||||
data: allNotificationResponse!.data!.copyWith(
|
data: allNotificationResponse!.data!.copyWith(
|
||||||
@@ -244,24 +277,31 @@ class NotificationViewModel with ChangeNotifier {
|
|||||||
);
|
);
|
||||||
|
|
||||||
unreadNotificationResponse = unreadNotificationResponse?.copyWith(
|
unreadNotificationResponse = unreadNotificationResponse?.copyWith(
|
||||||
data: unreadNotificationResponse?.data?.copyWith(notifications: []),
|
data: unreadNotificationResponse?.data?.copyWith(
|
||||||
|
notifications: [],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (importantNotificationResponse?.data?.notifications != null) {
|
if (importantNotificationResponse?.data?.notifications != null) {
|
||||||
final updatedImportant = importantNotificationResponse!.data!.notifications!
|
final updatedImportant =
|
||||||
.map((n) => n.copyWith(seen: true))
|
importantNotificationResponse!.data!.notifications!
|
||||||
.toList();
|
.map((n) => n.copyWith(seen: true))
|
||||||
|
.toList();
|
||||||
|
|
||||||
importantNotificationResponse = importantNotificationResponse!.copyWith(
|
importantNotificationResponse = importantNotificationResponse!
|
||||||
data: importantNotificationResponse!.data!.copyWith(
|
.copyWith(
|
||||||
notifications: updatedImportant,
|
data: importantNotificationResponse!.data!.copyWith(
|
||||||
),
|
notifications: updatedImportant,
|
||||||
);
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
AppToast.success(context, NotificationStrings.allNotificationMarkedAsRead);
|
AppToast.success(
|
||||||
|
context,
|
||||||
|
NotificationStrings.allNotificationMarkedAsRead,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_errorMessage = message;
|
_errorMessage = message;
|
||||||
|
|||||||
@@ -126,6 +126,8 @@ class TendersViewModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void init(BuildContext context) async {
|
void init(BuildContext context) async {
|
||||||
|
_isLoading = true;
|
||||||
|
notifyListeners();
|
||||||
clearAll();
|
clearAll();
|
||||||
await getTenders(context: context);
|
await getTenders(context: context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class NotificationCard extends StatelessWidget {
|
|||||||
Visibility(
|
Visibility(
|
||||||
visible:
|
visible:
|
||||||
notification.priority ==
|
notification.priority ==
|
||||||
NotificationStrings.important,
|
NotificationStrings.important.toLowerCase(),
|
||||||
child: Container(
|
child: Container(
|
||||||
width: 86.0.w(),
|
width: 86.0.w(),
|
||||||
height: 24.0.h(),
|
height: 24.0.h(),
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import 'package:tm_app/views/profile/strings/profile_strings.dart';
|
|||||||
import 'package:tm_app/views/tenders/strings/tenders_strings.dart';
|
import 'package:tm_app/views/tenders/strings/tenders_strings.dart';
|
||||||
|
|
||||||
import '../../core/routes/app_routes.dart';
|
import '../../core/routes/app_routes.dart';
|
||||||
|
import '../../view_models/notification_view_model.dart';
|
||||||
|
|
||||||
class DesktopNavigationWidget extends StatelessWidget {
|
class DesktopNavigationWidget extends StatelessWidget {
|
||||||
const DesktopNavigationWidget({
|
const DesktopNavigationWidget({
|
||||||
@@ -103,7 +104,7 @@ class DesktopNavigationWidget extends StatelessWidget {
|
|||||||
context,
|
context,
|
||||||
() => const NotificationRouteData().go(context),
|
() => const NotificationRouteData().go(context),
|
||||||
);
|
);
|
||||||
//context.read<notificationViewModel>().getTenders();
|
context.read<NotificationViewModel>().init();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
iconPath: AssetsManager.notify,
|
iconPath: AssetsManager.notify,
|
||||||
@@ -148,57 +149,56 @@ class DesktopNavigationWidget extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _navigationItem({
|
Widget _navigationItem({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required String text,
|
required String text,
|
||||||
required bool isActive,
|
required bool isActive,
|
||||||
required VoidCallback onTap,
|
required VoidCallback onTap,
|
||||||
required String iconPath,
|
required String iconPath,
|
||||||
required String activeIconPath,
|
required String activeIconPath,
|
||||||
}) {
|
}) {
|
||||||
final hasUnread = context.watch<HomeViewModel>().hasUnreadNotification;
|
final hasUnread = context.watch<HomeViewModel>().hasUnreadNotification;
|
||||||
|
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 115.0,
|
width: 115.0,
|
||||||
height: 64,
|
height: 64,
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Stack(
|
Stack(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(isActive ? activeIconPath : iconPath),
|
SvgPicture.asset(isActive ? activeIconPath : iconPath),
|
||||||
if (text == TendersStrings.notifications && hasUnread)
|
if (text == TendersStrings.notifications && hasUnread)
|
||||||
Positioned(
|
Positioned(
|
||||||
right: -5,
|
right: -5,
|
||||||
top: -2,
|
top: -2,
|
||||||
child: Container(
|
child: Container(
|
||||||
width: 8,
|
width: 8,
|
||||||
height: 8,
|
height: 8,
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
Text(
|
|
||||||
text,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12.0.sp(),
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
color: isActive ? AppColors.primaryColor : AppColors.grey60,
|
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(width: 8),
|
||||||
],
|
Text(
|
||||||
|
text,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.0.sp(),
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: isActive ? AppColors.primaryColor : AppColors.grey60,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import 'package:tm_app/views/profile/strings/profile_strings.dart';
|
|||||||
import 'package:tm_app/views/tenders/strings/tenders_strings.dart';
|
import 'package:tm_app/views/tenders/strings/tenders_strings.dart';
|
||||||
|
|
||||||
import '../../core/routes/app_routes.dart';
|
import '../../core/routes/app_routes.dart';
|
||||||
|
import '../../view_models/notification_view_model.dart';
|
||||||
|
|
||||||
class TabletNavigationWidget extends StatelessWidget {
|
class TabletNavigationWidget extends StatelessWidget {
|
||||||
const TabletNavigationWidget({required this.currentIndex, super.key});
|
const TabletNavigationWidget({required this.currentIndex, super.key});
|
||||||
@@ -93,6 +94,7 @@ class TabletNavigationWidget extends StatelessWidget {
|
|||||||
context,
|
context,
|
||||||
() => const NotificationRouteData().go(context),
|
() => const NotificationRouteData().go(context),
|
||||||
);
|
);
|
||||||
|
context.read<NotificationViewModel>().init();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
iconPath: AssetsManager.notify,
|
iconPath: AssetsManager.notify,
|
||||||
|
|||||||
Reference in New Issue
Block a user