Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VENOM-348: Show conference invites #349

Merged
merged 1 commit into from
Apr 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/core/ObservableList.vala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace Venom {
public class ObservableList : GLib.Object {
public signal void added(GLib.Object item, uint index);
public signal void removed(GLib.Object item, uint index);
public signal void changed();

private Gee.List<GLib.Object> list = new Gee.ArrayList<GLib.Object>();

Expand All @@ -44,12 +45,14 @@ namespace Venom {
var idx = list.size;
list.add(item);
added(item, idx);
changed();
}

public void remove(GLib.Object item) {
var idx = list.index_of(item);
removed(item, idx);
list.remove_at(idx);
changed();
}

public uint length() {
Expand Down
1 change: 1 addition & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ venom_source = files(
'view/AddContactWidget.vala',
'view/ApplicationWindow.vala',
'view/ConferenceInfoWidget.vala',
'view/ConferenceInviteEntry.vala',
'view/ConferenceWindow.vala',
'view/ContactListEntry.vala',
'view/ContactListRequestEntry.vala',
Expand Down
7 changes: 7 additions & 0 deletions src/testing/mocks/MockToxSession.vala
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@ namespace Mock {
.create();
mock().actual_call(this, "conference_invite", args).get_throws();
}
public void conference_join(uint32 friend_number, ConferenceType type, uint8[] cookie) throws ToxError {
var args = Arguments.builder()
.uint(friend_number)
.int(type)
.create();
mock().actual_call(this, "conference_join", args).get_throws();
}
public void conference_send_message(uint32 conference_number, string message) throws ToxError {
var args = Arguments.builder()
.uint(conference_number)
Expand Down
35 changes: 16 additions & 19 deletions src/tox/FriendRequest.vala
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,27 @@
*/

namespace Venom {
public class FriendRequest : IContact, GLib.Object {
private string id;
private string message;
public class FriendRequest : GLib.Object {
public string id { get; set; }
public string message { get; set; }

public FriendRequest(string id, string message) {
this.id = id;
this.message = message;
}
public string get_id() {
return id;
}
public string get_name_string() {
return _("Friend request");
}

public class ConferenceInvite : GLib.Object {
public IContact sender { get; set; }
public ConferenceType conference_type { get; set; }
public uint8[] get_cookie() {
return cookie;
}
public string get_status_string() {
return message;
private uint8[] cookie;
public ConferenceInvite(IContact sender, ConferenceType conference_type, uint8[] cookie) {
this.sender = sender;
this.conference_type = conference_type;
this.cookie = cookie;
}
public UserStatus get_status() { return UserStatus.NONE; }
public bool is_connected() { return false; }
public Gdk.Pixbuf get_image() { return null; }
public bool get_requires_attention() { return true; }
public void clear_attention() {}
public bool is_typing() { return false; }
public bool show_notifications() { return true; }
public bool is_conference() { return false; }
}

}
57 changes: 52 additions & 5 deletions src/tox/ToxAdapterConferenceListener.vala
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,22 @@
*/

namespace Venom {
public class ToxAdapterConferenceListenerImpl : ToxAdapterConferenceListener, ConferenceWidgetListener, ConferenceInfoWidgetListener, CreateGroupchatWidgetListener, GLib.Object {
public class ToxAdapterConferenceListenerImpl : ToxAdapterConferenceListener, ConferenceInviteEntryListener, ConferenceWidgetListener, ConferenceInfoWidgetListener, CreateGroupchatWidgetListener, GLib.Object {
private unowned ToxSession session;
private ILogger logger;
private ObservableList contacts;
private ObservableList conference_invites;
private NotificationListener notification_listener;
private GLib.HashTable<IContact, ObservableList> conversations;

private GLib.HashTable<uint32, IContact> conferences;
private unowned GLib.HashTable<uint32, IContact> friends;

public ToxAdapterConferenceListenerImpl(ILogger logger, ObservableList contacts, GLib.HashTable<IContact, ObservableList> conversations, NotificationListener notification_listener) {
public ToxAdapterConferenceListenerImpl(ILogger logger, ObservableList contacts, ObservableList conference_invites, GLib.HashTable<IContact, ObservableList> conversations, NotificationListener notification_listener) {
logger.d("ToxAdapterConferenceListenerImpl created.");
this.logger = logger;
this.contacts = contacts;
this.conference_invites = conference_invites;
this.conversations = conversations;
this.notification_listener = notification_listener;

Expand All @@ -46,6 +49,7 @@ namespace Venom {
public virtual void attach_to_session(ToxSession session) {
this.session = session;
session.set_conference_listener(this);
friends = session.get_friends();
}

public virtual void on_remove_conference(IContact c) throws Error {
Expand All @@ -63,12 +67,12 @@ namespace Venom {
session.conference_send_message(conference.conference_number, message);
}

public virtual void on_create_groupchat(string title, GroupchatType type) throws Error {
public virtual void on_create_groupchat(string title, ConferenceType type) throws Error {
session.conference_new(title);
}

public virtual void on_conference_invite(IContact c, string id) throws Error {
logger.d("on_conference_invite");
public virtual void on_send_conference_invite(IContact c, string id) throws Error {
logger.d("on_send_conference_invite");
if (c is Contact) {
var contact = c as Contact;
if (id == "") {
Expand All @@ -84,6 +88,49 @@ namespace Venom {
}
}

public virtual void on_accept_conference_invite(ConferenceInvite invite) throws Error {
var c = invite.sender as Contact;
session.conference_join(c.tox_friend_number, invite.conference_type, invite.get_cookie());
conference_invites.remove(invite);
}

public virtual void on_reject_conference_invite(ConferenceInvite invite) throws Error {
conference_invites.remove(invite);
}

private bool invite_equals(ConferenceInvite invite, uint32 friend_number, ConferenceType type, uint8[] cookie) {
var cmp_sender = invite.sender as Contact;
var cmp_cookie = invite.get_cookie();
return (cmp_sender.tox_friend_number == friend_number
&& invite.conference_type == type
&& cmp_cookie.length == cookie.length
&& Memory.cmp(cookie, cmp_cookie, cookie.length) == 0);
}

public virtual void on_conference_invite_received(uint32 friend_number, ConferenceType type, uint8[] cookie) {
logger.d("on_conference_invite_received");

if (friend_number == uint32.MAX) {
session.conference_join(friend_number, type, cookie);
} else {
for (var i = 0; i < conference_invites.length(); i++) {
var invite = conference_invites.nth_data(i) as ConferenceInvite;
if (invite_equals(invite, friend_number, type, cookie)) {
logger.d("duplicate invite received, discarding");
return;
}
}

var contact = friends.@get(friend_number) as Contact;
if (contact.auto_conference) {
session.conference_join(friend_number, type, cookie);
} else {
var invite = new ConferenceInvite(contact, type, cookie);
conference_invites.append(invite);
}
}
}

public virtual void on_conference_new(uint32 conference_number, string title) {
logger.d("on_conference_new");
var contact = new Conference(conference_number, title);
Expand Down
31 changes: 17 additions & 14 deletions src/tox/ToxAdapterFriendListener.vala
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,21 @@ namespace Venom {
private GLib.HashTable<uint32, Message> messages_waiting_for_rr;

private unowned GLib.HashTable<uint32, IContact> friends;
private GLib.HashTable<string, IContact> friend_requests;
private Gee.Map<string, FriendRequest> tox_friend_requests;
private ObservableList friend_requests;

public bool show_typing { get; set; }

public ToxAdapterFriendListenerImpl(ILogger logger, ObservableList contacts, GLib.HashTable<IContact, ObservableList> conversations, NotificationListener notification_listener) {
public ToxAdapterFriendListenerImpl(ILogger logger, ObservableList contacts, ObservableList friend_requests, GLib.HashTable<IContact, ObservableList> conversations, NotificationListener notification_listener) {
logger.d("ToxAdapterFriendListenerImpl created.");
this.logger = logger;
this.contacts = contacts;
this.friend_requests = friend_requests;
this.conversations = conversations;
this.notification_listener = notification_listener;

messages_waiting_for_rr = new GLib.HashTable<uint32, Message>(null, null);

friend_requests = new GLib.HashTable<string, IContact>(str_hash, str_equal);
tox_friend_requests = new Gee.HashMap<string, FriendRequest>();
}

~ToxAdapterFriendListenerImpl() {
Expand Down Expand Up @@ -75,17 +76,19 @@ namespace Venom {
}

public virtual void on_accept_friend_request(string id) throws Error {
var friend_request = friend_requests.@get(id);
var friend_request = tox_friend_requests.@get(id);
var public_key = Tools.hexstring_to_bin(id);
session.friend_add_norequest(public_key);
friend_requests.remove(id);
contacts.remove(friend_request);

friend_requests.remove(friend_request);
tox_friend_requests.remove(id);
}

public virtual void on_reject_friend_request(string id) throws Error {
var friend_request = friend_requests.@get(id);
friend_requests.remove(id);
contacts.remove(friend_request);
var friend_request = tox_friend_requests.@get(id);

friend_requests.remove(friend_request);
tox_friend_requests.remove(id);
}

public virtual void on_send_message(IContact c, string message) throws Error {
Expand Down Expand Up @@ -148,10 +151,10 @@ namespace Venom {

public virtual void on_friend_request(uint8[] public_key, string message) {
logger.d("on_friend_request");
var str_id = Tools.bin_to_hexstring(public_key);
var contact = new FriendRequest(str_id, message);
contacts.append(contact);
friend_requests.@set(str_id, contact);
var id = Tools.bin_to_hexstring(public_key);
var request = new FriendRequest(id, message);
friend_requests.append(request);
tox_friend_requests.@set(id, request);
}

public virtual void on_friend_status_changed(uint32 friend_number, UserStatus status) {
Expand Down
54 changes: 35 additions & 19 deletions src/tox/ToxSession.vala
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ namespace Venom {
GENERIC
}

public enum ConferenceType {
TEXT,
AV
}

public class ToxConferencePeer : GLib.Object {
public uint32 peer_number;
public string? peer_name;
Expand Down Expand Up @@ -73,6 +78,7 @@ namespace Venom {
public abstract uint32 conference_new(string title) throws ToxError;
public abstract void conference_delete(uint32 conference_number) throws ToxError;
public abstract void conference_invite(uint32 friend_number, uint32 conference_number) throws ToxError;
public abstract void conference_join(uint32 friend_number, ConferenceType type, uint8[] cookie) throws ToxError;

public abstract void conference_send_message(uint32 conference_number, string message) throws ToxError;
public abstract void conference_set_title(uint32 conference_number, string title) throws ToxError;
Expand Down Expand Up @@ -108,6 +114,7 @@ namespace Venom {
public interface ToxAdapterConferenceListener : GLib.Object {
public abstract void on_conference_new(uint32 conference_number, string title);
public abstract void on_conference_deleted(uint32 conference_number);
public abstract void on_conference_invite_received(uint32 friend_number, Venom.ConferenceType type, uint8[] cookie);

public abstract void on_conference_title_changed(uint32 conference_number, uint32 peer_number, string title);
public abstract void on_conference_peer_list_changed(uint32 conference_number, ToxConferencePeer[] peers);
Expand Down Expand Up @@ -419,27 +426,12 @@ namespace Venom {
Idle.add(() => { session.conference_listener.on_conference_title_changed(conference_number, peer_number, title_str); return false; });
}

private static void on_conference_invite_cb(Tox self, uint32 friend_number, ConferenceType type, uint8[] cookie, void *user_data) {
private static void on_conference_invite_cb(Tox self, uint32 friend_number, ToxCore.ConferenceType type, uint8[] cookie, void *user_data) {
var session = (ToxSessionImpl) user_data;
session.logger.d("on_conference_invite_cb type:" + type.to_string());
if (type == ConferenceType.TEXT) {
var err = ErrConferenceJoin.OK;
var conference_number = self.conference_join(friend_number, cookie, out err);
if (err != ErrConferenceJoin.OK) {
session.logger.e("Conference join failed: " + err.to_string());
return;
}
Idle.add(() => { session.conference_listener.on_conference_new(conference_number, ""); return false; });
} else if (type == ConferenceType.AV) {
var conference_number = ToxAV.ToxAV.join_av_groupchat(self, friend_number, cookie, session.on_av_conference_audio_frame);
if (conference_number < 0) {
session.logger.e(@"Conference AV join failed: $conference_number");
return;
}
Idle.add(() => { session.conference_listener.on_conference_new(conference_number, ""); return false; });
} else {
session.logger.e("Conference join failed: Invalid Conference Type");
}
var gc_type = (type == ToxCore.ConferenceType.AV) ? ConferenceType.AV : ConferenceType.TEXT;
var cookie_copy = copy_data(cookie, cookie.length);
Idle.add(() => { session.conference_listener.on_conference_invite_received(friend_number, gc_type, cookie_copy); return false; });
}

private void on_av_conference_audio_frame() {
Expand Down Expand Up @@ -774,6 +766,30 @@ namespace Venom {
return conference_number;
}

public virtual void conference_join(uint32 friend_number, ConferenceType type, uint8[] cookie) throws ToxError {
uint32 conference_number;
switch (type) {
case ConferenceType.AV:
conference_number = ToxAV.ToxAV.join_av_groupchat(handle, friend_number, cookie, on_av_conference_audio_frame);
if (conference_number < 0) {
var message = @"Conference AV join failed: $conference_number";
logger.e(message);
throw new ToxError.GENERIC(message);
}
break;
default:
var err = ErrConferenceJoin.OK;
conference_number = handle.conference_join(friend_number, cookie, out err);
if (err != ErrConferenceJoin.OK) {
logger.e("Conference join failed: " + err.to_string());
throw new ToxError.GENERIC(err.to_string());
}
break;
}

conference_listener.on_conference_new(conference_number, "");
}

public virtual void conference_delete(uint32 conference_number) throws ToxError {
var e = ErrConferenceDelete.OK;
handle.conference_delete(conference_number, out e);
Expand Down
Loading