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:
a.ghabeli
2025-09-27 10:47:52 +03:30
6 changed files with 139 additions and 90 deletions
@@ -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();
}
}); });
} }
+68 -28
View File
@@ -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,7 +208,8 @@ 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 =
(all.where((n) {
final p = n.priority ?? ''; final p = n.priority ?? '';
return p.toLowerCase() == 'important'; return p.toLowerCase() == 'important';
}).toList()); }).toList());
@@ -229,11 +259,14 @@ 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 =
allNotificationResponse!.data!.notifications!
.map((n) => n.copyWith(seen: true)) .map((n) => n.copyWith(seen: true))
.toList(); .toList();
@@ -244,15 +277,19 @@ 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 =
importantNotificationResponse!.data!.notifications!
.map((n) => n.copyWith(seen: true)) .map((n) => n.copyWith(seen: true))
.toList(); .toList();
importantNotificationResponse = importantNotificationResponse!.copyWith( importantNotificationResponse = importantNotificationResponse!
.copyWith(
data: importantNotificationResponse!.data!.copyWith( data: importantNotificationResponse!.data!.copyWith(
notifications: updatedImportant, notifications: updatedImportant,
), ),
@@ -261,7 +298,10 @@ class NotificationViewModel with ChangeNotifier {
} }
if (context.mounted) { if (context.mounted) {
AppToast.success(context, NotificationStrings.allNotificationMarkedAsRead); AppToast.success(
context,
NotificationStrings.allNotificationMarkedAsRead,
);
} }
} else { } else {
_errorMessage = message; _errorMessage = message;
+2
View File
@@ -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,
@@ -200,5 +201,4 @@ Widget _navigationItem({
), ),
); );
} }
} }
@@ -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,