Skip to content

Commit 0874443

Browse files
committed
Improve notification sample
1 parent d6497f0 commit 0874443

File tree

1 file changed

+74
-19
lines changed

1 file changed

+74
-19
lines changed

samples/Gallery/Pages/NotificationsPage.fs

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,34 @@ module NotificationsPage =
2929
| ShowAsyncStatusNotifications
3030
| ToggleInlinedNotification
3131
| NotifyInfo of string
32-
| YesCommand
33-
| NoCommand
3432
| AttachedToVisualTreeChanged of VisualTreeAttachmentEventArgs // event after which WindowNotificationManager is available
3533
| ControlNotificationsShow
3634
| NotificationShown
3735
| PositionChanged of SelectionChangedEventArgs
3836

37+
type WindowNotificationManager with
38+
member this.Show(content: WidgetBuilder<'msg, 'marker>) =
39+
let widget = content.Compile()
40+
let widgetDef = WidgetDefinitionStore.get widget.Key
41+
let logger = ProgramDefaults.defaultLogger()
42+
let syncAction = ViewHelpers.defaultSyncAction
43+
44+
let treeContext: ViewTreeContext =
45+
{ CanReuseView = ViewHelpers.canReuseView
46+
GetViewNode = ViewNode.get
47+
GetComponent = Component.get
48+
SetComponent = Component.set
49+
SyncAction = syncAction
50+
Logger = logger
51+
Dispatch = ignore }
52+
53+
let envContext = new EnvironmentContext(logger)
54+
55+
let struct (_node, view) =
56+
widgetDef.CreateView(widget, envContext, treeContext, ValueNone)
57+
58+
this.Show(view)
59+
3960
let notifyOneAsync () =
4061
Cmd.OfAsync.msg(
4162
async {
@@ -70,18 +91,33 @@ module NotificationsPage =
7091
notificationManager.Show(notification)
7192
dispatch(NotificationShown)))
7293

73-
let showNotificationContent (notificationManager: WindowNotificationManager) (content: WidgetBuilder<'msg, 'marker>) =
94+
let showNotificationContent<'msg, 'marker when 'msg: equality>
95+
(notificationManager: WindowNotificationManager)
96+
(content: WidgetBuilder<'msg, 'marker>)
97+
: Cmd<'msg> =
7498
Cmd.ofEffect(fun dispatch ->
7599
Dispatcher.UIThread.Post(fun () ->
100+
// Compile with the real dispatcher so events inside the notification can send messages
76101
let widget = content.Compile()
77102
let widgetDef = WidgetDefinitionStore.get widget.Key
103+
let logger = ProgramDefaults.defaultLogger()
104+
let syncAction = ViewHelpers.defaultSyncAction
78105

79-
// TODO how to attach or create the view? how to get TreeContext and EnvironmentContext?
80-
(*let struct (_node, view) =
81-
widgetDef.CreateView(widget, ...?, ...?, ValueNone)
106+
let treeContext: ViewTreeContext =
107+
{ CanReuseView = ViewHelpers.canReuseView
108+
GetViewNode = ViewNode.get
109+
GetComponent = Component.get
110+
SetComponent = Component.set
111+
SyncAction = syncAction
112+
Logger = logger
113+
Dispatch = (fun m -> dispatch(unbox m)) }
82114

83-
notificationManager.Show(view)*)
84-
dispatch(NotificationShown)))
115+
let envContext = new EnvironmentContext(logger)
116+
117+
let struct (_node, view) =
118+
widgetDef.CreateView(widget, envContext, treeContext, ValueNone)
119+
120+
notificationManager.Show(view)))
85121

86122
let controlNotificationsRef = ViewRef<WindowNotificationManager>()
87123

@@ -101,7 +137,27 @@ module NotificationsPage =
101137
ShowInlined = false },
102138
[]
103139

