Skip to content

Commit 4d0a007

Browse files
committed
Add FluentNotificationTriggerModel for easier client interactions with FluentNotification
1 parent 29dc07d commit 4d0a007

File tree

4 files changed

+35
-19
lines changed

4 files changed

+35
-19
lines changed

Demos/FluentUIDemo_iOS/FluentUI.Demo/Demos/NotificationViewDemoController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ class NotificationViewDemoController: DemoController {
248248
notification.state.actionButtonTitle = "Bump"
249249

250250
notification.state.actionButtonAction = { [weak notification] in
251-
notification?.state.bump()
251+
notification?.performBumpAnimation()
252252
}
253253

254254
return notification

Demos/FluentUIDemo_iOS/FluentUI.Demo/Demos/NotificationViewDemoController_SwiftUI.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ struct NotificationDemoView: View {
5252
@State var useCustomTheme: Bool = false
5353
@State var verticalOffset: CGFloat = 0.0
5454
@ObservedObject var fluentTheme: FluentTheme = .shared
55+
private var triggerModel = FluentNotificationTriggerModel()
5556
let customTheme: FluentTheme = {
5657
let foregroundColor = UIColor(light: GlobalTokens.sharedColor(.lavender, .shade30),
5758
dark: GlobalTokens.sharedColor(.lavender, .tint40))
@@ -171,7 +172,7 @@ struct NotificationDemoView: View {
171172
showActionButtonAndDismissButton: showActionButtonAndDismissButton,
172173
defaultDismissButtonAction: dismissButtonAction,
173174
messageButtonAction: messageButtonAction,
174-
showFromBottom: showFromBottom)
175+
showFromBottom: showFromBottom, triggerModel: triggerModel)
175176
.backgroundGradient(showBackgroundGradient ? backgroundGradient : nil)
176177
.overrideTokens($overrideTokens.wrappedValue ? notificationOverrideTokens : nil)
177178
}
@@ -212,7 +213,7 @@ struct NotificationDemoView: View {
212213
showActionButtonAndDismissButton: showActionButtonAndDismissButton,
213214
messageButtonAction: messageButtonAction,
214215
showFromBottom: showFromBottom,
215-
verticalOffset: verticalOffset)
216+
verticalOffset: verticalOffset, triggerModel: triggerModel)
216217
.backgroundGradient(showBackgroundGradient ? backgroundGradient : nil)
217218
.overrideTokens($overrideTokens.wrappedValue ? notificationOverrideTokens : nil)
218219
}
@@ -263,6 +264,9 @@ struct NotificationDemoView: View {
263264
Toggle("Has Attributed Text: Large Red Papyrus Font", isOn: $hasLargeRedPapyrusFontAttribute)
264265
Toggle("Set image", isOn: $showImage)
265266
Toggle("Set trailing image", isOn: $showTrailingImage)
267+
Button("Perform Bump") {
268+
triggerModel.shouldBump = true
269+
}
266270
}
267271

268272
FluentListSection("Action") {

Sources/FluentUI_iOS/Components/Notification/FluentNotification.swift

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#if canImport(FluentUI_common)
77
import FluentUI_common
88
#endif
9+
import Combine
910
import SwiftUI
1011

1112
/// Properties that can be used to customize the appearance of the `Notification`.
@@ -67,10 +68,17 @@ import SwiftUI
6768
///
6869
/// If this property is nil, then this notification will use the background color defined by its design tokens.
6970
var backgroundGradient: LinearGradientInfo? { get set }
71+
}
7072

71-
/// Performs an animation emphasizing the notification.
72-
/// The animation alternates between upward and downward movements with spring physics.
73-
func bump()
73+
/// Exposes public published properties that are observed by the `FluentNotification`. Enables
74+
/// easy interaction with the Notification for clients.
75+
@objc(MSFFluentNotificationTriggerModel)
76+
public class FluentNotificationTriggerModel: NSObject, ObservableObject {
77+
/// Triggers the bump animation for the notification.
78+
///
79+
/// Set this to `true` to trigger the bump animation. The value will be
80+
/// automatically reset to `false` after the animation is triggered.
81+
@Published public var shouldBump: Bool = false
7482
}
7583

