Muc Invite + Kick
This commit is contained in:
parent
205bd444a5
commit
e63d59eb34
|
@ -124,26 +124,36 @@ public class ChatInteraction : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_message_received(Entities.Message message, Conversation conversation) {
|
private void on_message_received(Entities.Message message, Conversation conversation) {
|
||||||
|
send_delivery_receipt(conversation, message);
|
||||||
if (is_active_focus(conversation)) {
|
if (is_active_focus(conversation)) {
|
||||||
check_send_read();
|
check_send_read();
|
||||||
conversation.read_up_to = message;
|
conversation.read_up_to = message;
|
||||||
send_chat_marker(conversation, message, Xep.ChatMarkers.MARKER_DISPLAYED);
|
send_chat_marker(conversation, message, Xep.ChatMarkers.MARKER_DISPLAYED);
|
||||||
} else {
|
} else {
|
||||||
|
send_chat_marker(conversation, message, Xep.ChatMarkers.MARKER_RECEIVED);
|
||||||
conversation_unread(conversation);
|
conversation_unread(conversation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void send_chat_marker(Conversation conversation, Entities.Message message, string marker) {
|
private void send_chat_marker(Conversation conversation, Entities.Message message, string marker) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(conversation.account);
|
Core.XmppStream stream = stream_interactor.get_stream(conversation.account);
|
||||||
if (stream != null && Settings.instance().send_marker &&
|
if (stream != null &&
|
||||||
|
(marker == Xep.ChatMarkers.MARKER_RECEIVED || conversation.get_send_marker_setting() == Conversation.Setting.ON) &&
|
||||||
Xep.ChatMarkers.Module.requests_marking(message.stanza)) {
|
Xep.ChatMarkers.Module.requests_marking(message.stanza)) {
|
||||||
stream.get_module(Xep.ChatMarkers.Module.IDENTITY).send_marker(stream, message.stanza.from, message.stanza_id, message.get_type_string(), marker);
|
stream.get_module(Xep.ChatMarkers.Module.IDENTITY).send_marker(stream, message.stanza.from, message.stanza_id, message.get_type_string(), marker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void send_delivery_receipt(Conversation conversation, Entities.Message message) {
|
||||||
|
Core.XmppStream stream = stream_interactor.get_stream(conversation.account);
|
||||||
|
if (stream != null && Xep.MessageDeliveryReceipts.Module.requests_receipt(message.stanza)) {
|
||||||
|
stream.get_module(Xep.MessageDeliveryReceipts.Module.IDENTITY).send_received(stream, message.from.to_string(), message.stanza_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void send_chat_state_notification(Conversation conversation, string state) {
|
private void send_chat_state_notification(Conversation conversation, string state) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(conversation.account);
|
Core.XmppStream stream = stream_interactor.get_stream(conversation.account);
|
||||||
if (stream != null && Settings.instance().send_typing &&
|
if (stream != null && conversation.get_send_typing_setting() == Conversation.Setting.ON &&
|
||||||
conversation.type_ != Conversation.Type.GROUPCHAT) {
|
conversation.type_ != Conversation.Type.GROUPCHAT) {
|
||||||
stream.get_module(Xep.ChatStateNotifications.Module.IDENTITY).send_state(stream, conversation.counterpart.to_string(), state);
|
stream.get_module(Xep.ChatStateNotifications.Module.IDENTITY).send_state(stream, conversation.counterpart.to_string(), state);
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
||||||
new_message.stanza_id = message.id;
|
new_message.stanza_id = message.id;
|
||||||
Jid from_jid = new Jid(message.from);
|
Jid from_jid = new Jid(message.from);
|
||||||
if (!account.bare_jid.equals_bare(from_jid) ||
|
if (!account.bare_jid.equals_bare(from_jid) ||
|
||||||
stream_interactor.get_module(MucManager.IDENTITY).get_nick(from_jid.bare_jid, account) == from_jid.resourcepart) {
|
from_jid.equals(stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(from_jid.bare_jid, account))) {
|
||||||
new_message.direction = Entities.Message.DIRECTION_RECEIVED;
|
new_message.direction = Entities.Message.DIRECTION_RECEIVED;
|
||||||
} else {
|
} else {
|
||||||
new_message.direction = Entities.Message.DIRECTION_SENT;
|
new_message.direction = Entities.Message.DIRECTION_SENT;
|
||||||
|
|
|
@ -28,7 +28,7 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void join(Account account, Jid jid, string? nick, string? password) {
|
public void join(Account account, Jid jid, string? nick, string? password) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream == null) return;
|
if (stream == null) return;
|
||||||
string nick_ = nick ?? account.bare_jid.localpart ?? account.bare_jid.domainpart;
|
string nick_ = nick ?? account.bare_jid.localpart ?? account.bare_jid.domainpart;
|
||||||
set_autojoin(stream, jid, nick_, password);
|
set_autojoin(stream, jid, nick_, password);
|
||||||
|
@ -36,7 +36,7 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void part(Account account, Jid jid) {
|
public void part(Account account, Jid jid) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream == null) return;
|
if (stream == null) return;
|
||||||
unset_autojoin(stream, jid);
|
unset_autojoin(stream, jid);
|
||||||
stream.get_module(Xep.Muc.Module.IDENTITY).exit(stream, jid.bare_jid.to_string());
|
stream.get_module(Xep.Muc.Module.IDENTITY).exit(stream, jid.bare_jid.to_string());
|
||||||
|
@ -47,7 +47,7 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
|
|
||||||
[CCode (has_target = false)] public delegate void OnResult(Jid jid, Xep.DataForms.DataForm data_form, Object? store);
|
[CCode (has_target = false)] public delegate void OnResult(Jid jid, Xep.DataForms.DataForm data_form, Object? store);
|
||||||
public void get_config_form(Account account, Jid jid, OnResult on_result, Object? store) {
|
public void get_config_form(Account account, Jid jid, OnResult on_result, Object? store) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream == null) return;
|
if (stream == null) return;
|
||||||
stream.get_module(Xep.Muc.Module.IDENTITY).get_config_form(stream, jid.to_string(), (stream, jid, data_form, store) => {
|
stream.get_module(Xep.Muc.Module.IDENTITY).get_config_form(stream, jid.to_string(), (stream, jid, data_form, store) => {
|
||||||
Tuple<OnResult, Object?> tuple = store as Tuple<OnResult, Object?>;
|
Tuple<OnResult, Object?> tuple = store as Tuple<OnResult, Object?>;
|
||||||
|
@ -56,20 +56,31 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void change_subject(Account account, Jid jid, string subject) {
|
public void change_subject(Account account, Jid jid, string subject) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).change_subject(stream, jid.bare_jid.to_string(), subject);
|
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).change_subject(stream, jid.bare_jid.to_string(), subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void change_nick(Account account, Jid jid, string new_nick) {
|
public void change_nick(Account account, Jid jid, string new_nick) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).change_nick(stream, jid.bare_jid.to_string(), new_nick);
|
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).change_nick(stream, jid.bare_jid.to_string(), new_nick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void invite(Account account, Jid muc, Jid invitee) {
|
||||||
|
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
|
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).invite(stream, muc.bare_jid.to_string(), invitee.bare_jid.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
public void kick(Account account, Jid jid, string nick) {
|
public void kick(Account account, Jid jid, string nick) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).kick(stream, jid.bare_jid.to_string(), nick);
|
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).kick(stream, jid.bare_jid.to_string(), nick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool kick_possible(Account account, Jid occupant) {
|
||||||
|
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
|
if (stream != null) return stream.get_module(Xep.Muc.Module.IDENTITY).kick_possible(stream, occupant.to_string());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public ArrayList<Jid>? get_occupants(Jid jid, Account account) {
|
public ArrayList<Jid>? get_occupants(Jid jid, Account account) {
|
||||||
if (is_groupchat(jid, account)) {
|
if (is_groupchat(jid, account)) {
|
||||||
return stream_interactor.get_module(PresenceManager.IDENTITY).get_full_jids(jid, account);
|
return stream_interactor.get_module(PresenceManager.IDENTITY).get_full_jids(jid, account);
|
||||||
|
@ -79,9 +90,9 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
|
|
||||||
public ArrayList<Jid>? get_other_occupants(Jid jid, Account account) {
|
public ArrayList<Jid>? get_other_occupants(Jid jid, Account account) {
|
||||||
ArrayList<Jid>? occupants = get_occupants(jid, account);
|
ArrayList<Jid>? occupants = get_occupants(jid, account);
|
||||||
string? nick = get_nick(jid, account);
|
Jid? own_jid = get_own_jid(jid, account);
|
||||||
if (occupants != null && nick != null) {
|
if (occupants != null && own_jid != null) {
|
||||||
occupants.remove(new Jid(@"$(jid.bare_jid)/$nick"));
|
occupants.remove(own_jid);
|
||||||
}
|
}
|
||||||
return occupants;
|
return occupants;
|
||||||
}
|
}
|
||||||
|
@ -142,11 +153,15 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Xep.Muc.Role? get_role(Jid jid, Account account) {
|
||||||
|
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
|
if (stream != null) return stream.get_flag(Xep.Muc.Flag.IDENTITY).get_occupant_role(jid.to_string());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public Xep.Muc.Affiliation? get_affiliation(Jid muc_jid, Jid jid, Account account) {
|
public Xep.Muc.Affiliation? get_affiliation(Jid muc_jid, Jid jid, Account account) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) {
|
if (stream != null) return stream.get_flag(Xep.Muc.Flag.IDENTITY).get_affiliation(muc_jid.to_string(), jid.to_string());
|
||||||
return stream.get_flag(Xep.Muc.Flag.IDENTITY).get_affiliation(muc_jid.to_string(), jid.to_string());
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,17 +185,19 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? get_nick(Jid jid, Account account) {
|
public Jid? get_own_jid(Jid muc_jid, Account account) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
Xep.Muc.Flag? flag = stream.get_flag(Xep.Muc.Flag.IDENTITY);
|
Xep.Muc.Flag? flag = stream.get_flag(Xep.Muc.Flag.IDENTITY);
|
||||||
if (flag != null) return flag.get_muc_nick(jid.bare_jid.to_string());
|
if (flag == null) return null;
|
||||||
|
string? nick = flag.get_muc_nick(muc_jid.bare_jid.to_string());
|
||||||
|
if (nick != null) return new Jid.with_resource(muc_jid.bare_jid.to_string(), nick);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool is_joined(Jid jid, Account account) {
|
public bool is_joined(Jid jid, Account account) {
|
||||||
return get_nick(jid, account) != null;
|
return get_own_jid(jid, account) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_account_added(Account account) {
|
private void on_account_added(Account account) {
|
||||||
|
|
|
@ -8,19 +8,21 @@ namespace Dino.Ui.AddConversation.Chat {
|
||||||
|
|
||||||
public class Dialog : Gtk.Dialog {
|
public class Dialog : Gtk.Dialog {
|
||||||
|
|
||||||
public signal void conversation_opened(Conversation conversation);
|
public signal void selected(Account account, Jid jid);
|
||||||
|
|
||||||
private Button ok_button;
|
public Button ok_button;
|
||||||
|
|
||||||
private RosterList roster_list;
|
private RosterList roster_list;
|
||||||
private SelectJidFragment select_jid_fragment;
|
private SelectJidFragment select_jid_fragment;
|
||||||
private StreamInteractor stream_interactor;
|
private StreamInteractor stream_interactor;
|
||||||
|
private Gee.List<Account> accounts;
|
||||||
|
|
||||||
public Dialog(StreamInteractor stream_interactor) {
|
public Dialog(StreamInteractor stream_interactor, Gee.List<Account> accounts) {
|
||||||
Object(use_header_bar : 1);
|
Object(use_header_bar : 1);
|
||||||
this.title = _("Start Chat");
|
modal = true;
|
||||||
this.modal = true;
|
|
||||||
this.stream_interactor = stream_interactor;
|
this.stream_interactor = stream_interactor;
|
||||||
|
this.accounts = accounts;
|
||||||
|
|
||||||
setup_headerbar();
|
setup_headerbar();
|
||||||
setup_view();
|
setup_view();
|
||||||
|
@ -37,19 +39,22 @@ public class Dialog : Gtk.Dialog {
|
||||||
|
|
||||||
ok_button = new Button();
|
ok_button = new Button();
|
||||||
ok_button.get_style_context().add_class("suggested-action");
|
ok_button.get_style_context().add_class("suggested-action");
|
||||||
ok_button.label = _("Start");
|
|
||||||
ok_button.sensitive = false;
|
ok_button.sensitive = false;
|
||||||
ok_button.visible = true;
|
ok_button.visible = true;
|
||||||
header_bar.pack_end(ok_button);
|
header_bar.pack_end(ok_button);
|
||||||
|
|
||||||
cancel_button.clicked.connect(() => { close(); });
|
cancel_button.clicked.connect(() => { close(); });
|
||||||
ok_button.clicked.connect(on_ok_button_clicked);
|
ok_button.clicked.connect(() => {
|
||||||
|
ListRow? selected_row = roster_list.get_selected_row() as ListRow;
|
||||||
|
if (selected_row != null) selected(selected_row.account, selected_row.jid);
|
||||||
|
close();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setup_view() {
|
private void setup_view() {
|
||||||
roster_list = new RosterList(stream_interactor);
|
roster_list = new RosterList(stream_interactor, accounts);
|
||||||
roster_list.row_activated.connect(() => { ok_button.clicked(); });
|
roster_list.row_activated.connect(() => { ok_button.clicked(); });
|
||||||
select_jid_fragment = new SelectJidFragment(stream_interactor, roster_list);
|
select_jid_fragment = new SelectJidFragment(stream_interactor, roster_list, accounts);
|
||||||
select_jid_fragment.add_jid.connect((row) => {
|
select_jid_fragment.add_jid.connect((row) => {
|
||||||
AddContactDialog add_contact_dialog = new AddContactDialog(stream_interactor);
|
AddContactDialog add_contact_dialog = new AddContactDialog(stream_interactor);
|
||||||
add_contact_dialog.set_transient_for(this);
|
add_contact_dialog.set_transient_for(this);
|
||||||
|
@ -67,16 +72,6 @@ public class Dialog : Gtk.Dialog {
|
||||||
});
|
});
|
||||||
get_content_area().add(select_jid_fragment);
|
get_content_area().add(select_jid_fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void on_ok_button_clicked() {
|
|
||||||
ListRow? selected_row = roster_list.get_selected_row() as ListRow;
|
|
||||||
if (selected_row != null) {
|
|
||||||
Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(selected_row.jid, selected_row.account, Conversation.Type.CHAT);
|
|
||||||
stream_interactor.get_module(ConversationManager.IDENTITY).start_conversation(conversation, true);
|
|
||||||
conversation_opened(conversation);
|
|
||||||
}
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -10,27 +10,28 @@ protected class RosterList : FilterableList {
|
||||||
|
|
||||||
public signal void conversation_selected(Conversation? conversation);
|
public signal void conversation_selected(Conversation? conversation);
|
||||||
private StreamInteractor stream_interactor;
|
private StreamInteractor stream_interactor;
|
||||||
|
private Gee.List<Account> accounts;
|
||||||
|
|
||||||
private HashMap<Account, HashMap<Jid, ListRow>> rows = new HashMap<Account, HashMap<Jid, ListRow>>(Account.hash_func, Account.equals_func);
|
private HashMap<Account, HashMap<Jid, ListRow>> rows = new HashMap<Account, HashMap<Jid, ListRow>>(Account.hash_func, Account.equals_func);
|
||||||
|
|
||||||
public RosterList(StreamInteractor stream_interactor) {
|
public RosterList(StreamInteractor stream_interactor, Gee.List<Account> accounts) {
|
||||||
this.stream_interactor = stream_interactor;
|
this.stream_interactor = stream_interactor;
|
||||||
|
this.accounts = accounts;
|
||||||
|
|
||||||
set_filter_func(filter);
|
set_filter_func(filter);
|
||||||
set_header_func(header);
|
set_header_func(header);
|
||||||
set_sort_func(sort);
|
set_sort_func(sort);
|
||||||
|
|
||||||
stream_interactor.get_module(RosterManager.IDENTITY).removed_roster_item.connect( (account, jid, roster_item) => {
|
stream_interactor.get_module(RosterManager.IDENTITY).removed_roster_item.connect( (account, jid, roster_item) => {
|
||||||
Idle.add(() => { on_removed_roster_item(account, jid, roster_item); return false;});});
|
if (accounts.contains(account))
|
||||||
|
Idle.add(() => { on_removed_roster_item(account, jid, roster_item); return false;});
|
||||||
|
});
|
||||||
stream_interactor.get_module(RosterManager.IDENTITY).updated_roster_item.connect( (account, jid, roster_item) => {
|
stream_interactor.get_module(RosterManager.IDENTITY).updated_roster_item.connect( (account, jid, roster_item) => {
|
||||||
Idle.add(() => { on_updated_roster_item(account, jid, roster_item); return false;});});
|
if (accounts.contains(account))
|
||||||
|
Idle.add(() => { on_updated_roster_item(account, jid, roster_item); return false;});
|
||||||
|
});
|
||||||
|
|
||||||
foreach (Account account in stream_interactor.get_accounts()) {
|
foreach (Account a in accounts) fetch_roster_items(a);
|
||||||
rows[account] = new HashMap<Jid, ListRow>(Jid.hash_func, Jid.equals_func);
|
|
||||||
foreach (Roster.Item roster_item in stream_interactor.get_module(RosterManager.IDENTITY).get_roster(account)) {
|
|
||||||
on_updated_roster_item(account, new Jid(roster_item.jid), roster_item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_removed_roster_item(Account account, Jid jid, Roster.Item roster_item) {
|
private void on_removed_roster_item(Account account, Jid jid, Roster.Item roster_item) {
|
||||||
|
@ -42,13 +43,20 @@ protected class RosterList : FilterableList {
|
||||||
|
|
||||||
private void on_updated_roster_item(Account account, Jid jid, Roster.Item roster_item) {
|
private void on_updated_roster_item(Account account, Jid jid, Roster.Item roster_item) {
|
||||||
on_removed_roster_item(account, jid, roster_item);
|
on_removed_roster_item(account, jid, roster_item);
|
||||||
ListRow row = new ListRow.from_jid(stream_interactor, new Jid(roster_item.jid), account);
|
ListRow row = new ListRow.from_jid(stream_interactor, new Jid(roster_item.jid), account, accounts.size > 1);
|
||||||
rows[account][jid] = row;
|
rows[account][jid] = row;
|
||||||
add(row);
|
add(row);
|
||||||
invalidate_sort();
|
invalidate_sort();
|
||||||
invalidate_filter();
|
invalidate_filter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fetch_roster_items(Account account) {
|
||||||
|
rows[account] = new HashMap<Jid, ListRow>(Jid.hash_func, Jid.equals_func);
|
||||||
|
foreach (Roster.Item roster_item in stream_interactor.get_module(RosterManager.IDENTITY).get_roster(account)) {
|
||||||
|
on_updated_roster_item(account, new Jid(roster_item.jid), roster_item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void header(ListBoxRow row, ListBoxRow? before_row) {
|
private void header(ListBoxRow row, ListBoxRow? before_row) {
|
||||||
if (row.get_header() == null && before_row != null) {
|
if (row.get_header() == null && before_row != null) {
|
||||||
row.set_header(new Separator(Orientation.HORIZONTAL));
|
row.set_header(new Separator(Orientation.HORIZONTAL));
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class Dialog : Gtk.Dialog {
|
||||||
private void setup_jid_add_view() {
|
private void setup_jid_add_view() {
|
||||||
conference_list = new ConferenceList(stream_interactor);
|
conference_list = new ConferenceList(stream_interactor);
|
||||||
conference_list.row_activated.connect(() => { ok_button.clicked(); });
|
conference_list.row_activated.connect(() => { ok_button.clicked(); });
|
||||||
select_fragment = new SelectJidFragment(stream_interactor, conference_list);
|
select_fragment = new SelectJidFragment(stream_interactor, conference_list, stream_interactor.get_accounts());
|
||||||
select_fragment.add_jid.connect((row) => {
|
select_fragment.add_jid.connect((row) => {
|
||||||
AddGroupchatDialog dialog = new AddGroupchatDialog(stream_interactor);
|
AddGroupchatDialog dialog = new AddGroupchatDialog(stream_interactor);
|
||||||
dialog.set_transient_for(this);
|
dialog.set_transient_for(this);
|
||||||
|
|
|
@ -17,12 +17,12 @@ public class ListRow : ListBoxRow {
|
||||||
|
|
||||||
public ListRow() {}
|
public ListRow() {}
|
||||||
|
|
||||||
public ListRow.from_jid(StreamInteractor stream_interactor, Jid jid, Account account) {
|
public ListRow.from_jid(StreamInteractor stream_interactor, Jid jid, Account account, bool show_account) {
|
||||||
this.jid = jid;
|
this.jid = jid;
|
||||||
this.account = account;
|
this.account = account;
|
||||||
|
|
||||||
string display_name = Util.get_display_name(stream_interactor, jid, account);
|
string display_name = Util.get_display_name(stream_interactor, jid, account);
|
||||||
if (stream_interactor.get_accounts().size > 1) {
|
if (show_account && stream_interactor.get_accounts().size > 1) {
|
||||||
via_label.label = @"via $(account.bare_jid)";
|
via_label.label = @"via $(account.bare_jid)";
|
||||||
this.has_tooltip = true;
|
this.has_tooltip = true;
|
||||||
set_tooltip_text(jid.to_string());
|
set_tooltip_text(jid.to_string());
|
||||||
|
|
|
@ -23,13 +23,16 @@ public class SelectJidFragment : Gtk.Box {
|
||||||
[GtkChild] private Button edit_button;
|
[GtkChild] private Button edit_button;
|
||||||
[GtkChild] private Button remove_button;
|
[GtkChild] private Button remove_button;
|
||||||
|
|
||||||
private FilterableList filterable_list;
|
|
||||||
private ArrayList<AddListRow> added_rows = new ArrayList<AddListRow>();
|
|
||||||
private StreamInteractor stream_interactor;
|
private StreamInteractor stream_interactor;
|
||||||
|
private FilterableList filterable_list;
|
||||||
|
private Gee.List<Account> accounts;
|
||||||
|
|
||||||
public SelectJidFragment(StreamInteractor stream_interactor, FilterableList filterable_list) {
|
private ArrayList<AddListRow> added_rows = new ArrayList<AddListRow>();
|
||||||
|
|
||||||
|
public SelectJidFragment(StreamInteractor stream_interactor, FilterableList filterable_list, Gee.List<Account> accounts) {
|
||||||
this.stream_interactor = stream_interactor;
|
this.stream_interactor = stream_interactor;
|
||||||
this.filterable_list = filterable_list;
|
this.filterable_list = filterable_list;
|
||||||
|
this.accounts = accounts;
|
||||||
|
|
||||||
filterable_list.visible = true;
|
filterable_list.visible = true;
|
||||||
filterable_list.activate_on_single_click = false;
|
filterable_list.activate_on_single_click = false;
|
||||||
|
@ -57,7 +60,7 @@ public class SelectJidFragment : Gtk.Box {
|
||||||
filterable_list.set_filter_values(values);
|
filterable_list.set_filter_values(values);
|
||||||
Jid? parsed_jid = Jid.parse(str);
|
Jid? parsed_jid = Jid.parse(str);
|
||||||
if (parsed_jid != null && parsed_jid.localpart != null) {
|
if (parsed_jid != null && parsed_jid.localpart != null) {
|
||||||
foreach (Account account in stream_interactor.get_accounts()) {
|
foreach (Account account in accounts) {
|
||||||
AddListRow row = new AddListRow(stream_interactor, str, account);
|
AddListRow row = new AddListRow(stream_interactor, str, account);
|
||||||
filterable_list.add(row);
|
filterable_list.add(row);
|
||||||
added_rows.add(row);
|
added_rows.add(row);
|
||||||
|
|
|
@ -90,8 +90,8 @@ class OccupantsTabCompletor {
|
||||||
Gee.List<Message> messages = stream_interactor.get_module(MessageStorage.IDENTITY).get_messages(conversation, 10);
|
Gee.List<Message> messages = stream_interactor.get_module(MessageStorage.IDENTITY).get_messages(conversation, 10);
|
||||||
for (int i = messages.size - 1; i > 0; i--) {
|
for (int i = messages.size - 1; i > 0; i--) {
|
||||||
string resourcepart = messages[i].from.resourcepart;
|
string resourcepart = messages[i].from.resourcepart;
|
||||||
string own_nick = stream_interactor.get_module(MucManager.IDENTITY).get_nick(conversation.counterpart, conversation.account);
|
Jid? own_nick = stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(conversation.counterpart, conversation.account);
|
||||||
if (resourcepart != null && resourcepart != "" && resourcepart != own_nick && !ret.contains(resourcepart)) {
|
if (resourcepart != null && resourcepart != "" && resourcepart != own_nick.resourcepart && !ret.contains(resourcepart)) {
|
||||||
ret.add(resourcepart);
|
ret.add(resourcepart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,15 @@ public class ConversationListTitlebar : Gtk.HeaderBar {
|
||||||
private void create_add_menu(Window window) {
|
private void create_add_menu(Window window) {
|
||||||
SimpleAction contacts_action = new SimpleAction("add_chat", null);
|
SimpleAction contacts_action = new SimpleAction("add_chat", null);
|
||||||
contacts_action.activate.connect(() => {
|
contacts_action.activate.connect(() => {
|
||||||
AddConversation.Chat.Dialog add_chat_dialog = new AddConversation.Chat.Dialog(stream_interactor);
|
AddConversation.Chat.Dialog add_chat_dialog = new AddConversation.Chat.Dialog(stream_interactor, stream_interactor.get_accounts());
|
||||||
add_chat_dialog.set_transient_for(window);
|
add_chat_dialog.set_transient_for(window);
|
||||||
add_chat_dialog.conversation_opened.connect((conversation) => conversation_opened(conversation));
|
add_chat_dialog.title = _("Start Chat");
|
||||||
|
add_chat_dialog.ok_button.label = _("Start");
|
||||||
|
add_chat_dialog.selected.connect((account, jid) => {
|
||||||
|
Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(jid, account, Conversation.Type.CHAT);
|
||||||
|
stream_interactor.get_module(ConversationManager.IDENTITY).start_conversation(conversation, true);
|
||||||
|
conversation_opened(conversation);
|
||||||
|
});
|
||||||
add_chat_dialog.present();
|
add_chat_dialog.present();
|
||||||
});
|
});
|
||||||
GLib.Application.get_default().add_action(contacts_action);
|
GLib.Application.get_default().add_action(contacts_action);
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class GroupchatPmRow : ConversationRow {
|
||||||
Box inner_box = builder.get_object("inner_box") as Box;
|
Box inner_box = builder.get_object("inner_box") as Box;
|
||||||
Label jid_label = builder.get_object("jid_label") as Label;
|
Label jid_label = builder.get_object("jid_label") as Label;
|
||||||
jid_label.label = conversation.counterpart.to_string();
|
jid_label.label = conversation.counterpart.to_string();
|
||||||
if (stream_interactor.get_module(MucManager.IDENTITY).get_nick(conversation.counterpart, conversation.account) != null) {
|
if (stream_interactor.get_module(MucManager.IDENTITY).is_joined(conversation.counterpart, conversation.account)) {
|
||||||
inner_box.add(get_fulljid_box(conversation.counterpart));
|
inner_box.add(get_fulljid_box(conversation.counterpart));
|
||||||
}
|
}
|
||||||
return main_box;
|
return main_box;
|
||||||
|
|
|
@ -16,10 +16,12 @@ public class ConversationTitlebar : Gtk.HeaderBar {
|
||||||
private Map<RadioButton, Plugins.EncryptionListEntry> encryption_radios = new HashMap<RadioButton, Plugins.EncryptionListEntry>();
|
private Map<RadioButton, Plugins.EncryptionListEntry> encryption_radios = new HashMap<RadioButton, Plugins.EncryptionListEntry>();
|
||||||
|
|
||||||
private StreamInteractor stream_interactor;
|
private StreamInteractor stream_interactor;
|
||||||
|
private Window window;
|
||||||
private Conversation? conversation;
|
private Conversation? conversation;
|
||||||
|
|
||||||
public ConversationTitlebar(StreamInteractor stream_interactor) {
|
public ConversationTitlebar(StreamInteractor stream_interactor, Window window) {
|
||||||
this.stream_interactor = stream_interactor;
|
this.stream_interactor = stream_interactor;
|
||||||
|
this.window = window;
|
||||||
create_conversation_menu();
|
create_conversation_menu();
|
||||||
create_encryption_menu();
|
create_encryption_menu();
|
||||||
|
|
||||||
|
@ -67,7 +69,7 @@ public class ConversationTitlebar : Gtk.HeaderBar {
|
||||||
groupchat_button.visible = conversation.type_ == Conversation.Type.GROUPCHAT;
|
groupchat_button.visible = conversation.type_ == Conversation.Type.GROUPCHAT;
|
||||||
if (conversation.type_ == Conversation.Type.GROUPCHAT) {
|
if (conversation.type_ == Conversation.Type.GROUPCHAT) {
|
||||||
groupchat_button.set_use_popover(true);
|
groupchat_button.set_use_popover(true);
|
||||||
OccupantMenu.View menu = new OccupantMenu.View(stream_interactor, conversation);
|
OccupantMenu.View menu = new OccupantMenu.View(stream_interactor, window, conversation);
|
||||||
groupchat_button.set_popover(menu);
|
groupchat_button.set_popover(menu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,8 +96,8 @@ public class Notifications : Object {
|
||||||
private bool should_notify_message(Entities.Message message, Conversation conversation) {
|
private bool should_notify_message(Entities.Message message, Conversation conversation) {
|
||||||
Conversation.NotifySetting notify = conversation.get_notification_setting(stream_interactor);
|
Conversation.NotifySetting notify = conversation.get_notification_setting(stream_interactor);
|
||||||
if (notify == Conversation.NotifySetting.OFF) return false;
|
if (notify == Conversation.NotifySetting.OFF) return false;
|
||||||
string? nick = stream_interactor.get_module(MucManager.IDENTITY).get_nick(conversation.counterpart, conversation.account);
|
Jid? nick = stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(conversation.counterpart, conversation.account);
|
||||||
if (notify == Conversation.NotifySetting.HIGHLIGHT && nick != null && !message.body.contains(nick)) return false;
|
if (notify == Conversation.NotifySetting.HIGHLIGHT && nick != null && !message.body.contains(nick.resourcepart)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ public class List : Box {
|
||||||
|
|
||||||
public void initialize_for_conversation(Conversation conversation) {
|
public void initialize_for_conversation(Conversation conversation) {
|
||||||
this.conversation = conversation;
|
this.conversation = conversation;
|
||||||
ArrayList<Jid>? occupants = stream_interactor.get_module(MucManager.IDENTITY).get_occupants(conversation.counterpart, conversation.account);
|
Gee.List<Jid>? occupants = stream_interactor.get_module(MucManager.IDENTITY).get_occupants(conversation.counterpart, conversation.account);
|
||||||
if (occupants != null) {
|
if (occupants != null) {
|
||||||
foreach (Jid occupant in occupants) {
|
foreach (Jid occupant in occupants) {
|
||||||
add_occupant(occupant);
|
add_occupant(occupant);
|
||||||
|
@ -110,12 +110,24 @@ public class List : Box {
|
||||||
default:
|
default:
|
||||||
aff_str = _("User"); break;
|
aff_str = _("User"); break;
|
||||||
}
|
}
|
||||||
Box box = new Box(Orientation.VERTICAL, 0) { visible=true };
|
|
||||||
Label label = new Label("") { margin_left=10, margin_top=top?5:15, xalign=0, visible=true };
|
int count = 0;
|
||||||
label.set_markup(@"<b>$(Markup.escape_text(aff_str))</b>");
|
foreach (ListRow row in rows.values) {
|
||||||
box.add(label);
|
Xmpp.Xep.Muc.Affiliation aff = stream_interactor.get_module(MucManager.IDENTITY).get_affiliation(conversation.counterpart, row.jid, conversation.account);
|
||||||
box.add(new Separator(Orientation.HORIZONTAL) { visible=true });
|
if (aff == affiliation) count++;
|
||||||
return box;
|
}
|
||||||
|
|
||||||
|
Label title_label = new Label("") { margin_left=10, xalign=0, visible=true };
|
||||||
|
title_label.set_markup(@"<b>$(Markup.escape_text(aff_str))</b>");
|
||||||
|
|
||||||
|
Label count_label = new Label(@"$count") { xalign=0, margin_right=7, expand=true, visible=true };
|
||||||
|
count_label.get_style_context().add_class("dim-label");
|
||||||
|
|
||||||
|
Grid grid = new Grid() { margin_top=top?5:15, column_spacing=5, hexpand=true, visible=true };
|
||||||
|
grid.attach(title_label, 0, 0, 1, 1);
|
||||||
|
grid.attach(count_label, 1, 0, 1, 1);
|
||||||
|
grid.attach(new Separator(Orientation.HORIZONTAL) { expand=true, visible=true }, 0, 1, 2, 1);
|
||||||
|
return grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool filter(ListBoxRow r) {
|
private bool filter(ListBoxRow r) {
|
||||||
|
|
|
@ -11,8 +11,8 @@ public class ListRow : ListBoxRow {
|
||||||
[GtkChild] private Image image;
|
[GtkChild] private Image image;
|
||||||
[GtkChild] public Label name_label;
|
[GtkChild] public Label name_label;
|
||||||
|
|
||||||
public Account account;
|
public Account? account;
|
||||||
public Jid jid;
|
public Jid? jid;
|
||||||
|
|
||||||
public ListRow(StreamInteractor stream_interactor, Account account, Jid jid) {
|
public ListRow(StreamInteractor stream_interactor, Account account, Jid jid) {
|
||||||
this.account = account;
|
this.account = account;
|
||||||
|
@ -22,8 +22,9 @@ public class ListRow : ListBoxRow {
|
||||||
Util.image_set_from_scaled_pixbuf(image, (new AvatarGenerator(30, 30, image.scale_factor)).draw_jid(stream_interactor, jid, account));
|
Util.image_set_from_scaled_pixbuf(image, (new AvatarGenerator(30, 30, image.scale_factor)).draw_jid(stream_interactor, jid, account));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void on_presence_received(Presence.Stanza presence) {
|
public ListRow.label(string c, string text) {
|
||||||
|
name_label.label = text;
|
||||||
|
image.set_from_pixbuf((new AvatarGenerator(30, 30, 1)).set_greyscale(true).draw_text(c)); // why 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Gee;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
@ -10,22 +11,40 @@ public class View : Popover {
|
||||||
|
|
||||||
private Stack stack = new Stack() { vhomogeneous=false, visible=true };
|
private Stack stack = new Stack() { vhomogeneous=false, visible=true };
|
||||||
private List list;
|
private List list;
|
||||||
private Label header_label = new Label("") { xalign=0.5f, hexpand=true, visible=true };
|
private ListBox invite_list;
|
||||||
|
|
||||||
public View(StreamInteractor stream_interactor, Conversation conversation) {
|
public View(StreamInteractor stream_interactor, Window window, Conversation conversation) {
|
||||||
this.stream_interactor = stream_interactor;
|
this.stream_interactor = stream_interactor;
|
||||||
this.conversation = conversation;
|
this.conversation = conversation;
|
||||||
|
|
||||||
|
Box list_box = new Box(Orientation.VERTICAL, 1) { visible=true };
|
||||||
list = new List(stream_interactor, conversation) { visible=true };
|
list = new List(stream_interactor, conversation) { visible=true };
|
||||||
stack.add_named(list, "list");
|
list_box.add(list);
|
||||||
setup_menu();
|
|
||||||
|
invite_list = new ListBox() { visible=true };
|
||||||
|
invite_list.add(new ListRow.label("+", _("Invite")) {visible=true});
|
||||||
|
list_box.add(invite_list);
|
||||||
|
invite_list.row_activated.connect((row) => {
|
||||||
|
hide();
|
||||||
|
Gee.List<Account> acc_list = new ArrayList<Account>(Account.equals_func);
|
||||||
|
acc_list.add(conversation.account);
|
||||||
|
AddConversation.Chat.Dialog add_chat_dialog = new AddConversation.Chat.Dialog(stream_interactor, acc_list);
|
||||||
|
add_chat_dialog.set_transient_for(window);
|
||||||
|
add_chat_dialog.title = _("Invite to Conference");
|
||||||
|
add_chat_dialog.ok_button.label = _("Invite");
|
||||||
|
add_chat_dialog.selected.connect((account, jid) => {
|
||||||
|
stream_interactor.get_module(MucManager.IDENTITY).invite(conversation.account, conversation.counterpart, jid);
|
||||||
|
});
|
||||||
|
add_chat_dialog.present();
|
||||||
|
});
|
||||||
|
|
||||||
|
stack.add_named(list_box, "list");
|
||||||
add(stack);
|
add(stack);
|
||||||
stack.visible_child_name = "list";
|
stack.visible_child_name = "list";
|
||||||
|
|
||||||
list.list_box.row_activated.connect((row) => {
|
list.list_box.row_activated.connect((row) => {
|
||||||
ListRow list_row = row as ListRow;
|
ListRow list_row = row as ListRow;
|
||||||
header_label.label = list_row.name_label.label;
|
show_menu(list_row.jid, list_row.name_label.label);
|
||||||
show_menu();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
hide.connect(reset);
|
hide.connect(reset);
|
||||||
|
@ -35,25 +54,7 @@ public class View : Popover {
|
||||||
stack.transition_type = StackTransitionType.NONE;
|
stack.transition_type = StackTransitionType.NONE;
|
||||||
stack.visible_child_name = "list";
|
stack.visible_child_name = "list";
|
||||||
list.list_box.unselect_all();
|
list.list_box.unselect_all();
|
||||||
}
|
invite_list.unselect_all();
|
||||||
|
|
||||||
private void setup_menu() {
|
|
||||||
Box header_box = new Box(Orientation.HORIZONTAL, 5) { visible=true };
|
|
||||||
header_box.add(new Image.from_icon_name("pan-start-symbolic", IconSize.SMALL_TOOLBAR) { visible=true });
|
|
||||||
header_box.add(header_label);
|
|
||||||
|
|
||||||
Button header_button = new Button() { relief=ReliefStyle.NONE, visible=true };
|
|
||||||
header_button.add(header_box);
|
|
||||||
|
|
||||||
ModelButton private_button = new ModelButton() { active=true, text=_("Start private conversation"), visible=true };
|
|
||||||
|
|
||||||
Box outer_box = new Box(Orientation.VERTICAL, 5) { margin=10, visible=true };
|
|
||||||
outer_box.add(header_button);
|
|
||||||
outer_box.add(private_button);
|
|
||||||
stack.add_named(outer_box, "menu");
|
|
||||||
|
|
||||||
header_button.clicked.connect(show_list);
|
|
||||||
private_button.clicked.connect(private_conversation_button_clicked);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void show_list() {
|
private void show_list() {
|
||||||
|
@ -62,8 +63,34 @@ public class View : Popover {
|
||||||
stack.visible_child_name = "list";
|
stack.visible_child_name = "list";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void show_menu() {
|
private void show_menu(Jid jid, string name_label) {
|
||||||
stack.transition_type = StackTransitionType.SLIDE_LEFT;
|
stack.transition_type = StackTransitionType.SLIDE_LEFT;
|
||||||
|
|
||||||
|
Box header_box = new Box(Orientation.HORIZONTAL, 5) { visible=true };
|
||||||
|
header_box.add(new Image.from_icon_name("pan-start-symbolic", IconSize.SMALL_TOOLBAR) { visible=true });
|
||||||
|
header_box.add(new Label(name_label) { xalign=0.5f, hexpand=true, visible=true });
|
||||||
|
|
||||||
|
Button header_button = new Button() { relief=ReliefStyle.NONE, visible=true };
|
||||||
|
header_button.add(header_box);
|
||||||
|
|
||||||
|
Box outer_box = new Box(Orientation.VERTICAL, 5) { margin=10, visible=true };
|
||||||
|
outer_box.add(header_button);
|
||||||
|
header_button.clicked.connect(show_list);
|
||||||
|
|
||||||
|
ModelButton private_button = new ModelButton() { active=true, text=_("Start private conversation"), visible=true };
|
||||||
|
outer_box.add(private_button);
|
||||||
|
private_button.clicked.connect(private_conversation_button_clicked);
|
||||||
|
|
||||||
|
Jid? own_jid = stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(conversation.counterpart, conversation.account);
|
||||||
|
Xmpp.Xep.Muc.Role? role = stream_interactor.get_module(MucManager.IDENTITY).get_role(own_jid, conversation.account);
|
||||||
|
|
||||||
|
if (role == Xmpp.Xep.Muc.Role.MODERATOR && stream_interactor.get_module(MucManager.IDENTITY).kick_possible(conversation.account, jid)) {
|
||||||
|
ModelButton kick_button = new ModelButton() { active=true, text=_("Kick"), visible=true };
|
||||||
|
outer_box.add(kick_button);
|
||||||
|
kick_button.clicked.connect(kick_button_clicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
stack.add_named(outer_box, "menu");
|
||||||
stack.visible_child_name = "menu";
|
stack.visible_child_name = "menu";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +101,13 @@ public class View : Popover {
|
||||||
Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(list_row.jid, list_row.account, Conversation.Type.GROUPCHAT_PM);
|
Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(list_row.jid, list_row.account, Conversation.Type.GROUPCHAT_PM);
|
||||||
stream_interactor.get_module(ConversationManager.IDENTITY).start_conversation(conversation, true);
|
stream_interactor.get_module(ConversationManager.IDENTITY).start_conversation(conversation, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void kick_button_clicked() {
|
||||||
|
ListRow? list_row = list.list_box.get_selected_row() as ListRow;
|
||||||
|
if (list_row == null) return;
|
||||||
|
|
||||||
|
stream_interactor.get_module(MucManager.IDENTITY).kick(conversation.account, conversation.counterpart, list_row.jid.resourcepart);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -83,7 +83,7 @@ public class UnifiedWindow : Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setup_headerbar() {
|
private void setup_headerbar() {
|
||||||
conversation_titlebar = new ConversationTitlebar(stream_interactor) { visible=true };
|
conversation_titlebar = new ConversationTitlebar(stream_interactor, this) { visible=true };
|
||||||
conversation_list_titlebar = new ConversationListTitlebar(stream_interactor, this) { visible=true };
|
conversation_list_titlebar = new ConversationListTitlebar(stream_interactor, this) { visible=true };
|
||||||
headerbar_paned.add1(conversation_list_titlebar);
|
headerbar_paned.add1(conversation_list_titlebar);
|
||||||
headerbar_paned.add2(conversation_titlebar);
|
headerbar_paned.add2(conversation_titlebar);
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Xmpp.Iq {
|
||||||
private HashMap<string, ResponseListener> responseListeners = new HashMap<string, ResponseListener>();
|
private HashMap<string, ResponseListener> responseListeners = new HashMap<string, ResponseListener>();
|
||||||
private HashMap<string, ArrayList<Handler>> namespaceRegistrants = new HashMap<string, ArrayList<Handler>>();
|
private HashMap<string, ArrayList<Handler>> namespaceRegistrants = new HashMap<string, ArrayList<Handler>>();
|
||||||
|
|
||||||
[CCode (has_target = false)] public delegate void OnResult(XmppStream stream, Iq.Stanza iq, Object store);
|
[CCode (has_target = false)] public delegate void OnResult(XmppStream stream, Iq.Stanza iq, Object? store);
|
||||||
public void send_iq(XmppStream stream, Iq.Stanza iq, OnResult? listener = null, Object? store = null) {
|
public void send_iq(XmppStream stream, Iq.Stanza iq, OnResult? listener = null, Object? store = null) {
|
||||||
try {
|
try {
|
||||||
stream.write(iq.stanza);
|
stream.write(iq.stanza);
|
||||||
|
|
|
@ -103,10 +103,37 @@ public class Module : XmppStreamModule {
|
||||||
stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence);
|
stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void invite(XmppStream stream, string to_muc, string jid) {
|
||||||
|
Message.Stanza message = new Message.Stanza();
|
||||||
|
message.to = to_muc;
|
||||||
|
StanzaNode invite_node = new StanzaNode.build("x", NS_URI_USER).add_self_xmlns()
|
||||||
|
.put_node(new StanzaNode.build("invite", NS_URI_USER).put_attribute("to", jid));
|
||||||
|
message.stanza.put_node(invite_node);
|
||||||
|
stream.get_module(Message.Module.IDENTITY).send_message(stream, message);
|
||||||
|
}
|
||||||
|
|
||||||
public void kick(XmppStream stream, string jid, string nick) {
|
public void kick(XmppStream stream, string jid, string nick) {
|
||||||
change_role(stream, jid, nick, "none");
|
change_role(stream, jid, nick, "none");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XEP 0046: "A user cannot be kicked by a moderator with a lower affiliation." (XEP 0045 8.2) */
|
||||||
|
public bool kick_possible(XmppStream stream, string occupant) {
|
||||||
|
string muc_jid = get_bare_jid(occupant);
|
||||||
|
Flag flag = stream.get_flag(Flag.IDENTITY);
|
||||||
|
string own_nick = flag.get_muc_nick(muc_jid);
|
||||||
|
Affiliation my_affiliation = flag.get_affiliation(muc_jid, muc_jid + "/" + own_nick);
|
||||||
|
Affiliation other_affiliation = flag.get_affiliation(muc_jid, occupant);
|
||||||
|
switch (my_affiliation) {
|
||||||
|
case Affiliation.MEMBER:
|
||||||
|
if (other_affiliation == Affiliation.ADMIN || other_affiliation == Affiliation.OWNER) return false;
|
||||||
|
break;
|
||||||
|
case Affiliation.ADMIN:
|
||||||
|
if (other_affiliation == Affiliation.OWNER) return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
[CCode (has_target = false)] public delegate void OnConfigFormResult(XmppStream stream, string jid, DataForms.DataForm data_form, Object? store);
|
[CCode (has_target = false)] public delegate void OnConfigFormResult(XmppStream stream, string jid, DataForms.DataForm data_form, Object? store);
|
||||||
public void get_config_form(XmppStream stream, string jid, OnConfigFormResult listener, Object? store) {
|
public void get_config_form(XmppStream stream, string jid, OnConfigFormResult listener, Object? store) {
|
||||||
Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_OWNER).add_self_xmlns()) { to=jid };
|
Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_OWNER).add_self_xmlns()) { to=jid };
|
||||||
|
|
|
@ -35,12 +35,12 @@ namespace Xmpp.Xep.PrivateXmlStorage {
|
||||||
public override string get_ns() { return NS_URI; }
|
public override string get_ns() { return NS_URI; }
|
||||||
public override string get_id() { return IDENTITY.id; }
|
public override string get_id() { return IDENTITY.id; }
|
||||||
|
|
||||||
private static void on_store_response(XmppStream stream, Iq.Stanza iq, Object o) {
|
private static void on_store_response(XmppStream stream, Iq.Stanza iq, Object? o) {
|
||||||
Tuple<OnSuccess, Object> tuple = o as Tuple<OnSuccess, Object>;
|
Tuple<OnSuccess, Object> tuple = o as Tuple<OnSuccess, Object>;
|
||||||
tuple.a(stream, tuple.b);
|
tuple.a(stream, tuple.b);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void on_retrieve_response(XmppStream stream, Iq.Stanza iq, Object o) {
|
private static void on_retrieve_response(XmppStream stream, Iq.Stanza iq, Object? o) {
|
||||||
Tuple<OnResponse, Object> tuple = o as Tuple<OnResponse, Object>;
|
Tuple<OnResponse, Object> tuple = o as Tuple<OnResponse, Object>;
|
||||||
tuple.a(stream, iq.stanza.get_subnode("query", NS_URI), tuple.b);
|
tuple.a(stream, iq.stanza.get_subnode("query", NS_URI), tuple.b);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ namespace Xmpp.Xep.Pubsub {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void on_received_request_response(XmppStream stream, Iq.Stanza iq, Object o) {
|
private static void on_received_request_response(XmppStream stream, Iq.Stanza iq, Object? o) {
|
||||||
Tuple<OnResult, Object?> tuple = o as Tuple<OnResult, Object?>;
|
Tuple<OnResult, Object?> tuple = o as Tuple<OnResult, Object?>;
|
||||||
OnResult on_result = tuple.a;
|
OnResult on_result = tuple.a;
|
||||||
StanzaNode event_node = iq.stanza.get_subnode("pubsub", NS_URI);
|
StanzaNode event_node = iq.stanza.get_subnode("pubsub", NS_URI);
|
||||||
|
|
|
@ -8,6 +8,17 @@ namespace Xmpp.Xep.MessageDeliveryReceipts {
|
||||||
|
|
||||||
public signal void receipt_received(XmppStream stream, string jid, string id);
|
public signal void receipt_received(XmppStream stream, string jid, string id);
|
||||||
|
|
||||||
|
public void send_received(XmppStream stream, string from, string message_id) {
|
||||||
|
Message.Stanza received_message = new Message.Stanza();
|
||||||
|
received_message.to = from;
|
||||||
|
received_message.stanza.put_node(new StanzaNode.build("received", NS_URI).add_self_xmlns().put_attribute("id", message_id));
|
||||||
|
stream.get_module(Message.Module.IDENTITY).send_message(stream, received_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool requests_receipt(Message.Stanza message) {
|
||||||
|
return message.stanza.get_subnode("request", NS_URI) != null;
|
||||||
|
}
|
||||||
|
|
||||||
public override void attach(XmppStream stream) {
|
public override void attach(XmppStream stream) {
|
||||||
ServiceDiscovery.Module.require(stream);
|
ServiceDiscovery.Module.require(stream);
|
||||||
Message.Module.require(stream);
|
Message.Module.require(stream);
|
||||||
|
@ -33,18 +44,9 @@ namespace Xmpp.Xep.MessageDeliveryReceipts {
|
||||||
StanzaNode? received_node = message.stanza.get_subnode("received", NS_URI);
|
StanzaNode? received_node = message.stanza.get_subnode("received", NS_URI);
|
||||||
if (received_node != null) {
|
if (received_node != null) {
|
||||||
receipt_received(stream, message.from, received_node.get_attribute("id", NS_URI));
|
receipt_received(stream, message.from, received_node.get_attribute("id", NS_URI));
|
||||||
} else if (message.stanza.get_subnode("request", NS_URI) != null) {
|
|
||||||
send_received(stream, message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void send_received(XmppStream stream, Message.Stanza message) {
|
|
||||||
Message.Stanza received_message = new Message.Stanza();
|
|
||||||
received_message.to = message.from;
|
|
||||||
received_message.stanza.put_node(new StanzaNode.build("received", NS_URI).add_self_xmlns().put_attribute("id", message.id));
|
|
||||||
stream.get_module(Message.Module.IDENTITY).send_message(stream, received_message);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void pre_send_message(XmppStream stream, Message.Stanza message) {
|
private void pre_send_message(XmppStream stream, Message.Stanza message) {
|
||||||
StanzaNode? received_node = message.stanza.get_subnode("received", NS_URI);
|
StanzaNode? received_node = message.stanza.get_subnode("received", NS_URI);
|
||||||
if (received_node != null) return;
|
if (received_node != null) return;
|
||||||
|
|
|
@ -48,7 +48,6 @@ namespace Xmpp.Xep.MessageCarbons {
|
||||||
if (forwarded_node != null) {
|
if (forwarded_node != null) {
|
||||||
StanzaNode? message_node = forwarded_node.get_subnode("message", Message.NS_URI);
|
StanzaNode? message_node = forwarded_node.get_subnode("message", Message.NS_URI);
|
||||||
string? from_attribute = message_node.get_attribute("from", Message.NS_URI);
|
string? from_attribute = message_node.get_attribute("from", Message.NS_URI);
|
||||||
// The security model assumed by this document is that all of the resources for a single user are in the same trust boundary.
|
|
||||||
// Any forwarded copies received by a Carbons-enabled client MUST be from that user's bare JID; any copies that do not meet this requirement MUST be ignored.
|
// Any forwarded copies received by a Carbons-enabled client MUST be from that user's bare JID; any copies that do not meet this requirement MUST be ignored.
|
||||||
if (from_attribute != null && from_attribute == get_bare_jid(stream.get_flag(Bind.Flag.IDENTITY).my_jid)) {
|
if (from_attribute != null && from_attribute == get_bare_jid(stream.get_flag(Bind.Flag.IDENTITY).my_jid)) {
|
||||||
if (received_node != null) {
|
if (received_node != null) {
|
||||||
|
|
|
@ -53,10 +53,6 @@ public class Module : XmppStreamModule {
|
||||||
|
|
||||||
private void on_received_message(XmppStream stream, Message.Stanza message) {
|
private void on_received_message(XmppStream stream, Message.Stanza message) {
|
||||||
if (message.type_ != Message.Stanza.TYPE_CHAT) return;
|
if (message.type_ != Message.Stanza.TYPE_CHAT) return;
|
||||||
if (requests_marking(message)) {
|
|
||||||
send_marker(stream, message.from, message.id, message.type_, MARKER_RECEIVED);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Gee.List<StanzaNode> nodes = message.stanza.get_all_subnodes();
|
Gee.List<StanzaNode> nodes = message.stanza.get_all_subnodes();
|
||||||
foreach (StanzaNode node in nodes) {
|
foreach (StanzaNode node in nodes) {
|
||||||
if (node.ns_uri == NS_URI && node.name in MARKERS) {
|
if (node.ns_uri == NS_URI && node.name in MARKERS) {
|
||||||
|
|
Loading…
Reference in a new issue