104-
let questionContent title question = InlinedYesNoQuestion(title, question, YesCommand, NoCommand)
140+
type QuestionLocalMsg =
141+
| LocalYes
142+
| LocalNo
143+
144+
let questionInit () = (), Cmd.none
145+
146+
let questionUpdate (msg: QuestionLocalMsg) (model: unit) =
147+
let show (title: string) (message: string) : Cmd<QuestionLocalMsg> =
148+
Cmd.ofEffect(fun _ -> Dispatcher.UIThread.Post(fun () -> FabApplication.Current.WindowNotificationManager.Show(Notification(title, message))))
149+
150+
match msg with
151+
| LocalYes -> model, show "Wise choice." "You better!"
152+
| LocalNo -> model, show "What?" "Why wouldn't you?"
153+
154+
let questionProgram = Program.statefulWithCmd questionInit questionUpdate
155+
156+
let questionContent title question =
157+
Component("QuestionContent") {
158+
let! _ = Context.Mvu questionProgram
159+
InlinedYesNoQuestion(title, question, QuestionLocalMsg.LocalYes, QuestionLocalMsg.LocalNo)
160+
}
105161

106162
let update msg model =
107163
match msg with
@@ -111,22 +167,22 @@ module NotificationsPage =
111167
| ShowCustomPlainNotification ->
112168
model,
113169
showNotification model.NotificationManager (notification "Hey There!" "Did you know that Avalonia now supports Custom In-Window Notifications?")
114-
170+
115171
| ShowCustomManagedNotification ->
116-
model,
117-
showNotificationContent model.NotificationManager (questionContent "Can you dig it?" "You can use standard widgets in notifications!")
172+
model, showNotificationContent model.NotificationManager (questionContent "Can you dig it?" "You can use standard widgets in notifications!")
118173

119174
| ShowNativeNotification ->
120175
model,
121176
showNotification model.NotificationManager (Notification("Error", "Native Notifications are not quite ready. Coming soon.", NotificationType.Error))
122177

123178
| ShowAsyncCompletedNotification -> model, notifyOneAsync()
124179
| ShowAsyncStatusNotifications -> model, notifyAsyncStatusUpdates()
125-
| ToggleInlinedNotification -> {model with ShowInlined = not model.ShowInlined}, Cmd.none
180+
| ToggleInlinedNotification ->
181+
{ model with
182+
ShowInlined = not model.ShowInlined },
183+
Cmd.none
126184

127185
| NotifyInfo message -> model, showNotification model.NotificationManager (Notification(message, "", NotificationType.Information))
128-
| YesCommand -> model, showNotification model.NotificationManager (Notification("Wise choice.", "You better!"))
129-
| NoCommand -> model, showNotification model.NotificationManager (Notification("What?", "Why wouldn't you?"))
130186

131187
(* WindowNotificationManager can't be used immediately after creating it,
132188
so we need to wait for it to be attached to the visual tree.
@@ -216,21 +272,20 @@ module NotificationsPage =
216272
})
217273
.dock(Dock.Top)
218274

219-
InlinedYesNoQuestion("Can you believe it?", "You can also roll your own inlined dialogs using standard widgets.", YesCommand, NoCommand)
275+
(questionContent "Can you believe it?" "You can also roll your own inlined dialogs using standard widgets.")
220276
.isVisible(model.ShowInlined)
221277
.dock(Dock.Top)
222278

223-
//TODO toggling the isClosed flag seems to do nothing. Why include it in the builders at all?
279+
// Demonstrate NotificationCard controlled solely via its IsClosed flag. Avoid .isVisible, which masks the effect.
224280
NotificationCard(not model.ShowInlined, "I was here all along, just hidden!")
225-
.isVisible(model.ShowInlined)
226281
.size(300., 70.)
227282
.dock(Dock.Top)
228283
.padding(10)
229284
.borderBrush(SolidColorBrush(Colors.Blue))
230285
}
231286

232287
// We can use the WindowNotificationManager a widget to be able to have a different WindowNotificationManager than FabApplication.Current.WindowNotificationManager
233-
// Allowing you control ie the Position of a single notification
288+
// Allowing you to control ie the Position of a single notification
234289
WindowNotificationManager(controlNotificationsRef)
235290
.position(model.NotificationPosition)
236291
.dock(Dock.Top)

0 commit comments

Comments
 (0)