7684
/// View that represents the Notification.
@@ -116,7 +124,9 @@ public struct FluentNotification: View, TokenizedControlView {
116124
defaultDismissButtonAction: (() -> Void)? = nil,
117125
messageButtonAction: (() -> Void)? = nil,
118126
showFromBottom: Bool = true,
119-
verticalOffset: CGFloat = 0.0) {
127+
verticalOffset: CGFloat = 0.0,
128+
triggerModel: FluentNotificationTriggerModel = FluentNotificationTriggerModel(),
129+
onDismiss: (() -> Void)? = nil) {
120130
let state = MSFNotificationStateImpl(style: style,
121131
message: message,
122132
attributedMessage: attributedMessage,
@@ -133,9 +143,11 @@ public struct FluentNotification: View, TokenizedControlView {
133143
messageButtonAction: messageButtonAction,
134144
showFromBottom: showFromBottom,
135145
verticalOffset: verticalOffset)
146+
state.onDismiss = onDismiss
136147
self.state = state
137148
self.shouldSelfPresent = shouldSelfPresent
138149
self.isFlexibleWidthToast = isFlexibleWidthToast && style.isToast
150+
self.triggerModel = triggerModel
139151

140152
self.tokenSet = NotificationTokenSet(style: { state.style })
141153

@@ -328,9 +340,9 @@ public struct FluentNotification: View, TokenizedControlView {
328340
.glassBackgroundEffect(in: RoundedRectangle(cornerRadius: tokenSet[.cornerRadius].float))
329341
#endif // os(visionOS)
330342
.offset(y: -bumpVerticalOffset)
331-
.onChange(of: state.shouldPerformBump) { _, shouldBump in
343+
.onChange(of: triggerModel.shouldBump) { _, shouldBump in
332344
if shouldBump {
333-
state.shouldPerformBump = false
345+
triggerModel.shouldBump = false
334346
performBumpAnimated()
335347
}
336348
}
@@ -390,6 +402,7 @@ public struct FluentNotification: View, TokenizedControlView {
390402

391403
@Environment(\.fluentTheme) var fluentTheme: FluentTheme
392404
@ObservedObject var state: MSFNotificationStateImpl
405+
@ObservedObject var triggerModel: FluentNotificationTriggerModel
393406

394407
/// The `dismissButtonAction` will be non-nil for the following cases:
395408
/// - The `state.actionButtonAction` is set but there is no custom title or trailing image. The `actionButtonAction`
@@ -522,9 +535,6 @@ class MSFNotificationStateImpl: ControlState, MSFNotificationState {
522535
/// Style to draw the control.
523536
@Published var style: MSFNotificationStyle
524537

525-
/// Controls whether the bump animation should start
526-
@Published internal var shouldPerformBump: Bool = false
527-
528538
@objc convenience init(style: MSFNotificationStyle) {
529539
self.init(style: style,
530540
message: nil,
@@ -578,10 +588,4 @@ class MSFNotificationStateImpl: ControlState, MSFNotificationState {
578588

579589
super.init()
580590
}
581-
582-
@objc func bump() {
583-
if !shouldPerformBump {
584-
shouldPerformBump = true
585-
}
586-
}
587591
}

Sources/FluentUI_iOS/Components/Notification/MSFNotification.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ import UIKit
2626
@objc public init(style: MSFNotificationStyle,
2727
isFlexibleWidthToast: Bool = false) {
2828
self.isFlexibleWidthToast = isFlexibleWidthToast && style.isToast
29+
self.triggerModel = FluentNotificationTriggerModel()
2930
notification = FluentNotification(style: style,
30-
shouldSelfPresent: false)
31+
shouldSelfPresent: false,
32+
triggerModel: triggerModel)
3133
super.init(AnyView(notification), safeAreaRegions: [])
3234
let defaultDismissAction = { [weak self] in
3335
guard let strongSelf = self else {
@@ -211,6 +213,11 @@ import UIKit
211213
}
212214
}
213215

216+
/// Triggers the bump animation for the notification
217+
@objc public func performBumpAnimation() {
218+
triggerModel.shouldBump = true
219+
}
220+
214221
// MARK: - Private variables
215222
private static var currentToast: MSFNotification? {
216223
didSet {
@@ -224,5 +231,6 @@ import UIKit
224231
private var constraintWhenHidden: NSLayoutConstraint!
225232
private var constraintWhenShown: NSLayoutConstraint!
226233
private var notification: FluentNotification!
234+
private var triggerModel: FluentNotificationTriggerModel
227235
private var isHiding: Bool = false
228236
}

0 commit comments

Comments
 (0)