Skip to content

Commit 18c999c

Browse files
committed
refactor advanced_message_dialog in own file
1 parent 65c71a5 commit 18c999c

File tree

3 files changed

+233
-185
lines changed

3 files changed

+233
-185
lines changed
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
use std::cell::OnceCell;
2+
3+
use adw::prelude::*;
4+
use adw::subclass::prelude::*;
5+
use gsv::prelude::*;
6+
use gtk::{gio, glib};
7+
8+
use crate::subscription::Subscription;
9+
use crate::widgets::*;
10+
11+
mod imp {
12+
use super::*;
13+
14+
#[derive(Debug, Default)]
15+
pub struct AdvancedMessageDialog {
16+
pub subscription: OnceCell<Subscription>,
17+
}
18+
19+
#[glib::object_subclass]
20+
impl ObjectSubclass for AdvancedMessageDialog {
21+
const NAME: &'static str = "AdvancedMessageDialog";
22+
type Type = super::AdvancedMessageDialog;
23+
type ParentType = adw::Window;
24+
}
25+
26+
impl ObjectImpl for AdvancedMessageDialog {}
27+
impl WidgetImpl for AdvancedMessageDialog {}
28+
impl WindowImpl for AdvancedMessageDialog {}
29+
impl AdwWindowImpl for AdvancedMessageDialog {}
30+
}
31+
32+
glib::wrapper! {
33+
pub struct AdvancedMessageDialog(ObjectSubclass<imp::AdvancedMessageDialog>)
34+
@extends gtk::Widget, gtk::Window, adw::Window;
35+
}
36+
37+
impl AdvancedMessageDialog {
38+
pub fn new(
39+
parent: &impl IsA<gtk::Window>,
40+
subscription: Subscription,
41+
message: String,
42+
) -> Self {
43+
let this: Self = glib::Object::new();
44+
this.set_transient_for(Some(parent));
45+
this.set_modal(true);
46+
this.set_default_height(400);
47+
this.imp().subscription.set(subscription).unwrap();
48+
this.build_ui(
49+
this.imp().subscription.get().unwrap().topic().clone(),
50+
message,
51+
);
52+
this
53+
}
54+
fn build_ui(&self, topic: String, message: String) {
55+
let this = self.clone();
56+
relm4_macros::view! {
57+
content = &adw::ToolbarView {
58+
add_top_bar = &adw::HeaderBar {},
59+
#[wrap(Some)]
60+
set_content: toast_overlay = &adw::ToastOverlay {
61+
#[wrap(Some)]
62+
set_child = &adw::Clamp {
63+
#[wrap(Some)]
64+
set_child = &gtk::Box {
65+
set_margin_top: 8,
66+
set_margin_bottom: 8,
67+
set_margin_start: 8,
68+
set_margin_end: 8,
69+
set_spacing: 8,
70+
set_orientation: gtk::Orientation::Vertical,
71+
append = &gtk::Label {
72+
set_label: "Here you can manually build the JSON message you want to POST to this topic",
73+
set_natural_wrap_mode: gtk::NaturalWrapMode::None,
74+
set_xalign: 0.0,
75+
set_halign: gtk::Align::Start,
76+
set_wrap_mode: gtk::pango::WrapMode::WordChar,
77+
set_wrap: true,
78+
},
79+
append = &gtk::Label {
80+
add_css_class: "heading",
81+
set_label: "JSON",
82+
set_xalign: 0.0,
83+
set_halign: gtk::Align::Start,
84+
},
85+
append = &gtk::ScrolledWindow {
86+
#[wrap(Some)]
87+
set_child: text_view = &gsv::View {
88+
add_css_class: "code",
89+
set_tab_width: 4,
90+
set_indent_width: 2,
91+
set_auto_indent: true,
92+
set_top_margin: 4,
93+
set_bottom_margin: 4,
94+
set_left_margin: 4,
95+
set_right_margin: 4,
96+
set_hexpand: true,
97+
set_vexpand: true,
98+
set_monospace: true,
99+
set_background_pattern: gsv::BackgroundPatternType::Grid
100+
},
101+
},
102+
append = &gtk::Label {
103+
add_css_class: "heading",
104+
set_label: "Snippets",
105+
set_xalign: 0.0,
106+
set_halign: gtk::Align::Start,
107+
},
108+
append = &gtk::FlowBox {
109+
set_column_spacing: 4,
110+
set_row_spacing: 4,
111+
append = &gtk::Button {
112+
add_css_class: "pill",
113+
add_css_class: "small",
114+
set_label: "Title",
115+
connect_clicked[text_view] => move |_| {
116+
text_view.buffer().insert_at_cursor(r#""title": "Title of your message""#)
117+
}
118+
},
119+
append = &gtk::Button {
120+
add_css_class: "pill",
121+
add_css_class: "small",
122+
set_label: "Tags",
123+
connect_clicked[text_view] => move |_| {
124+
text_view.buffer().insert_at_cursor(r#""tags": ["warning","cd"]"#)
125+
}
126+
},
127+
append = &gtk::Button {
128+
add_css_class: "pill",
129+
add_css_class: "small",
130+
set_label: "Priority",
131+
connect_clicked[text_view] => move |_| {
132+
text_view.buffer().insert_at_cursor(r#""priority": 5"#)
133+
}
134+
},
135+
append = &gtk::Button {
136+
add_css_class: "pill",
137+
add_css_class: "small",
138+
set_label: "View Action",
139+
connect_clicked[text_view] => move |_| {
140+
text_view.buffer().insert_at_cursor(r#""actions": [
141+
{
142+
"action": "view",
143+
"label": "torvalds boosted your toot",
144+
"url": "https://joinmastodon.org"
145+
}
146+
]"#)
147+
}
148+
},
149+
append = &gtk::Button {
150+
add_css_class: "pill",
151+
add_css_class: "small",
152+
set_label: "HTTP Action",
153+
connect_clicked[text_view] => move |_| {
154+
text_view.buffer().insert_at_cursor(r#""actions": [
155+
{
156+
"action": "http",
157+
"label": "Turn off lights",
158+
"method": "post",
159+
"url": "https://api.example.com/lights",
160+
"body": "OFF"
161+
}
162+
]"#)
163+
}
164+
},
165+
append = &gtk::Button {
166+
add_css_class: "circular",
167+
add_css_class: "small",
168+
set_label: "?",
169+
connect_clicked[this] => move |_| {
170+
gtk::UriLauncher::new("https://docs.ntfy.sh/publish/#publish-as-json").launch(
171+
Some(&this),
172+
gio::Cancellable::NONE,
173+
|_| {}
174+
);
175+
}
176+
},
177+
},
178+
append = &gtk::Button {
179+
set_margin_top: 8,
180+
set_margin_bottom: 8,
181+
add_css_class: "suggested-action",
182+
add_css_class: "pill",
183+
set_label: "Send",
184+
connect_clicked[this, toast_overlay, text_view] => move |_| {
185+
let thisc = this.clone();
186+
let text_view = text_view.clone();
187+
let f = async move {
188+
let buffer = text_view.buffer();
189+
let msg = serde_json::from_str(&buffer.text(
190+
&mut buffer.start_iter(),
191+
&mut buffer.end_iter(),
192+
true,
193+
)).map_err(|e| capnp::Error::failed(e.to_string()))?;
194+
thisc.imp().subscription.get().unwrap()
195+
.publish_msg(msg).await
196+
};
197+
toast_overlay.spawn_with_near_toast(f);
198+
}
199+
}
200+
}
201+
}
202+
}
203+
}
204+
}
205+
206+
let lang = gsv::LanguageManager::default().language("json").unwrap();
207+
let buffer = gsv::Buffer::with_language(&lang);
208+
buffer.set_text(&format!(
209+
r#"{{
210+
"topic": "{topic}",
211+
"message": "{message}"
212+
}}"#
213+
));
214+
text_view.set_buffer(Some(&buffer));
215+
216+
let manager = adw::StyleManager::default();
217+
let scheme_name = if manager.is_dark() {
218+
"solarized-dark"
219+
} else {
220+
"solarized-light"
221+
};
222+
let scheme = gsv::StyleSchemeManager::default().scheme(scheme_name);
223+
buffer.set_style_scheme(scheme.as_ref());
224+
this.set_content(Some(&content));
225+
}
226+
}

src/widgets/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
mod add_subscription_dialog;
2+
mod advanced_message_dialog;
23
mod message_row;
34
mod subscription_info_dialog;
45
mod window;
56
pub use add_subscription_dialog::AddSubscriptionDialog;
7+
pub use advanced_message_dialog::*;
68
pub use message_row::*;
79
pub use subscription_info_dialog::SubscriptionInfoDialog;
810
pub use window::*;

0 commit comments

Comments
 (0)