@@ -308,15 +308,57 @@ extension SettingsProTab {
308308 self . detailStatusCard (
309309 icon: " checkmark.shield.fill " ,
310310 title: " Approvals " ,
311- detail: self . pendingApproval == nil ? " No gateway actions are waiting for review. " :
312- " Review the pending gateway action. " ,
313- value: self . pendingApproval == nil ? " clear " : " 1 waiting " ,
314- color: self . pendingApproval == nil ? OpenClawBrand . ok : OpenClawBrand . warn)
311+ detail: self . notificationsNeedAttention
312+ ? " Out-of-app approval alerts need notification permission. "
313+ : ( self . pendingApproval == nil ? " No gateway actions are waiting for review. " :
314+ " Review the pending gateway action. " ) ,
315+ value: self . notificationsNeedAttention
316+ ? " Alerts Off "
317+ : ( self . pendingApproval == nil ? " clear " : " 1 waiting " ) ,
318+ color: self . notificationsNeedAttention ? OpenClawBrand . warn :
319+ ( self . pendingApproval == nil ? OpenClawBrand . ok : OpenClawBrand . warn) )
320+
321+ if self . notificationsNeedAttention {
322+ self . approvalNotificationsWarningCard
323+ }
315324
316325 self . approvalsReviewCard
317326 }
318327 }
319328
329+ var approvalNotificationsWarningCard : some View {
330+ ProCard ( radius: SettingsLayout . cardRadius) {
331+ VStack ( alignment: . leading, spacing: 12 ) {
332+ HStack ( alignment: . top, spacing: 12 ) {
333+ ProIconBadge ( systemName: " bell.slash.fill " , color: OpenClawBrand . warn)
334+ VStack ( alignment: . leading, spacing: 4 ) {
335+ Text ( " Notifications are off " )
336+ . font ( . subheadline. weight ( . semibold) )
337+ Text (
338+ """
339+ Enable Notifications to receive approval notifications while OpenClaw is not open.
340+ """ )
341+ . font ( . caption)
342+ . foregroundStyle ( . secondary)
343+ . fixedSize ( horizontal: false , vertical: true )
344+ }
345+ }
346+
347+ if self . directRoute == nil {
348+ Button {
349+ self . openNotificationsRouteFromApprovals ( )
350+ } label: {
351+ Label ( " Open Notifications " , systemImage: " bell.badge " )
352+ . frame ( maxWidth: . infinity)
353+ }
354+ . buttonStyle ( . bordered)
355+ . controlSize ( . small)
356+ }
357+ }
358+ }
359+ . padding ( . horizontal, OpenClawProMetric . pagePadding)
360+ }
361+
320362 var approvalsReviewCard : some View {
321363 ProCard ( radius: SettingsLayout . cardRadius) {
322364 VStack ( alignment: . leading, spacing: 12 ) {
@@ -490,7 +532,7 @@ extension SettingsProTab {
490532 self . detailStatusCard (
491533 icon: " bell " ,
492534 title: " Notifications " ,
493- detail: " Approvals and event alerts from OpenClaw. " ,
535+ detail: self . notificationStatusDetail ,
494536 value: self . notificationStatusText,
495537 color: self . notificationStatus. color)
496538
@@ -506,10 +548,25 @@ extension SettingsProTab {
506548 }
507549 . buttonStyle ( . borderedProminent)
508550 . controlSize ( . small)
551+ . disabled ( self . notificationStatus == . checking || self . isRequestingNotificationAuthorization)
509552
510- Text ( " OpenClaw uses notifications for approval prompts and mirrored event alerts. " )
553+ Text ( self . notificationStatusDetail )
511554 . font ( . caption)
512555 . foregroundStyle ( . secondary)
556+ . fixedSize ( horizontal: false , vertical: true )
557+
558+ Divider ( )
559+
560+ HStack ( alignment: . top, spacing: 10 ) {
561+ Image ( systemName: " network " )
562+ . font ( . caption. weight ( . semibold) )
563+ . foregroundStyle ( OpenClawBrand . accent)
564+ . frame ( width: 22 , height: 22 )
565+ Text ( self . notificationRelayDetail)
566+ . font ( . caption)
567+ . foregroundStyle ( . secondary)
568+ . fixedSize ( horizontal: false , vertical: true )
569+ }
513570 }
514571 }
515572 . padding ( . horizontal, OpenClawProMetric . pagePadding)
0 commit comments