Improve show description UI
Instead of being a scroll window inside a scroll window, the show description now shows just the first paragraph by default, then displays a "Read More" button if there is more to the description. Clicking the button reveals the rest. Currently, to keep the button from glitching when updating it from the size-allocate signal, a GtkRevealer with a transition-duration of 1 millisecond is used. It's a hacky workaround but I'm not quite sure how to do it better. Fixes #81
This commit is contained in:
parent
eb2d5419f9
commit
8081990895
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1624,6 +1624,7 @@ dependencies = [
|
||||
"loggerv 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mpris-player 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"open 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pango 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"podcasts-data 0.1.0",
|
||||
"podcasts-downloader 0.1.0",
|
||||
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
||||
@ -29,6 +29,7 @@ serde_json = "1.0.41"
|
||||
# html2text = "0.1.8"
|
||||
html2text = { git = "https://github.com/jugglerchris/rust-html2text" }
|
||||
mpris-player = "0.4.0"
|
||||
pango = "0.7.0"
|
||||
|
||||
[dependencies.gettext-rs]
|
||||
git = "https://github.com/danigm/gettext-rs"
|
||||
|
||||
@ -58,38 +58,78 @@ Tobias Bernard
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<object class="HdyColumn">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="min_content_height">80</property>
|
||||
<property name="maximum_width">600</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<object class="GtkStack" id="description_stack">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="vhomogeneous">False</property>
|
||||
<property name="transition_type">none</property>
|
||||
<property name="interpolate_size">True</property>
|
||||
<property name="margin">12</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">fill</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="description_short">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="wrap_mode">word-char</property>
|
||||
<property name="ellipsize">end</property>
|
||||
<property name="lines">4</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="description_button_revealer">
|
||||
<property name="visible">True</property>
|
||||
<property name="reveal_child">False</property>
|
||||
<property name="transition_duration">1</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="description_button">
|
||||
<property name="label" translatable="yes">Read More</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="margin_top">12</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">short</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="description">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="label">This is embarrasing!
|
||||
Sorry, we could not find a description for this Show.</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="wrap_mode">word-char</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">full</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
|
||||
@ -43,6 +43,10 @@ pub(crate) struct ShowWidget {
|
||||
pub(crate) view: BaseView,
|
||||
cover: gtk::Image,
|
||||
description: gtk::Label,
|
||||
description_short: gtk::Label,
|
||||
description_stack: gtk::Stack,
|
||||
description_button: gtk::Button,
|
||||
description_button_revealer: gtk::Revealer,
|
||||
episodes: gtk::ListBox,
|
||||
show_id: Option<i32>,
|
||||
}
|
||||
@ -53,6 +57,11 @@ impl Default for ShowWidget {
|
||||
let sub_cont: gtk::Box = builder.get_object("sub_container").unwrap();
|
||||
let cover: gtk::Image = builder.get_object("cover").unwrap();
|
||||
let description: gtk::Label = builder.get_object("description").unwrap();
|
||||
let description_short: gtk::Label = builder.get_object("description_short").unwrap();
|
||||
let description_stack: gtk::Stack = builder.get_object("description_stack").unwrap();
|
||||
let description_button: gtk::Button = builder.get_object("description_button").unwrap();
|
||||
let description_button_revealer =
|
||||
builder.get_object("description_button_revealer").unwrap();
|
||||
let episodes = builder.get_object("episodes").unwrap();
|
||||
let view = BaseView::default();
|
||||
|
||||
@ -71,6 +80,10 @@ impl Default for ShowWidget {
|
||||
view,
|
||||
cover,
|
||||
description,
|
||||
description_short,
|
||||
description_stack,
|
||||
description_button,
|
||||
description_button_revealer,
|
||||
episodes,
|
||||
show_id: None,
|
||||
}
|
||||
@ -95,6 +108,18 @@ impl ShowWidget {
|
||||
let res = populate_listbox(&pdw, pd.clone(), sender, vadj);
|
||||
debug_assert!(res.is_ok());
|
||||
|
||||
let weak = Rc::downgrade(&pdw);
|
||||
pdw.description_short
|
||||
.connect_size_allocate(clone!(weak => move |_, _2| {
|
||||
weak.upgrade().map(|w| w.update_read_more());
|
||||
}));
|
||||
|
||||
pdw.description_button
|
||||
.connect_clicked(clone!(weak => move |_| {
|
||||
weak.upgrade()
|
||||
.map(|w| w.description_stack.set_visible_child_name("full"));
|
||||
}));
|
||||
|
||||
pdw
|
||||
}
|
||||
|
||||
@ -111,10 +136,31 @@ impl ShowWidget {
|
||||
utils::set_image_from_path(&self.cover, pd.id(), 256)
|
||||
}
|
||||
|
||||
fn update_read_more(&self) {
|
||||
if let Some(layout) = self.description_short.get_layout() {
|
||||
let more = layout.is_ellipsized()
|
||||
|| self.description.get_label() != self.description_short.get_label();
|
||||
self.description_button_revealer.set_reveal_child(more);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the description text.
|
||||
fn set_description(&self, text: &str) {
|
||||
self.description
|
||||
.set_markup(html2text::from_read(text.as_bytes(), 80).trim());
|
||||
let markup = html2text::from_read(text.as_bytes(), text.as_bytes().len());
|
||||
let markup = markup.trim();
|
||||
let lines: Vec<&str> = markup.lines().collect();
|
||||
|
||||
if markup.is_empty() {
|
||||
self.description_stack.set_visible(false);
|
||||
} else {
|
||||
self.description_stack.set_visible(true);
|
||||
|
||||
self.description.set_markup(markup);
|
||||
debug_assert!(lines.len() > 0);
|
||||
if lines.len() > 0 {
|
||||
self.description_short.set_markup(lines[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn show_id(&self) -> Option<i32> {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user