Move managing toolbar mesage buttons from convo viewer to controller.

* src/client/application/geary-controller.vala (GearyController): Update
  message button state when updating ConversationViewer state.
  (GearyController::on_conversations_selected): Move logic for handling
  different numbers of selected conversations from ConversationViewer
  here, so that message button state can be updated when the selection
  count changes.

* src/client/conversation-viewer/conversation-viewer.vala
  (ConversationViewer): Add ::is_composer_visible property, methods for
  showing empty/muiple conversations selected UI.
This commit is contained in:
Michael James Gratton 2016-08-14 12:18:40 +10:00
parent edf1bf01d3
commit 599da42d18
2 changed files with 100 additions and 68 deletions

View file

@ -1298,6 +1298,7 @@ public class GearyController : Geary.BaseObject {
private void on_folder_selected(Geary.Folder? folder) {
debug("Folder %s selected", folder != null ? folder.to_string() : "(null)");
this.main_window.conversation_viewer.show_loading();
enable_message_buttons(false);
// If the folder is being unset, clear the message list and exit here.
if (folder == null) {
@ -1456,6 +1457,7 @@ public class GearyController : Geary.BaseObject {
} else {
this.main_window.conversation_viewer.show_empty_folder();
}
enable_message_buttons(false);
}
conversation_count_changed(count);
}
@ -1504,11 +1506,40 @@ public class GearyController : Geary.BaseObject {
}
private void on_conversations_selected(Gee.Set<Geary.App.Conversation> selected) {
selected_conversations = selected;
if (this.current_folder != null) {
this.main_window.conversation_viewer.load_conversations.begin(
selected, this.current_folder
);
this.selected_conversations = selected;
ConversationViewer viewer = this.main_window.conversation_viewer;
if (this.current_folder != null && !viewer.is_composer_visible) {
switch(selected.size) {
case 0:
enable_message_buttons(false);
viewer.show_none_selected();
break;
case 1:
// Cancel existing avatar loads before loading new
// convo since that will start loading more avatars
avatar_session.flush_queue();
bool is_search = this.current_folder is Geary.SearchFolder;
viewer.load_conversation.begin(
Geary.Collection.get_first(selected),
this.current_folder,
(obj, ret) => {
try {
viewer.load_conversation.end(ret);
enable_message_buttons(!is_search);
} catch (Error err) {
debug("Unable to load conversation: %s",
err.message);
}
}
);
break;
default:
enable_multiple_message_buttons();
viewer.show_multiple_selected();
break;
}
}
}

View file

@ -33,10 +33,20 @@ public class ConversationViewer : Gtk.Stack {
COUNT;
}
/**
* The current conversation listbox, if any.
*/
public ConversationListBox? current_list {
get; private set; default = null;
}
/**
* Specifies if a full-height composer is currently shown.
*/
public bool is_composer_visible {
get { return (get_visible_child() == this.composer_page); }
}
// Stack pages
[GtkChild]
private Gtk.Spinner loading_page;
@ -183,7 +193,21 @@ public class ConversationViewer : Gtk.Stack {
public void show_loading() {
set_visible_child(this.loading_page);
}
/**
* Shows the UI when no conversations have been selected
*/
public void show_none_selected() {
set_visible_child(this.no_conversations_page);
}
/**
* Shows the UI when multiple conversations have been selected
*/
public void show_multiple_selected() {
set_visible_child(this.multiple_conversations_page);
}
/**
* Shows the empty folder UI.
*/
@ -199,72 +223,49 @@ public class ConversationViewer : Gtk.Stack {
}
/**
* Shows one or more conversations in the viewer.
* Shows a conversation in the viewer.
*/
public async void load_conversations(Gee.Set<Geary.App.Conversation> conversations,
Geary.Folder location) {
if (get_visible_child() == this.composer_page) {
// When first showing a composer, the conversation list
// will be cleared. In that case the composer should
// remain visible.
return;
public async void load_conversation(Geary.App.Conversation conversation,
Geary.Folder location)
throws Error {
// If the load is taking too long, display the spinner
if (this.conversation_timeout_id != 0) {
Source.remove(this.conversation_timeout_id);
}
debug("Conversations selected in %s: %u", location.to_string(), conversations.size);
if (conversations.size == 0) {
set_visible_child(this.no_conversations_page);
GearyApplication.instance.controller.enable_message_buttons(false);
} else if (conversations.size > 1) {
set_visible_child(this.multiple_conversations_page);
GearyApplication.instance.controller.enable_multiple_message_buttons();
} else {
// If the load is taking too long, display the spinner
if (this.conversation_timeout_id != 0) {
Source.remove(this.conversation_timeout_id);
}
this.conversation_timeout_id =
Timeout.add(SELECT_CONVERSATION_TIMEOUT_MSEC, () => {
if (this.conversation_timeout_id != 0) {
debug("Loading timed out\n");
show_loading();
}
this.conversation_timeout_id = 0;
return false;
});
Geary.Account account = location.account;
ConversationListBox new_list = new ConversationListBox(
Geary.Collection.get_first(conversations),
account.get_contact_store(),
new Geary.App.EmailStore(account),
location.special_folder_type == Geary.SpecialFolderType.DRAFTS,
conversation_page.get_vadjustment()
);
// Need to fire this signal early so the the controller
// can hook in to its signals to catch any emails added
// during loading.
this.conversation_added(new_list);
// Cancel existing avatar loads this before loading new
// convo since that will start loading more avatars
GearyApplication.instance.controller.avatar_session.flush_queue();
bool loaded = false;
try {
yield new_list.load_conversation();
loaded = true;
remove_current_list();
add_new_list(new_list);
this.conversation_timeout_id =
Timeout.add(SELECT_CONVERSATION_TIMEOUT_MSEC, () => {
if (this.conversation_timeout_id != 0) {
debug("Loading timed out\n");
// XXX should disable message buttons here, so
// need to move this timer to the controller.
show_loading();
}
this.conversation_timeout_id = 0;
} catch (Error err) {
debug("Unable to load conversation: %s", err.message);
}
set_visible_child(this.conversation_page);
GearyApplication.instance.controller.enable_message_buttons(true);
return false;
});
if (loaded && location is Geary.SearchFolder) {
yield new_list.load_search_terms((Geary.SearchFolder) location);
}
Geary.Account account = location.account;
ConversationListBox new_list = new ConversationListBox(
conversation,
account.get_contact_store(),
new Geary.App.EmailStore(account),
location.special_folder_type == Geary.SpecialFolderType.DRAFTS,
conversation_page.get_vadjustment()
);
// Need to fire this signal early so the the controller
// can hook in to its signals to catch any emails added
// during loading.
this.conversation_added(new_list);
yield new_list.load_conversation();
remove_current_list();
add_new_list(new_list);
set_visible_child(this.conversation_page);
this.conversation_timeout_id = 0;
if (location is Geary.SearchFolder) {
yield new_list.load_search_terms((Geary.SearchFolder) location);
}
}