Tidy up ConversationMessage styling and state management.
* src/client/components/main-window.vala: Adjust theme CSS style to account for new widget classes. Fix style for last row in the convo listbox. * src/client/conversation-viewer/conversation-message.vala: Decouple updating message state and updating message flags. Prefix CSS classes with "geary_" to prevent class name clashes. * src/client/conversation-viewer/conversation-viewer.vala: Manually maintain a CSS class on the last row of the convo listbox to work around Bug 764710. Prefix CSS classes with "geary_" to prevent class name clashes. (ConversationViewer::on_update_flags): Renamed from update_flags since it is only ever called as a signal handler. Remove most of the work - it is now done by ConversationMessage.
This commit is contained in:
parent
0a4611a3f4
commit
9e7fee035a
3 changed files with 78 additions and 64 deletions
|
|
@ -57,6 +57,9 @@ public class ConversationMessage : Gtk.Box {
|
|||
// The allocation for the web view
|
||||
public Gdk.Rectangle web_view_allocation { get; private set; }
|
||||
|
||||
// Is the message body shown or not?
|
||||
public bool is_message_body_visible = false;
|
||||
|
||||
// Has the message body been been fully loaded?
|
||||
public bool is_loading_complete = false;
|
||||
|
||||
|
|
@ -235,15 +238,12 @@ public class ConversationMessage : Gtk.Box {
|
|||
// }
|
||||
// }
|
||||
|
||||
update_flags(email);
|
||||
update_message_state(false);
|
||||
}
|
||||
|
||||
public bool is_message_visible() {
|
||||
return get_style_context().has_class("show-message");
|
||||
}
|
||||
|
||||
public void show_message(bool include_transitions=true) {
|
||||
get_style_context().add_class("show-message");
|
||||
public void show_message_body(bool include_transitions=true) {
|
||||
is_message_body_visible = true;
|
||||
get_style_context().add_class("geary_show_body");
|
||||
avatar_image.set_pixel_size(32); // XXX constant
|
||||
|
||||
Gtk.RevealerTransitionType revealer = preview_revealer.get_transition_type();
|
||||
|
|
@ -264,7 +264,6 @@ public class ConversationMessage : Gtk.Box {
|
|||
unstar_button.set_sensitive(true);
|
||||
message_menubutton.set_sensitive(true);
|
||||
|
||||
// XXX this is pretty gross
|
||||
revealer = body_revealer.get_transition_type();
|
||||
if (!include_transitions) {
|
||||
body_revealer.set_transition_type(Gtk.RevealerTransitionType.NONE);
|
||||
|
|
@ -273,8 +272,9 @@ public class ConversationMessage : Gtk.Box {
|
|||
body_revealer.set_transition_type(revealer);
|
||||
}
|
||||
|
||||
public void hide_message() {
|
||||
get_style_context().remove_class("show-message");
|
||||
public void hide_message_body() {
|
||||
is_message_body_visible = false;
|
||||
get_style_context().remove_class("geary_show_body");
|
||||
avatar_image.set_pixel_size(24); // XXX constant
|
||||
preview_revealer.set_reveal_child(true);
|
||||
header_revealer.set_reveal_child(false);
|
||||
|
|
@ -379,11 +379,20 @@ public class ConversationMessage : Gtk.Box {
|
|||
return menu;
|
||||
}
|
||||
|
||||
public void update_flags(Geary.Email email) {
|
||||
this.email.set_flags(email.email_flags);
|
||||
update_message_state();
|
||||
}
|
||||
|
||||
public bool is_manual_read() {
|
||||
return get_style_context().has_class("geary_manual_read");
|
||||
}
|
||||
|
||||
public void update_flags(Geary.Email email) {
|
||||
public void mark_manual_read() {
|
||||
get_style_context().add_class("geary_manual_read");
|
||||
}
|
||||
|
||||
private void update_message_state(bool include_transitions=true) {
|
||||
Geary.EmailFlags flags = email.email_flags;
|
||||
Gtk.StyleContext style = get_style_context();
|
||||
|
||||
|
|
@ -409,10 +418,6 @@ public class ConversationMessage : Gtk.Box {
|
|||
// Geary.SpecialFolderType.SENT.get_display_name()));
|
||||
}
|
||||
|
||||
public void mark_manual_read() {
|
||||
get_style_context().add_class("manual_read");
|
||||
}
|
||||
|
||||
private void load_message_body() {
|
||||
bool load_images = false;
|
||||
string? body_text = null;
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ public class ConversationViewer : Gtk.Stack {
|
|||
// Conversation messages list
|
||||
[GtkChild]
|
||||
private Gtk.ListBox conversation_listbox;
|
||||
private Gtk.Widget? last_list_row;
|
||||
|
||||
// Label for displaying messages in the main pane.
|
||||
[GtkChild]
|
||||
|
|
@ -148,7 +149,11 @@ public class ConversationViewer : Gtk.Stack {
|
|||
// embedded composer and should not be activated.
|
||||
ConversationMessage? msg = row.get_child() as ConversationMessage;
|
||||
if (email_to_row.size > 1 && msg != null) {
|
||||
toggle_show_message(row);
|
||||
if (msg.is_message_body_visible) {
|
||||
hide_message(row);
|
||||
} else {
|
||||
show_message(row);
|
||||
}
|
||||
}
|
||||
});
|
||||
conversation_listbox.realize.connect(() => {
|
||||
|
|
@ -156,6 +161,24 @@ public class ConversationViewer : Gtk.Stack {
|
|||
.value_changed.connect(check_mark_read);
|
||||
});
|
||||
conversation_listbox.size_allocate.connect(check_mark_read);
|
||||
conversation_listbox.add.connect((widget) => {
|
||||
// Due to Bug 764710, we can only use the CSS
|
||||
// :last-child selector for GTK themes after 3.20.3,
|
||||
// so for now manually maintain a class on the last
|
||||
// box in the convo listbox so we can emulate it.
|
||||
|
||||
Gtk.Widget current_last_row =
|
||||
conversation_listbox.get_children().last().data;;
|
||||
if (last_list_row != current_last_row) {
|
||||
if (last_list_row != null) {
|
||||
last_list_row.get_style_context().remove_class("geary_last");
|
||||
}
|
||||
|
||||
last_list_row = current_last_row;
|
||||
last_list_row.get_style_context().add_class("geary_last");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Setup state machine for search/find states.
|
||||
Geary.State.Mapping[] mappings = {
|
||||
|
|
@ -308,7 +331,7 @@ public class ConversationViewer : Gtk.Stack {
|
|||
embed.set_property("name", "composer_embed"); // Bug 764622
|
||||
|
||||
Gtk.ListBoxRow row = new Gtk.ListBoxRow();
|
||||
row.get_style_context().add_class("composer");
|
||||
row.get_style_context().add_class("geary_composer");
|
||||
row.show();
|
||||
row.add(embed);
|
||||
conversation_listbox.add(row);
|
||||
|
|
@ -377,7 +400,7 @@ public class ConversationViewer : Gtk.Stack {
|
|||
if (current_conversation != null) {
|
||||
current_conversation.appended.disconnect(on_conversation_appended);
|
||||
current_conversation.trimmed.disconnect(on_conversation_trimmed);
|
||||
current_conversation.email_flags_changed.disconnect(update_flags);
|
||||
current_conversation.email_flags_changed.disconnect(on_update_flags);
|
||||
current_conversation = null;
|
||||
}
|
||||
|
||||
|
|
@ -430,7 +453,7 @@ public class ConversationViewer : Gtk.Stack {
|
|||
|
||||
current_conversation.appended.connect(on_conversation_appended);
|
||||
current_conversation.trimmed.connect(on_conversation_trimmed);
|
||||
current_conversation.email_flags_changed.connect(update_flags);
|
||||
current_conversation.email_flags_changed.connect(on_update_flags);
|
||||
|
||||
GearyApplication.instance.controller.enable_message_buttons(true);
|
||||
}
|
||||
|
|
@ -617,7 +640,7 @@ public class ConversationViewer : Gtk.Stack {
|
|||
|
||||
ConversationMessage message = new ConversationMessage(email, current_folder);
|
||||
message.link_selected.connect((link) => { link_selected(link); });
|
||||
message.web_view.button_release_event.connect_after((event) => {
|
||||
message.body_box.button_release_event.connect_after((event) => {
|
||||
// Consume all non-consumed clicks so the row is not
|
||||
// inadvertently activated after clicking on the
|
||||
// message body.
|
||||
|
|
@ -627,11 +650,10 @@ public class ConversationViewer : Gtk.Stack {
|
|||
Gtk.ListBoxRow row = new Gtk.ListBoxRow();
|
||||
row.show();
|
||||
row.add(message);
|
||||
email_to_row.set(email.id, row);
|
||||
|
||||
conversation_listbox.add(row);
|
||||
|
||||
email_to_row.set(email.id, row);
|
||||
|
||||
if (email.is_unread() == Geary.Trillian.TRUE) {
|
||||
show_message(row, false);
|
||||
}
|
||||
|
|
@ -648,52 +670,23 @@ public class ConversationViewer : Gtk.Stack {
|
|||
}
|
||||
|
||||
private void show_message(Gtk.ListBoxRow row, bool include_transitions=true) {
|
||||
row.get_style_context().add_class("show-message");
|
||||
((ConversationMessage) row.get_child()).show_message(include_transitions);
|
||||
row.get_style_context().add_class("geary_expand");
|
||||
((ConversationMessage) row.get_child()).show_message_body(include_transitions);
|
||||
}
|
||||
|
||||
private void hide_message(Gtk.ListBoxRow row) {
|
||||
row.get_style_context().remove_class("show-message");
|
||||
((ConversationMessage) row.get_child()).hide_message();
|
||||
}
|
||||
|
||||
private void toggle_show_message(Gtk.ListBoxRow row) {
|
||||
if (row.get_style_context().has_class("show-message")) {
|
||||
hide_message(row);
|
||||
} else {
|
||||
show_message(row);
|
||||
}
|
||||
row.get_style_context().remove_class("geary_expand");
|
||||
((ConversationMessage) row.get_child()).hide_message_body();
|
||||
}
|
||||
|
||||
private void compress_emails() {
|
||||
conversation_listbox.get_style_context().add_class("compressed");
|
||||
conversation_listbox.get_style_context().add_class("geary_compressed");
|
||||
}
|
||||
|
||||
//private void decompress_emails() {
|
||||
// conversation_listbox.get_style_context().remove_class("compressed");
|
||||
// conversation_listbox.get_style_context().remove_class("geary_compressed");
|
||||
//}
|
||||
|
||||
private void update_flags(Geary.Email email) {
|
||||
// Nothing to do if we aren't displaying this email.
|
||||
if (!email_to_row.has_key(email.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Geary.EmailFlags flags = email.email_flags;
|
||||
|
||||
// Update the flags in our message set.
|
||||
foreach (Geary.Email message in messages) {
|
||||
if (message.id.equal_to(email.id)) {
|
||||
message.set_flags(flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the convo message and update its state.
|
||||
Gtk.ListBoxRow row = email_to_row.get(email.id);
|
||||
((ConversationMessage) row.get_child()).update_flags(email);
|
||||
}
|
||||
|
||||
public void show_find_bar() {
|
||||
fsm.issue(SearchEvent.OPEN_FIND_BAR);
|
||||
conversation_find_bar.focus_entry();
|
||||
|
|
@ -706,6 +699,17 @@ public class ConversationViewer : Gtk.Stack {
|
|||
conversation_find_bar.find(forward);
|
||||
}
|
||||
|
||||
private void on_update_flags(Geary.Email email) {
|
||||
// Nothing to do if we aren't displaying this email.
|
||||
if (!email_to_row.has_key(email.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the convo message and update its state.
|
||||
Gtk.ListBoxRow row = email_to_row.get(email.id);
|
||||
((ConversationMessage) row.get_child()).update_flags(email);
|
||||
}
|
||||
|
||||
// State reset.
|
||||
private uint on_reset(uint state, uint event, void *user, Object? object) {
|
||||
//web_view.set_highlight_text_matches(false);
|
||||
|
|
|
|||
19
ui/geary.css
19
ui/geary.css
|
|
@ -58,27 +58,32 @@ row.geary-folder-popover-list-row > label {
|
|||
}
|
||||
|
||||
#conversation_listbox {
|
||||
padding: 18px 18px calc(18px/2);
|
||||
padding: 18px;
|
||||
}
|
||||
#conversation_listbox > row {
|
||||
margin: 0;
|
||||
border: 1px solid @borders;
|
||||
border-bottom-width: 0;
|
||||
padding: 0;
|
||||
background: shade(@theme_base_color, 0.96);
|
||||
box-shadow: 0 4px 8px 1px rgba(0,0,0,0.4);
|
||||
transition: margin 0.1s, background 0.15s;
|
||||
}
|
||||
#conversation_listbox > row > box {
|
||||
background: shade(@theme_base_color, 0.96);
|
||||
}
|
||||
#conversation_listbox > row:hover,
|
||||
#conversation_listbox > row.show-message,
|
||||
#conversation_listbox > row.show-message:hover {
|
||||
#conversation_listbox > row > box.geary_show_body,
|
||||
#conversation_listbox > row:hover > box.geary_show_body {
|
||||
background: @theme_base_color;
|
||||
}
|
||||
#conversation_listbox > row.show-message,
|
||||
#conversation_listbox > row.composer {
|
||||
margin-bottom: calc(18px/2);
|
||||
#conversation_listbox > row.geary_expand,
|
||||
#conversation_listbox > row.geary_composer {
|
||||
margin-bottom: 18px;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
#conversation_listbox > row.geary_last {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#ConversationMessage {
|
||||
padding: 12px;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue