Skip to content

Commit

Permalink
VENOM-302: Refactor logic from ui classes
Browse files Browse the repository at this point in the history
* Refactor into viewmodel
* Visualise errors in addcontactdialog
  • Loading branch information
naxuroqa committed Apr 8, 2018
1 parent a95ffef commit d38f32b
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 96 deletions.
11 changes: 7 additions & 4 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,9 @@ venom_source = files(
'tox/ToxAdapterListener.vala',
'tox/ToxSessionThread.vala',
'ui/AboutDialog.vala',
'ui/AddContactWidget.vala',
'ui/ApplicationWindow.vala',
'ui/ConferenceInfoWidget.vala',
'ui/ConferenceWindow.vala',
'ui/ContactListEntry.vala',
'ui/ContactListRequestEntry.vala',
'ui/ContactListWidget.vala',
'ui/ConversationWindow.vala',
Expand All @@ -73,13 +71,18 @@ venom_source = files(
'ui/FileTransferWidget.vala',
'ui/FriendInfoWidget.vala',
'ui/FriendRequestWidget.vala',
'ui/MessageWidget.vala',
'ui/NodeWidget.vala',
'ui/PeerEntry.vala',
'ui/SettingsWidget.vala',
'ui/UserInfoWidget.vala',
'ui/UITools.vala',
'ui/WelcomeWidget.vala'
'ui/WelcomeWidget.vala',
'view/AddContactWidget.vala',
'view/ContactListEntry.vala',
'view/MessageWidget.vala',
'viewmodel/AddContactViewModel.vala',
'viewmodel/ContactListEntryViewModel.vala',
'viewmodel/MessageViewModel.vala'
)

venom_ui_resources = gnome.compile_resources( 'venom_ui_resources', 'ui/venom.gresource.xml',
Expand Down
26 changes: 24 additions & 2 deletions src/ui/add_contact_widget.ui
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.2 -->
<!-- Generated with glade 3.20.4 -->
<interface domain="venom">
<requires lib="gtk+" version="3.20"/>
<object class="GtkTextBuffer" id="textbuffer1">
Expand Down Expand Up @@ -98,6 +98,28 @@
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRevealer" id="contact_id_error_content">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="contact_id_error">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">Error id</property>
<property name="xalign">0</property>
<attributes>
<attribute name="style" value="italic"/>
</attributes>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
Expand All @@ -112,7 +134,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
<property name="position">3</property>
</packing>
</child>
</object>
Expand Down
44 changes: 13 additions & 31 deletions src/ui/AddContactWidget.vala → src/view/AddContactWidget.vala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* AddContactWidget.vala
*
* Copyright (C) 2013-2017 Venom authors and contributors
* Copyright (C) 2013-2018 Venom authors and contributors
*
* This file is part of Venom.
*
Expand All @@ -28,49 +28,31 @@ namespace Venom {
private Gtk.TextView contact_message;
[GtkChild]
private Gtk.Button send;
[GtkChild]
private Gtk.Label contact_id_error;
[GtkChild]
private Gtk.Revealer contact_id_error_content;

private ILogger logger;
private AddContactWidgetListener listener;
private AddContactViewModel view_model;

public AddContactWidget(ILogger logger, AddContactWidgetListener listener) {
logger.d("AddContactWidget created.");
this.logger = logger;
this.listener = listener;
view_model = new AddContactViewModel(logger, listener);

contact_id.icon_release.connect(on_paste_clipboard);
send.clicked.connect(on_send);
}
contact_id.bind_property("text", view_model, "contact-id", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
contact_message.buffer.bind_property("text", view_model, "contact-message", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
contact_id_error.bind_property("label", view_model, "contact-id-error-message", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
contact_id_error_content.bind_property("reveal-child", view_model, "contact-id-error-visible", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);

private void on_send() {
logger.d("on_send");
if (listener == null) {
return;
}
try {
listener.on_send_friend_request(contact_id.text, contact_message.buffer.text);
} catch (Error e) {
logger.e("Could not add contact: " + e.message);
return;
}
logger.d("on_send_successful");
contact_id.icon_release.connect(view_model.on_paste_clipboard);
send.clicked.connect(view_model.on_send);
}

~AddContactWidget() {
logger.d("AddContactWidget destroyed.");
}

private void on_paste_clipboard() {
var clipboard = Gtk.Clipboard.@get(Gdk.SELECTION_CLIPBOARD);
var text = clipboard.wait_for_text();
if (text == null) {
logger.d("clipboard.wait_for_text returned null, probably empty.");
return;
}
contact_id.set_text(text);
}
}

public interface AddContactWidgetListener : GLib.Object {
public abstract void on_send_friend_request(string id, string message) throws Error;
}
}
32 changes: 7 additions & 25 deletions src/ui/ContactListEntry.vala → src/view/ContactListEntry.vala
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace Venom {
[GtkTemplate(ui = "/im/tox/venom/ui/contact_list_entry.ui")]
public class ContactListEntry : Gtk.ListBoxRow, IContactListEntry {
private ILogger logger;
private IContact contact;
private ContactListEntryViewModel view_model;

[GtkChild]
private Gtk.Label contact_name;
Expand All @@ -41,34 +41,16 @@ namespace Venom {
public ContactListEntry(ILogger logger, IContact contact) {
logger.d("ContactListEntry created.");
this.logger = logger;
this.contact = contact;
init_widgets();
this.view_model = new ContactListEntryViewModel(logger, contact);

contact.changed.connect(init_widgets);
view_model.bind_property("contact-name", contact_name, "label", GLib.BindingFlags.SYNC_CREATE);
view_model.bind_property("contact-status", contact_status, "label", GLib.BindingFlags.SYNC_CREATE);
view_model.bind_property("contact-image", contact_image, "pixbuf", GLib.BindingFlags.SYNC_CREATE);
view_model.bind_property("contact-status-image", status_image, "icon-name", GLib.BindingFlags.SYNC_CREATE);
}

public IContact get_contact() {
return contact;
}

private void init_widgets() {
contact_name.label = contact.get_name_string();
contact_status.label = contact.get_status_string();
contact_image.pixbuf = contact.get_image();
status_image.icon_name = icon_name_from_status(contact.get_status());
}

private string icon_name_from_status(UserStatus status) {
switch (status) {
case UserStatus.ONLINE:
return R.icons.online;
case UserStatus.AWAY:
return R.icons.idle;
case UserStatus.BUSY:
return R.icons.busy;
default:
return R.icons.offline;
}
return view_model.get_contact();
}

~ContactListEntry() {
Expand Down
45 changes: 11 additions & 34 deletions src/ui/MessageWidget.vala → src/view/MessageWidget.vala
Original file line number Diff line number Diff line change
Expand Up @@ -37,50 +37,27 @@ namespace Venom {
[GtkChild]
private Gtk.Box additional_info;

private IMessage message_content;
private ILogger logger;
private MessageViewModel view_model;

public MessageWidget(ILogger logger, IMessage message_content) {
this.logger = logger;
this.message_content = message_content;
this.view_model = new MessageViewModel(logger, message_content);

if (message_content.message_direction == MessageDirection.OUTGOING) {
//TODO move this
sender.label = "me";
sender.sensitive = false;
message_content.message_changed.connect(on_message_changed);
} else {
sender.label = message_content.get_sender_plain();
}
on_message_changed();
view_model.bind_property("additional-info-visible", additional_info, "visible", GLib.BindingFlags.SYNC_CREATE);
view_model.bind_property("timestamp", timestamp, "label", GLib.BindingFlags.SYNC_CREATE);
view_model.bind_property("message", message, "label", GLib.BindingFlags.SYNC_CREATE);
view_model.bind_property("sender-image", sender_image, "pixbuf", GLib.BindingFlags.SYNC_CREATE);
view_model.bind_property("sender", sender, "label", GLib.BindingFlags.SYNC_CREATE);
view_model.bind_property("sender-sensitive", sender, "sensitive", GLib.BindingFlags.SYNC_CREATE);
view_model.bind_property("sent-visible", sent, "visible", GLib.BindingFlags.SYNC_CREATE);
view_model.bind_property("received-visible", received, "visible", GLib.BindingFlags.SYNC_CREATE);

sender_image.set_from_pixbuf(message_content.get_sender_image());
timestamp.label = message_content.get_time_plain();
message.label = message_content.get_message_plain();
sender.activate_link.connect(on_activate_sender_link);

state_flags_changed.connect(on_state_flags_changed);
state_flags_changed.connect(() => { view_model.on_state_flags_changed(get_state_flags()); });

logger.d("MessageWidget created.");
}

private void on_state_flags_changed() {
var flag = get_state_flags();
additional_info.visible = Gtk.StateFlags.PRELIGHT in flag || Gtk.StateFlags.SELECTED in flag;
}

private void on_message_changed() {
if (message_content.message_direction == MessageDirection.OUTGOING) {
received.visible = message_content.received;
sent.visible = !message_content.received;
}
}

private bool on_activate_sender_link() {
logger.d("on_activate_sender_link");
return true;
}

~MessageWidget() {
logger.d("MessageWidget destroyed.");
}
Expand Down
64 changes: 64 additions & 0 deletions src/viewmodel/AddContactViewModel.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* AddContactViewModel.vala
*
* Copyright (C) 2018 Venom authors and contributors
*
* This file is part of Venom.
*
* Venom is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Venom is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Venom. If not, see <http://www.gnu.org/licenses/>.
*/

namespace Venom {
public class AddContactViewModel : GLib.Object {
public string contact_id { get; set; }
public string contact_message { get; set; }
public bool contact_id_error_visible { get; set; }
public string contact_id_error_message { get; set; }

private ILogger logger;
private AddContactWidgetListener listener;

public AddContactViewModel(ILogger logger, AddContactWidgetListener listener) {
logger.d("AddContactViewModel created.");
this.logger = logger;
this.listener = listener;

this.notify["contact-id"].connect(() => { contact_id_error_visible = false; });
}

public void on_send() {
try {
listener.on_send_friend_request(contact_id, contact_message);
} catch (Error e) {
contact_id_error_message = "Could not add contact: " + e.message;
contact_id_error_visible = true;
logger.e(contact_id_error_message);
return;
}
}

public void on_paste_clipboard() {
var clipboard = Gtk.Clipboard.@get(Gdk.SELECTION_CLIPBOARD);
contact_id = clipboard.wait_for_text() ?? "";
}

~AddContactViewModel() {
logger.d("AddContactViewModel destroyed.");
}
}

public interface AddContactWidgetListener : GLib.Object {
public abstract void on_send_friend_request(string id, string message) throws Error;
}
}
69 changes: 69 additions & 0 deletions src/viewmodel/ContactListEntryViewModel.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* ContactListEntryViewModel.vala
*
* Copyright (C) 2018 Venom authors and contributors
*
* This file is part of Venom.
*
* Venom is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Venom is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Venom. If not, see <http://www.gnu.org/licenses/>.
*/

namespace Venom {
public class ContactListEntryViewModel : GLib.Object {
private ILogger logger;
private IContact contact;

public string contact_name { get; set; }
public string contact_status { get; set; }
public Gdk.Pixbuf contact_image { get; set; }
public string contact_status_image { get; set; }

public ContactListEntryViewModel(ILogger logger, IContact contact) {
logger.d("ContactListEntryViewModel created.");
this.logger = logger;
this.contact = contact;

contact.changed.connect(update_contact);
update_contact();
}

public IContact get_contact() {
return contact;
}

private void update_contact() {
contact_name = contact.get_name_string();
contact_status = contact.get_status_string();
contact_image = contact.get_image();
contact_status_image = icon_name_from_status(contact.get_status());
}

private string icon_name_from_status(UserStatus status) {
switch (status) {
case UserStatus.ONLINE:
return R.icons.online;
case UserStatus.AWAY:
return R.icons.idle;
case UserStatus.BUSY:
return R.icons.busy;
default:
return R.icons.offline;
}
}

~ContactListEntryViewModel() {
logger.d("ContactListEntryViewModel destroyed.");
}
}
}

0 comments on commit d38f32b

Please sign in to comment.