@@ -4,6 +4,7 @@ use std::cell::OnceCell;
44use adw:: prelude:: * ;
55use adw:: subclass:: prelude:: * ;
66use futures:: prelude:: * ;
7+ use gsv:: prelude:: * ;
78use gtk:: { gio, glib} ;
89use ntfy_daemon:: models;
910use ntfy_daemon:: ntfy_capnp:: { system_notifier, Status } ;
@@ -26,13 +27,17 @@ impl<W: glib::IsA<gtk::Widget>> SpawnWithToast for W {
2627 & self ,
2728 f : impl Future < Output = Result < T , R > > + ' static ,
2829 ) {
29- let p: Option < NotifyWindow > = self . ancestor ( NotifyWindow :: static_type ( ) ) . and_downcast ( ) ;
30+ let toast_overlay: Option < adw:: ToastOverlay > = self
31+ . ancestor ( adw:: ToastOverlay :: static_type ( ) )
32+ . and_downcast ( ) ;
33+ let win: Option < NotifyWindow > = self . ancestor ( NotifyWindow :: static_type ( ) ) . and_downcast ( ) ;
3034 glib:: MainContext :: default ( ) . spawn_local ( async move {
3135 if let Err ( e) = f. await {
32- if let Some ( p) = p {
33- p. imp ( )
34- . toast_overlay
35- . add_toast ( adw:: Toast :: builder ( ) . title ( & e. to_string ( ) ) . build ( ) )
36+ if let Some ( o) = toast_overlay
37+ . as_ref ( )
38+ . or_else ( || win. as_ref ( ) . map ( |win| win. imp ( ) . toast_overlay . as_ref ( ) ) )
39+ {
40+ o. add_toast ( adw:: Toast :: builder ( ) . title ( & e. to_string ( ) ) . build ( ) )
3641 }
3742 }
3843 } ) ;
@@ -255,13 +260,6 @@ impl NotifyWindow {
255260 let this = self . clone ( ) ;
256261 let topic = self . selected_subscription ( ) . unwrap ( ) . topic ( ) ;
257262 let message = imp. entry . text ( ) ;
258- let buffer = gtk:: TextBuffer :: new ( None ) ;
259- buffer. set_text ( & format ! (
260- r#"{{
261- "topic": "{topic}",
262- "message": "{message}"
263- }}"#
264- ) ) ;
265263 relm4_macros:: view! {
266264 window = adw:: Window {
267265 set_modal: true ,
@@ -270,50 +268,127 @@ impl NotifyWindow {
270268 set_content = & adw:: ToolbarView {
271269 add_top_bar = & adw:: HeaderBar { } ,
272270 #[ wrap( Some ) ]
273- set_content = & adw:: Clamp {
271+ set_content: toast_overlay = & adw:: ToastOverlay {
274272 #[ wrap( Some ) ]
275- set_child = & gtk:: Box {
276- set_margin_top: 8 ,
277- set_margin_bottom: 8 ,
278- set_margin_start: 8 ,
279- set_margin_end: 8 ,
280- set_spacing: 8 ,
281- set_orientation: gtk:: Orientation :: Vertical ,
282- append = & gtk:: Label {
283- set_label: "Here you can manually build the JSON message you want to POST to this topic" ,
284- set_xalign: 0.0 ,
285- set_halign: gtk:: Align :: Start ,
286- set_wrap_mode: gtk:: pango:: WrapMode :: WordChar ,
287- set_wrap: true ,
288- } ,
289- append: text_view = & gtk:: TextView {
290- set_top_margin: 8 ,
291- set_bottom_margin: 8 ,
292- set_left_margin: 8 ,
293- set_right_margin: 8 ,
294- set_hexpand: true ,
295- set_vexpand: true ,
296- set_buffer: Some ( & buffer) ,
297- } ,
298- append = & gtk:: Box {
299- set_halign: gtk:: Align :: Center ,
273+ set_child = & adw:: Clamp {
274+ #[ wrap( Some ) ]
275+ set_child = & gtk:: Box {
276+ set_margin_top: 8 ,
277+ set_margin_bottom: 8 ,
278+ set_margin_start: 8 ,
279+ set_margin_end: 8 ,
300280 set_spacing: 8 ,
301- append = & gtk:: Button {
302- add_css_class: "pill" ,
303- set_label: "Documentation" ,
304- connect_clicked[ this] => move |_| {
305- gtk:: UriLauncher :: new( "https://docs.ntfy.sh/publish/#publish-as-json" ) . launch(
306- Some ( & this) ,
307- gio:: Cancellable :: NONE ,
308- |_| { }
309- ) ;
310- }
281+ set_orientation: gtk:: Orientation :: Vertical ,
282+ append = & gtk:: Label {
283+ set_label: "Here you can manually build the JSON message you want to POST to this topic" ,
284+ set_natural_wrap_mode: gtk:: NaturalWrapMode :: None ,
285+ set_xalign: 0.0 ,
286+ set_halign: gtk:: Align :: Start ,
287+ set_wrap_mode: gtk:: pango:: WrapMode :: WordChar ,
288+ set_wrap: true ,
289+ } ,
290+ append = & gtk:: Label {
291+ add_css_class: "heading" ,
292+ set_label: "JSON" ,
293+ set_xalign: 0.0 ,
294+ set_halign: gtk:: Align :: Start ,
295+ } ,
296+ append: text_view = & gsv:: View {
297+ add_css_class: "code" ,
298+ set_tab_width: 4 ,
299+ set_indent_width: 2 ,
300+ set_auto_indent: true ,
301+ set_top_margin: 4 ,
302+ set_bottom_margin: 4 ,
303+ set_left_margin: 4 ,
304+ set_right_margin: 4 ,
305+ set_hexpand: true ,
306+ set_vexpand: true ,
307+ set_monospace: true ,
308+ set_background_pattern: gsv:: BackgroundPatternType :: Grid
309+ } ,
310+ append = & gtk:: Label {
311+ add_css_class: "heading" ,
312+ set_label: "Snippets" ,
313+ set_xalign: 0.0 ,
314+ set_halign: gtk:: Align :: Start ,
315+ } ,
316+ append = & gtk:: Box {
317+ set_spacing: 4 ,
318+ append = & gtk:: Button {
319+ add_css_class: "pill" ,
320+ add_css_class: "small" ,
321+ set_label: "Title" ,
322+ connect_clicked[ text_view] => move |_| {
323+ text_view. buffer( ) . insert_at_cursor( r#""title": "Title of your message""# )
324+ }
325+ } ,
326+ append = & gtk:: Button {
327+ add_css_class: "pill" ,
328+ add_css_class: "small" ,
329+ set_label: "Tags" ,
330+ connect_clicked[ text_view] => move |_| {
331+ text_view. buffer( ) . insert_at_cursor( r#""tags": ["warning","cd"]"# )
332+ }
333+ } ,
334+ append = & gtk:: Button {
335+ add_css_class: "pill" ,
336+ add_css_class: "small" ,
337+ set_label: "Priority" ,
338+ connect_clicked[ text_view] => move |_| {
339+ text_view. buffer( ) . insert_at_cursor( r#""priority": 5"# )
340+ }
341+ } ,
342+ append = & gtk:: Button {
343+ add_css_class: "pill" ,
344+ add_css_class: "small" ,
345+ set_label: "View Action" ,
346+ connect_clicked[ text_view] => move |_| {
347+ text_view. buffer( ) . insert_at_cursor( r#""action": [
348+ {
349+ "type": "view",
350+ "label": "torvalds boosted your toot",
351+ "url": "https://joinmastodon.org"
352+ }
353+ ]"# )
354+ }
355+ } ,
356+ append = & gtk:: Button {
357+ add_css_class: "pill" ,
358+ add_css_class: "small" ,
359+ set_label: "HTTP Action" ,
360+ connect_clicked[ text_view] => move |_| {
361+ text_view. buffer( ) . insert_at_cursor( r#""action": [
362+ {
363+ "type": "http",
364+ "label": "Turn off lights",
365+ "method": "post",
366+ "url": "https://api.example.com/lights",
367+ "body": "OFF"
368+ }
369+ ]"# )
370+ }
371+ } ,
372+ append = & gtk:: Button {
373+ add_css_class: "circular" ,
374+ add_css_class: "small" ,
375+ set_label: "?" ,
376+ connect_clicked[ this] => move |_| {
377+ gtk:: UriLauncher :: new( "https://docs.ntfy.sh/publish/#publish-as-json" ) . launch(
378+ Some ( & this) ,
379+ gio:: Cancellable :: NONE ,
380+ |_| { }
381+ ) ;
382+ }
383+ } ,
311384 } ,
312385 append = & gtk:: Button {
386+ set_margin_top: 8 ,
387+ set_margin_bottom: 8 ,
313388 add_css_class: "suggested-action" ,
314389 add_css_class: "pill" ,
315390 set_label: "Send" ,
316- connect_clicked[ this, text_view] => move |_| {
391+ connect_clicked[ this, toast_overlay , text_view] => move |_| {
317392 let thisc = this. clone( ) ;
318393 let text_view = text_view. clone( ) ;
319394 let f = async move {
@@ -327,7 +402,7 @@ impl NotifyWindow {
327402 . unwrap( )
328403 . publish_msg( msg) . await
329404 } ;
330- this . spawn_with_near_toast( f) ;
405+ toast_overlay . spawn_with_near_toast( f) ;
331406 }
332407 }
333408 }
@@ -336,6 +411,26 @@ impl NotifyWindow {
336411 }
337412 }
338413 }
414+
415+ let lang = gsv:: LanguageManager :: default ( ) . language ( "json" ) . unwrap ( ) ;
416+ let buffer = gsv:: Buffer :: with_language ( & lang) ;
417+ buffer. set_text ( & format ! (
418+ r#"{{
419+ "topic": "{topic}",
420+ "message": "{message}"
421+ }}"#
422+ ) ) ;
423+ text_view. set_buffer ( Some ( & buffer) ) ;
424+
425+ let manager = adw:: StyleManager :: default ( ) ;
426+ let scheme_name = if manager. is_dark ( ) {
427+ "solarized-dark"
428+ } else {
429+ "solarized-light"
430+ } ;
431+ let scheme = gsv:: StyleSchemeManager :: default ( ) . scheme ( scheme_name) ;
432+ buffer. set_style_scheme ( scheme. as_ref ( ) ) ;
433+
339434 window. present ( ) ;
340435 }
341436 fn show_subscription_info ( & self ) {
0 commit comments