Redesign chat input + move file upload there
This commit is contained in:
parent
f0dd0e0c3a
commit
c1533f2577
|
@ -111,7 +111,6 @@ SOURCES
|
||||||
src/ui/conversation_summary/message_textview.vala
|
src/ui/conversation_summary/message_textview.vala
|
||||||
src/ui/conversation_summary/slashme_message_display.vala
|
src/ui/conversation_summary/slashme_message_display.vala
|
||||||
src/ui/conversation_summary/subscription_notification.vala
|
src/ui/conversation_summary/subscription_notification.vala
|
||||||
src/ui/conversation_titlebar/file_entry.vala
|
|
||||||
src/ui/conversation_titlebar/menu_entry.vala
|
src/ui/conversation_titlebar/menu_entry.vala
|
||||||
src/ui/conversation_titlebar/occupants_entry.vala
|
src/ui/conversation_titlebar/occupants_entry.vala
|
||||||
src/ui/conversation_titlebar/view.vala
|
src/ui/conversation_titlebar/view.vala
|
||||||
|
|
|
@ -9,6 +9,14 @@ window.dino-main headerbar.dino-left label.title {
|
||||||
color: transparent;
|
color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.dino-main .dino-conversation {
|
||||||
|
background: @theme_base_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.dino-main .dino-conversation undershoot {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
window.dino-main .dino-chatinput frame box {
|
window.dino-main .dino-chatinput frame box {
|
||||||
background: @theme_base_color;
|
background: @theme_base_color;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,11 @@ using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui.ChatInput {
|
namespace Dino.Ui.ChatInput {
|
||||||
|
|
||||||
[GtkTemplate (ui = "/im/dino/Dino/chat_input.ui")]
|
|
||||||
public class View : Box {
|
public class View : Box {
|
||||||
|
|
||||||
[GtkChild] private ScrolledWindow scrolled;
|
private ScrolledWindow scrolled;
|
||||||
[GtkChild] private TextView text_input;
|
private TextView text_input;
|
||||||
[GtkChild] private Box box;
|
private Box outer_box;
|
||||||
|
|
||||||
public string text {
|
public string text {
|
||||||
owned get { return text_input.buffer.text; }
|
owned get { return text_input.buffer.text; }
|
||||||
|
@ -26,20 +25,62 @@ public class View : Box {
|
||||||
private OccupantsTabCompletor occupants_tab_completor;
|
private OccupantsTabCompletor occupants_tab_completor;
|
||||||
private SmileyConverter smiley_converter;
|
private SmileyConverter smiley_converter;
|
||||||
private EditHistory edit_history;
|
private EditHistory edit_history;
|
||||||
private EncryptionButton encryption_widget = new EncryptionButton() { yalign=0, visible=true };
|
private EncryptionButton encryption_widget;
|
||||||
|
private Button file_button = new Button.from_icon_name("mail-attachment-symbolic", IconSize.MENU) { margin_top=3, valign=Align.START, relief=ReliefStyle.NONE };
|
||||||
|
private Separator file_separator = new Separator(Orientation.VERTICAL);
|
||||||
|
|
||||||
public View(StreamInteractor stream_interactor) {
|
public View(StreamInteractor stream_interactor) {
|
||||||
this.stream_interactor = stream_interactor;
|
this.stream_interactor = stream_interactor;
|
||||||
occupants_tab_completor = new OccupantsTabCompletor(stream_interactor, text_input);
|
|
||||||
smiley_converter = new SmileyConverter(stream_interactor, text_input);
|
|
||||||
edit_history = new EditHistory(text_input, GLib.Application.get_default());
|
|
||||||
|
|
||||||
box.add(encryption_widget);
|
outer_box = new Box(Orientation.HORIZONTAL, 0) { visible=true };
|
||||||
|
|
||||||
|
file_button.get_style_context().add_class("dino-chatinput-button");
|
||||||
|
file_button.clicked.connect(() => {
|
||||||
|
PreviewFileChooserNative chooser = new PreviewFileChooserNative("Select file", get_toplevel() as Gtk.Window, FileChooserAction.OPEN, "Select", "Cancel");
|
||||||
|
|
||||||
|
// long max_file_size = stream_interactor.get_module(Manager.IDENTITY).get_max_file_size(conversation.account);
|
||||||
|
// if (max_file_size != -1) {
|
||||||
|
// FileFilter filter = new FileFilter();
|
||||||
|
// filter.add_custom(FileFilterFlags.URI, (filter_info) => {
|
||||||
|
// File file = File.new_for_uri(filter_info.uri);
|
||||||
|
// FileInfo file_info = file.query_info("*", FileQueryInfoFlags.NONE);
|
||||||
|
// return file_info.get_size() <= max_file_size;
|
||||||
|
// });
|
||||||
|
// chooser.set_filter(filter);
|
||||||
|
// }
|
||||||
|
if (chooser.run() == Gtk.ResponseType.ACCEPT) {
|
||||||
|
string uri = chooser.get_filename();
|
||||||
|
stream_interactor.get_module(FileManager.IDENTITY).send_file(uri, conversation);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
outer_box.add(file_button);
|
||||||
|
outer_box.add(file_separator);
|
||||||
|
|
||||||
|
scrolled = new ScrolledWindow(null, null) { max_content_height=300, propagate_natural_height=true, visible=true };
|
||||||
|
text_input = new TextView() { valign=Align.CENTER, wrap_mode=WrapMode.WORD_CHAR, margin=8, can_focus=true, hexpand=true, visible=true };
|
||||||
|
|
||||||
|
scrolled.add(text_input);
|
||||||
|
outer_box.add(scrolled);
|
||||||
|
|
||||||
|
encryption_widget = new EncryptionButton() { margin_top=3, valign=Align.START, visible=true };
|
||||||
encryption_widget.get_style_context().add_class("dino-chatinput-button");
|
encryption_widget.get_style_context().add_class("dino-chatinput-button");
|
||||||
|
outer_box.add(encryption_widget);
|
||||||
|
|
||||||
scrolled.get_vscrollbar().get_preferred_height(out vscrollbar_min_height, null);
|
scrolled.get_vscrollbar().get_preferred_height(out vscrollbar_min_height, null);
|
||||||
scrolled.vadjustment.notify["upper"].connect_after(on_upper_notify);
|
scrolled.vadjustment.notify["upper"].connect_after(on_upper_notify);
|
||||||
text_input.key_press_event.connect(on_text_input_key_press);
|
text_input.key_press_event.connect(on_text_input_key_press);
|
||||||
text_input.buffer.changed.connect(on_text_input_changed);
|
text_input.buffer.changed.connect(on_text_input_changed);
|
||||||
|
|
||||||
|
Frame frame = new Frame(null) { margin=12, margin_top=0, visible=true };
|
||||||
|
Util.force_css(frame, "* { border-radius: 3px; }");
|
||||||
|
frame.add(outer_box);
|
||||||
|
this.add(frame);
|
||||||
|
|
||||||
|
occupants_tab_completor = new OccupantsTabCompletor(stream_interactor, text_input);
|
||||||
|
smiley_converter = new SmileyConverter(stream_interactor, text_input);
|
||||||
|
edit_history = new EditHistory(text_input, GLib.Application.get_default());
|
||||||
|
|
||||||
|
stream_interactor.get_module(FileManager.IDENTITY).upload_available.connect(on_upload_available);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize_for_conversation(Conversation conversation) {
|
public void initialize_for_conversation(Conversation conversation) {
|
||||||
|
@ -50,6 +91,10 @@ public class View : Box {
|
||||||
if (this.conversation != null) entry_cache[this.conversation] = text_input.buffer.text;
|
if (this.conversation != null) entry_cache[this.conversation] = text_input.buffer.text;
|
||||||
this.conversation = conversation;
|
this.conversation = conversation;
|
||||||
|
|
||||||
|
bool upload_available = stream_interactor.get_module(FileManager.IDENTITY).is_upload_available(conversation);
|
||||||
|
file_button.visible = upload_available;
|
||||||
|
file_separator.visible = upload_available;
|
||||||
|
|
||||||
text_input.buffer.changed.disconnect(on_text_input_changed);
|
text_input.buffer.changed.disconnect(on_text_input_changed);
|
||||||
text_input.buffer.text = "";
|
text_input.buffer.text = "";
|
||||||
if (entry_cache.has_key(conversation)) {
|
if (entry_cache.has_key(conversation)) {
|
||||||
|
@ -135,6 +180,13 @@ public class View : Box {
|
||||||
stream_interactor.get_module(ChatInteraction.IDENTITY).on_message_cleared(conversation);
|
stream_interactor.get_module(ChatInteraction.IDENTITY).on_message_cleared(conversation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void on_upload_available(Account account) {
|
||||||
|
if (conversation != null && conversation.account.equals(account)) {
|
||||||
|
file_button.visible = true;
|
||||||
|
file_separator.visible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
|
||||||
|
|
||||||
private Mutex reloading_mutex = Mutex();
|
private Mutex reloading_mutex = Mutex();
|
||||||
private bool animate = false;
|
private bool animate = false;
|
||||||
|
private bool firstLoad = true;
|
||||||
|
|
||||||
public ConversationView(StreamInteractor stream_interactor) {
|
public ConversationView(StreamInteractor stream_interactor) {
|
||||||
this.stream_interactor = stream_interactor;
|
this.stream_interactor = stream_interactor;
|
||||||
|
@ -59,7 +60,22 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
|
||||||
Util.force_base_background(this);
|
Util.force_base_background(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Workaround GTK TextView issues: Delay first load of contents
|
||||||
public void initialize_for_conversation(Conversation? conversation) {
|
public void initialize_for_conversation(Conversation? conversation) {
|
||||||
|
if (firstLoad) {
|
||||||
|
int timeout = firstLoad ? 1000 : 0;
|
||||||
|
Timeout.add(timeout, () => {
|
||||||
|
initialize_for_conversation_(conversation);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
firstLoad = false;
|
||||||
|
} else {
|
||||||
|
initialize_for_conversation_(conversation);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initialize_for_conversation_(Conversation? conversation) {
|
||||||
Dino.Application app = Dino.Application.get_default();
|
Dino.Application app = Dino.Application.get_default();
|
||||||
if (this.conversation != null) {
|
if (this.conversation != null) {
|
||||||
foreach (Plugins.ConversationItemPopulator populator in app.plugin_registry.conversation_item_populators) {
|
foreach (Plugins.ConversationItemPopulator populator in app.plugin_registry.conversation_item_populators) {
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
using Gtk;
|
|
||||||
|
|
||||||
using Dino.Entities;
|
|
||||||
|
|
||||||
namespace Dino.Ui {
|
|
||||||
|
|
||||||
public class FileEntry : Plugins.ConversationTitlebarEntry, Object {
|
|
||||||
public string id { get { return "send_files"; } }
|
|
||||||
|
|
||||||
StreamInteractor stream_interactor;
|
|
||||||
|
|
||||||
public FileEntry(StreamInteractor stream_interactor) {
|
|
||||||
this.stream_interactor = stream_interactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double order { get { return 4; } }
|
|
||||||
public Plugins.ConversationTitlebarWidget? get_widget(Plugins.WidgetType type) {
|
|
||||||
if (type == Plugins.WidgetType.GTK) {
|
|
||||||
return new FileWidget(stream_interactor) { visible=true };
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FileWidget : Button, Plugins.ConversationTitlebarWidget {
|
|
||||||
|
|
||||||
private const int PREVIEW_SIZE = 180;
|
|
||||||
private const int PREVIEW_PADDING = 3;
|
|
||||||
|
|
||||||
private Conversation? conversation;
|
|
||||||
private StreamInteractor stream_interactor;
|
|
||||||
|
|
||||||
public FileWidget(StreamInteractor stream_interactor) {
|
|
||||||
this.stream_interactor = stream_interactor;
|
|
||||||
image = new Image.from_icon_name("mail-attachment-symbolic", IconSize.MENU);
|
|
||||||
clicked.connect(on_clicked);
|
|
||||||
stream_interactor.get_module(FileManager.IDENTITY).upload_available.connect(on_upload_available);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void on_clicked() {
|
|
||||||
PreviewFileChooserNative chooser = new PreviewFileChooserNative("Select file", get_toplevel() as Window, FileChooserAction.OPEN, "Select", "Cancel");
|
|
||||||
|
|
||||||
// long max_file_size = stream_interactor.get_module(Manager.IDENTITY).get_max_file_size(conversation.account);
|
|
||||||
// if (max_file_size != -1) {
|
|
||||||
// FileFilter filter = new FileFilter();
|
|
||||||
// filter.add_custom(FileFilterFlags.URI, (filter_info) => {
|
|
||||||
// File file = File.new_for_uri(filter_info.uri);
|
|
||||||
// FileInfo file_info = file.query_info("*", FileQueryInfoFlags.NONE);
|
|
||||||
// return file_info.get_size() <= max_file_size;
|
|
||||||
// });
|
|
||||||
// chooser.set_filter(filter);
|
|
||||||
// }
|
|
||||||
if (chooser.run() == Gtk.ResponseType.ACCEPT) {
|
|
||||||
string uri = chooser.get_filename();
|
|
||||||
stream_interactor.get_module(FileManager.IDENTITY).send_file(uri, conversation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void on_upload_available(Account account) {
|
|
||||||
if (conversation != null && conversation.account.equals(account)) {
|
|
||||||
visible = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public new void set_conversation(Conversation conversation) {
|
|
||||||
this.conversation = conversation;
|
|
||||||
visible = stream_interactor.get_module(FileManager.IDENTITY).is_upload_available(conversation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -23,7 +23,6 @@ public class ConversationTitlebar : Gtk.HeaderBar {
|
||||||
Application app = GLib.Application.get_default() as Application;
|
Application app = GLib.Application.get_default() as Application;
|
||||||
app.plugin_registry.register_contact_titlebar_entry(new MenuEntry(stream_interactor));
|
app.plugin_registry.register_contact_titlebar_entry(new MenuEntry(stream_interactor));
|
||||||
app.plugin_registry.register_contact_titlebar_entry(new OccupantsEntry(stream_interactor, window));
|
app.plugin_registry.register_contact_titlebar_entry(new OccupantsEntry(stream_interactor, window));
|
||||||
app.plugin_registry.register_contact_titlebar_entry(new FileEntry(stream_interactor));
|
|
||||||
|
|
||||||
foreach(var e in app.plugin_registry.conversation_titlebar_entries) {
|
foreach(var e in app.plugin_registry.conversation_titlebar_entries) {
|
||||||
Plugins.ConversationTitlebarWidget widget = e.get_widget(Plugins.WidgetType.GTK);
|
Plugins.ConversationTitlebarWidget widget = e.get_widget(Plugins.WidgetType.GTK);
|
||||||
|
|
|
@ -75,8 +75,8 @@ public class UnifiedWindow : Window {
|
||||||
filterable_conversation_list = new ConversationSelector.View(stream_interactor) { visible=true };
|
filterable_conversation_list = new ConversationSelector.View(stream_interactor) { visible=true };
|
||||||
|
|
||||||
Grid grid = new Grid() { orientation=Orientation.VERTICAL, visible=true };
|
Grid grid = new Grid() { orientation=Orientation.VERTICAL, visible=true };
|
||||||
|
grid.get_style_context().add_class("dino-conversation");
|
||||||
grid.add(conversation_frame);
|
grid.add(conversation_frame);
|
||||||
grid.add(new Separator(Orientation.HORIZONTAL) { visible=true });
|
|
||||||
grid.add(chat_input);
|
grid.add(chat_input);
|
||||||
|
|
||||||
paned.set_position(300);
|
paned.set_position(300);
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class TlsConnectionProvider : ConnectionProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string get_id() { return "start_tls"; }
|
public override string get_id() { return "srv_records"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue