Merge pull request 'Refactor loading and error handling in DesktopHomePage; improve notification click handling in service worker' (#202) from some_fixes into main

Reviewed-on: https://repo.ravanertebat.com/TM/tm_app/pulls/202
This commit is contained in:
a.ghabeli
2025-10-05 10:24:19 +03:30
3 changed files with 117 additions and 58 deletions
+50 -45
View File
@@ -21,62 +21,67 @@ class DesktopHomePage extends StatelessWidget {
const DesktopNavigationWidget( const DesktopNavigationWidget(
currentIndex: 0, // Home index currentIndex: 0, // Home index
), ),
Expanded( Consumer<HomeViewModel>(
child: Consumer<HomeViewModel>( builder: (context, homeViewModel, child) {
builder: (context, homeViewModel, child) { if (homeViewModel.isLoading) {
if (homeViewModel.isLoading) { return const Expanded(
return const Center( child: Center(
child: CircularProgressIndicator( child: CircularProgressIndicator(
color: AppColors.secondary50, color: AppColors.secondary50,
), ),
); ),
} );
}
if (homeViewModel.errorMessage != null) { if (homeViewModel.errorMessage != null) {
return Center(child: Text(homeViewModel.errorMessage!)); return Expanded(
} child: Center(child: Text(homeViewModel.errorMessage!)),
);
}
if (homeViewModel.tenderApprovalsStateResponse != null && if (homeViewModel.tenderApprovalsStateResponse != null &&
homeViewModel.data != null && homeViewModel.data != null &&
homeViewModel.feedbackStats != null) { homeViewModel.feedbackStats != null) {
return SafeArea( return Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
child: SizedBox( child: SizedBox(
width: 780, width: double.infinity,
child: Column( child: Center(
crossAxisAlignment: CrossAxisAlignment.center, child: SizedBox(
children: [ width: 780,
const SizedBox(height: 55), child: Column(
// SizedBox(width: 780, child: NotificationCard()), crossAxisAlignment: CrossAxisAlignment.center,
const SizedBox(height: 40.0), children: [
_progressBarsRow(homeViewModel), const SizedBox(height: 55),
SizedBox(height: 32.0.h()), // SizedBox(width: 780, child: NotificationCard()),
Padding( const SizedBox(height: 40.0),
padding: EdgeInsets.symmetric( _progressBarsRow(homeViewModel),
horizontal: 15.0.w(), SizedBox(height: 32.0.h()),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 15.0.w(),
),
child: _firstTenderCardsRow(
context,
homeViewModel,
),
), ),
child: _firstTenderCardsRow( SizedBox(height: 32.0.h()),
context, _yourTenderText(homeViewModel),
homeViewModel, SizedBox(height: 8.0.h()),
), _bottomListView(homeViewModel),
), ],
SizedBox(height: 32.0.h()), ),
_yourTenderText(homeViewModel),
SizedBox(height: 8.0.h()),
_bottomListView(homeViewModel),
],
), ),
), ),
), ),
);
}
return const Center(
child: CircularProgressIndicator(
color: AppColors.secondary50,
), ),
); );
}, }
), return const Center(
child: CircularProgressIndicator(color: AppColors.secondary50),
);
},
), ),
], ],
), ),
@@ -97,6 +97,36 @@ class _MobileNotificationPageState extends State<MobileNotificationPage>
], ],
), ),
SizedBox(height: 12.0.h()), SizedBox(height: 12.0.h()),
Padding(
padding: EdgeInsetsDirectional.only(end: 24.0.w()),
child: Align(
alignment: Alignment.centerRight,
child: InkWell(
onTap: () {
viewModel.markAllAsRead(context);
},
borderRadius: BorderRadius.circular(99),
child: Container(
width: 132.0.w(),
height: 32.0.h(),
decoration: BoxDecoration(
color: AppColors.primary20,
borderRadius: BorderRadius.circular(99),
),
child: Center(
child: Text(
NotificationStrings.markAllAsReadButton,
style: TextStyle(
fontSize: 14.0.sp(),
fontWeight: FontWeight.w500,
color: AppColors.mainBlue,
),
),
),
),
),
),
),
Expanded( Expanded(
child: TabBarView( child: TabBarView(
controller: controller, controller: controller,
+37 -13
View File
@@ -14,25 +14,49 @@ firebase.initializeApp({
const messaging = firebase.messaging(); const messaging = firebase.messaging();
// Handle background messages // Handle background messages
messaging.onBackgroundMessage(async (payload) => { // messaging.onBackgroundMessage(async (payload) => {
const notificationTitle = payload.notification.title; // const notificationTitle = payload.notification.title;
const notificationOptions = { // const notificationOptions = {
body: payload.notification.body, // body: payload.notification.body,
badge: '/icons/Icon-192.svg', // badge: '/icons/Icon-192.svg',
icon: '/icons/notification.svg', // icon: '/icons/notification.svg',
data: payload.data, // data: payload.data,
click_action: payload.notification.click_action, // click_action: payload.notification.click_action,
}; // };
self.registration.showNotification(notificationTitle, notificationOptions); // self.registration.showNotification(notificationTitle, notificationOptions);
}); // });
// Open or focus the app when a notification is clicked // Open or focus the app when a notification is clicked
self.addEventListener('notificationclick', (event) => { self.addEventListener('notificationclick', (event) => {
event.notification.close(); event.notification.close();
const targetUrl = 'https://app.opplens.com/notification';
// Get the URL from the data payload, defaulting to the notification page
const urlToOpen = event.notification.data?.url || '/notification';
const baseUrl = 'https://app.opplens.com';
const targetUrl = urlToOpen.startsWith('http') ? urlToOpen : `${baseUrl}${urlToOpen}`;
console.log('Opening URL:', targetUrl);
event.waitUntil( event.waitUntil(
self.clients.openWindow(targetUrl) clients.matchAll({
type: 'window',
includeUncontrolled: true,
}).then((clientList) => {
// Find an open client (any tab/window belonging to your site)
const focusedClient = clientList.find(client => {
return new URL(client.url).origin === location.origin;
});
if (focusedClient) {
// If a client is open, navigate it to the new URL and focus it
focusedClient.navigate(urlToOpen);
return focusedClient.focus();
} else {
// Otherwise, open a new window
return clients.openWindow(targetUrl);
}
})
); );
}); });