Support replies and reactions to files
This commit is contained in:
parent
0c4aea96ff
commit
cb3b19b01d
|
@ -44,11 +44,8 @@ public class ContentItemStore : StreamInteractionModule, Object {
|
|||
Gee.TreeSet<ContentItem> items = new Gee.TreeSet<ContentItem>(ContentItem.compare_func);
|
||||
|
||||
foreach (var row in select) {
|
||||
int id = row[db.content_item.id];
|
||||
int content_type = row[db.content_item.content_type];
|
||||
int foreign_id = row[db.content_item.foreign_id];
|
||||
DateTime time = new DateTime.from_unix_utc(row[db.content_item.time]);
|
||||
items.add(get_item(conversation, id, content_type, foreign_id, time));
|
||||
ContentItem content_item = get_item_from_row(row, conversation);
|
||||
items.add(content_item);
|
||||
}
|
||||
|
||||
Gee.List<ContentItem> ret = new ArrayList<ContentItem>();
|
||||
|
@ -58,6 +55,14 @@ public class ContentItemStore : StreamInteractionModule, Object {
|
|||
return ret;
|
||||
}
|
||||
|
||||
private ContentItem get_item_from_row(Row row, Conversation conversation) throws Error {
|
||||
int id = row[db.content_item.id];
|
||||
int content_type = row[db.content_item.content_type];
|
||||
int foreign_id = row[db.content_item.foreign_id];
|
||||
DateTime time = new DateTime.from_unix_utc(row[db.content_item.time]);
|
||||
return get_item(conversation, id, content_type, foreign_id, time);
|
||||
}
|
||||
|
||||
private ContentItem get_item(Conversation conversation, int id, int content_type, int foreign_id, DateTime time) throws Error {
|
||||
switch (content_type) {
|
||||
case 1:
|
||||
|
@ -112,6 +117,86 @@ public class ContentItemStore : StreamInteractionModule, Object {
|
|||
return item.size > 0 ? item[0] : null;
|
||||
}
|
||||
|
||||
public string? get_message_id_for_content_item(Conversation conversation, ContentItem content_item) {
|
||||
Message? message = get_message_for_content_item(conversation, content_item);
|
||||
if (message == null) return null;
|
||||
|
||||
if (conversation.type_ == Conversation.Type.CHAT) {
|
||||
return message.stanza_id;
|
||||
} else {
|
||||
return message.server_id;
|
||||
}
|
||||
}
|
||||
|
||||
public Jid? get_message_sender_for_content_item(Conversation conversation, ContentItem content_item) {
|
||||
Message? message = get_message_for_content_item(conversation, content_item);
|
||||
if (message == null) return null;
|
||||
return message.from;
|
||||
}
|
||||
|
||||
private Message? get_message_for_content_item(Conversation conversation, ContentItem content_item) {
|
||||
FileItem? file_item = content_item as FileItem;
|
||||
if (file_item != null) {
|
||||
if (file_item.file_transfer.provider != 0 || file_item.file_transfer.info == null) return null;
|
||||
|
||||
int message_db_id = int.parse(file_item.file_transfer.info);
|
||||
return stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_id(message_db_id, conversation);
|
||||
}
|
||||
MessageItem? message_item = content_item as MessageItem;
|
||||
if (message_item != null) {
|
||||
return message_item.message;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ContentItem? get_content_item_for_message_id(Conversation conversation, string message_id) {
|
||||
Row? row = get_content_item_row_for_message_id(conversation, message_id);
|
||||
if (row != null) {
|
||||
return get_item_from_row(row, conversation);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int get_content_item_id_for_message_id(Conversation conversation, string message_id) {
|
||||
Row? row = get_content_item_row_for_message_id(conversation, message_id);
|
||||
if (row != null) {
|
||||
return row[db.content_item.id];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private Row? get_content_item_row_for_message_id(Conversation conversation, string message_id) {
|
||||
var content_item_row = db.content_item.select();
|
||||
|
||||
Message? message = null;
|
||||
if (conversation.type_ == Conversation.Type.CHAT) {
|
||||
message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_stanza_id(message_id, conversation);
|
||||
} else {
|
||||
message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_server_id(message_id, conversation);
|
||||
}
|
||||
if (message == null) return null;
|
||||
|
||||
RowOption file_transfer_row = db.file_transfer.select()
|
||||
.with(db.file_transfer.account_id, "=", conversation.account.id)
|
||||
.with(db.file_transfer.counterpart_id, "=", db.get_jid_id(conversation.counterpart))
|
||||
.with(db.file_transfer.info, "=", message.id.to_string())
|
||||
.order_by(db.file_transfer.time, "DESC")
|
||||
.single().row();
|
||||
|
||||
if (file_transfer_row.is_present()) {
|
||||
content_item_row.with(db.content_item.foreign_id, "=", file_transfer_row[db.file_transfer.id])
|
||||
.with(db.content_item.content_type, "=", 2);
|
||||
} else {
|
||||
content_item_row.with(db.content_item.foreign_id, "=", message.id)
|
||||
.with(db.content_item.content_type, "=", 1);
|
||||
}
|
||||
RowOption content_item_row_option = content_item_row.single().row();
|
||||
if (content_item_row_option.is_present()) {
|
||||
return content_item_row_option.inner;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ContentItem? get_latest(Conversation conversation) {
|
||||
Gee.List<ContentItem> items = get_n_latest(conversation, 1);
|
||||
if (items.size > 0) {
|
||||
|
|
|
@ -425,24 +425,8 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
|||
new_message.type_ = MessageStanza.TYPE_CHAT;
|
||||
}
|
||||
|
||||
if (message.quoted_item_id > 0) {
|
||||
ContentItem? content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_item_by_id(conversation, message.quoted_item_id);
|
||||
if (content_item != null && content_item.type_ == MessageItem.TYPE) {
|
||||
Message? quoted_message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_id(((MessageItem) content_item).message.id, conversation);
|
||||
if (quoted_message != null) {
|
||||
Xep.Replies.set_reply_to(new_message, new Xep.Replies.ReplyTo(quoted_message.from, quoted_message.stanza_id));
|
||||
|
||||
string body_with_fallback = "> " + Dino.message_body_without_reply_fallback(quoted_message);
|
||||
body_with_fallback = body_with_fallback.replace("\n", "\n> ");
|
||||
body_with_fallback += "\n";
|
||||
long fallback_length = body_with_fallback.length;
|
||||
body_with_fallback += message.body;
|
||||
new_message.body = body_with_fallback;
|
||||
var fallback_location = new Xep.FallbackIndication.FallbackLocation(0, (int)fallback_length);
|
||||
Xep.FallbackIndication.set_fallback(new_message, new Xep.FallbackIndication.Fallback(Xep.Replies.NS_URI, new Xep.FallbackIndication.FallbackLocation[] { fallback_location }));
|
||||
}
|
||||
}
|
||||
}
|
||||
string? fallback = get_fallback_body_set_infos(message, new_message, conversation);
|
||||
new_message.body = fallback == null ? message.body : fallback + message.body;
|
||||
|
||||
build_message_stanza(message, new_message, conversation);
|
||||
pre_message_send(message, new_message, conversation);
|
||||
|
@ -487,6 +471,37 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
public string? get_fallback_body_set_infos(Entities.Message message, MessageStanza new_stanza, Conversation conversation) {
|
||||
if (message.quoted_item_id == 0) return null;
|
||||
|
||||
ContentItem? content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_item_by_id(conversation, message.quoted_item_id);
|
||||
if (content_item == null) return null;
|
||||
|
||||
Jid? quoted_sender = stream_interactor.get_module(ContentItemStore.IDENTITY).get_message_sender_for_content_item(conversation, content_item);
|
||||
string? quoted_stanza_id = stream_interactor.get_module(ContentItemStore.IDENTITY).get_message_id_for_content_item(conversation, content_item);
|
||||
if (quoted_sender != null && quoted_stanza_id != null) {
|
||||
Xep.Replies.set_reply_to(new_stanza, new Xep.Replies.ReplyTo(quoted_sender, quoted_stanza_id));
|
||||
}
|
||||
|
||||
string fallback = "> ";
|
||||
|
||||
if (content_item.type_ == MessageItem.TYPE) {
|
||||
Message? quoted_message = ((MessageItem) content_item).message;
|
||||
fallback += Dino.message_body_without_reply_fallback(quoted_message);
|
||||
fallback = fallback.replace("\n", "\n> ");
|
||||
} else if (content_item.type_ == FileItem.TYPE) {
|
||||
FileTransfer? quoted_file = ((FileItem) content_item).file_transfer;
|
||||
fallback += quoted_file.file_name;
|
||||
}
|
||||
fallback += "\n";
|
||||
|
||||
long fallback_length = fallback.length;
|
||||
var fallback_location = new Xep.FallbackIndication.FallbackLocation(0, (int)fallback_length);
|
||||
Xep.FallbackIndication.set_fallback(new_stanza, new Xep.FallbackIndication.Fallback(Xep.Replies.NS_URI, new Xep.FallbackIndication.FallbackLocation[] { fallback_location }));
|
||||
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class MessageListener : Xmpp.OrderedListener {
|
||||
|
|
|
@ -116,9 +116,7 @@ public class MessageStorage : StreamInteractionModule, Object {
|
|||
.outer_join_with(db.message_correction, db.message_correction.message_id, db.message.id)
|
||||
.outer_join_with(db.reply, db.reply.message_id, db.message.id);
|
||||
|
||||
if (conversation.counterpart.resourcepart == null) {
|
||||
query.with_null(db.message.counterpart_resource);
|
||||
} else {
|
||||
if (conversation.counterpart.resourcepart != null) {
|
||||
query.with(db.message.counterpart_resource, "=", conversation.counterpart.resourcepart);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ public class Dino.Reactions : StreamInteractionModule, Object {
|
|||
public string id { get { return IDENTITY.id; } }
|
||||
|
||||
public signal void reaction_added(Account account, int content_item_id, Jid jid, string reaction);
|
||||
// [Signal(detailed=true)]
|
||||
public signal void reaction_removed(Account account, int content_item_id, Jid jid, string reaction);
|
||||
|
||||
private StreamInteractor stream_interactor;
|
||||
|
@ -35,15 +34,19 @@ public class Dino.Reactions : StreamInteractionModule, Object {
|
|||
if (!reactions.contains(reaction)) {
|
||||
reactions.add(reaction);
|
||||
}
|
||||
try {
|
||||
send_reactions(conversation, content_item, reactions);
|
||||
reaction_added(conversation.account, content_item.id, conversation.account.bare_jid, reaction);
|
||||
} catch (SendError e) {}
|
||||
}
|
||||
|
||||
public void remove_reaction(Conversation conversation, ContentItem content_item, string reaction) {
|
||||
Gee.List<string> reactions = get_own_reactions(conversation, content_item);
|
||||
reactions.remove(reaction);
|
||||
try {
|
||||
send_reactions(conversation, content_item, reactions);
|
||||
reaction_removed(conversation.account, content_item.id, conversation.account.bare_jid, reaction);
|
||||
} catch (SendError e) {}
|
||||
}
|
||||
|
||||
public Gee.List<ReactionUsers> get_item_reactions(Conversation conversation, ContentItem content_item) {
|
||||
|
@ -80,35 +83,28 @@ public class Dino.Reactions : StreamInteractionModule, Object {
|
|||
return false;
|
||||
}
|
||||
|
||||
private void send_reactions(Conversation conversation, ContentItem content_item, Gee.List<string> reactions) {
|
||||
Message? message = null;
|
||||
private void send_reactions(Conversation conversation, ContentItem content_item, Gee.List<string> reactions) throws SendError {
|
||||
string? message_id = stream_interactor.get_module(ContentItemStore.IDENTITY).get_message_id_for_content_item(conversation, content_item);
|
||||
if (message_id == null) throw new SendError.Misc("No message for content_item");
|
||||
|
||||
FileItem? file_item = content_item as FileItem;
|
||||
if (file_item != null) {
|
||||
int message_id = int.parse(file_item.file_transfer.info);
|
||||
message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_id(message_id, conversation);
|
||||
}
|
||||
MessageItem? message_item = content_item as MessageItem;
|
||||
if (message_item != null) {
|
||||
message = message_item.message;
|
||||
}
|
||||
XmppStream? stream = stream_interactor.get_stream(conversation.account);
|
||||
if (stream == null) throw new SendError.NoStream("");
|
||||
|
||||
if (message == null) {
|
||||
return;
|
||||
}
|
||||
var reactions_module = stream.get_module(Xmpp.Xep.Reactions.Module.IDENTITY);
|
||||
|
||||
XmppStream stream = stream_interactor.get_stream(conversation.account);
|
||||
if (conversation.type_ == Conversation.Type.GROUPCHAT || conversation.type_ == Conversation.Type.GROUPCHAT_PM) {
|
||||
if (conversation.type_ == Conversation.Type.GROUPCHAT) {
|
||||
stream.get_module(Xmpp.Xep.Reactions.Module.IDENTITY).send_reaction(stream, conversation.counterpart, "groupchat", message.server_id ?? message.stanza_id, reactions);
|
||||
} else if (conversation.type_ == Conversation.Type.GROUPCHAT_PM) {
|
||||
stream.get_module(Xmpp.Xep.Reactions.Module.IDENTITY).send_reaction(stream, conversation.counterpart, "chat", message.server_id ?? message.stanza_id, reactions);
|
||||
}
|
||||
reactions_module.send_reaction.begin(stream, conversation.counterpart, "groupchat", message_id, reactions);
|
||||
// We save the reaction when it gets reflected back to us
|
||||
} else if (conversation.type_ == Conversation.Type.GROUPCHAT_PM) {
|
||||
reactions_module.send_reaction(stream, conversation.counterpart, "chat", message_id, reactions);
|
||||
} else if (conversation.type_ == Conversation.Type.CHAT) {
|
||||
stream.get_module(Xmpp.Xep.Reactions.Module.IDENTITY).send_reaction(stream, conversation.counterpart, "chat", message.stanza_id, reactions);
|
||||
int64 now_millis = GLib.get_real_time () / 1000;
|
||||
reactions_module.send_reaction.begin(stream, conversation.counterpart, "chat", message_id, reactions, (_, res) => {
|
||||
try {
|
||||
reactions_module.send_reaction.end(res);
|
||||
save_chat_reactions(conversation.account, conversation.account.bare_jid, content_item.id, now_millis, reactions);
|
||||
} catch (SendError e) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,11 +247,11 @@ public class Dino.Reactions : StreamInteractionModule, Object {
|
|||
Message reaction_message = yield stream_interactor.get_module(MessageProcessor.IDENTITY).parse_message_stanza(account, stanza);
|
||||
Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation_for_message(reaction_message);
|
||||
|
||||
Message? message = get_message_for_reaction(conversation, message_id);
|
||||
int content_item_id = stream_interactor.get_module(ContentItemStore.IDENTITY).get_content_item_id_for_message_id(conversation, message_id);
|
||||
var reaction_info = new ReactionInfo() { account=account, from_jid=from_jid, reactions=reactions, stanza=stanza, received_time=new DateTime.now() };
|
||||
|
||||
if (message != null) {
|
||||
process_reaction_for_message(message.id, reaction_info);
|
||||
if (content_item_id != -1) {
|
||||
process_reaction_for_message(content_item_id, reaction_info);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -317,30 +313,12 @@ public class Dino.Reactions : StreamInteractionModule, Object {
|
|||
}
|
||||
}
|
||||
|
||||
private void process_reaction_for_message(int message_db_id, ReactionInfo reaction_info) {
|
||||
private void process_reaction_for_message(int content_item_id, ReactionInfo reaction_info) {
|
||||
Account account = reaction_info.account;
|
||||
MessageStanza stanza = reaction_info.stanza;
|
||||
Jid from_jid = reaction_info.from_jid;
|
||||
Gee.List<string> reactions = reaction_info.reactions;
|
||||
|
||||
RowOption file_transfer_row = db.file_transfer.select()
|
||||
.with(db.file_transfer.account_id, "=", account.id)
|
||||
.with(db.file_transfer.info, "=", message_db_id.to_string())
|
||||
.single().row(); // TODO better
|
||||
|
||||
var content_item_row = db.content_item.select();
|
||||
|
||||
if (file_transfer_row.is_present()) {
|
||||
content_item_row.with(db.content_item.foreign_id, "=", file_transfer_row[db.file_transfer.id])
|
||||
.with(db.content_item.content_type, "=", 2);
|
||||
} else {
|
||||
content_item_row.with(db.content_item.foreign_id, "=", message_db_id)
|
||||
.with(db.content_item.content_type, "=", 1);
|
||||
}
|
||||
var content_item_row_opt = content_item_row.single().row();
|
||||
if (!content_item_row_opt.is_present()) return;
|
||||
int content_item_id = content_item_row_opt[db.content_item.id];
|
||||
|
||||
// Get reaction time
|
||||
DateTime? reaction_time = null;
|
||||
DelayedDelivery.MessageFlag? delayed_message_flag = DelayedDelivery.MessageFlag.get_flag(stanza);
|
||||
|
|
|
@ -77,22 +77,7 @@ public class Dino.Replies : StreamInteractionModule, Object {
|
|||
Xep.Replies.ReplyTo? reply_to = Xep.Replies.get_reply_to(stanza);
|
||||
if (reply_to == null) return;
|
||||
|
||||
Message? quoted_message = null;
|
||||
if (conversation.type_ == Conversation.Type.GROUPCHAT) {
|
||||
quoted_message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_server_id(reply_to.to_message_id, conversation);
|
||||
} else {
|
||||
quoted_message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_stanza_id(reply_to.to_message_id, conversation);
|
||||
}
|
||||
if (quoted_message == null) {
|
||||
db.reply.upsert()
|
||||
.value(db.reply.message_id, message.id, true)
|
||||
.value(db.reply.quoted_message_stanza_id, reply_to.to_message_id)
|
||||
.value(db.reply.quoted_message_from, reply_to.to_jid.to_string())
|
||||
.perform();
|
||||
return;
|
||||
}
|
||||
|
||||
ContentItem? quoted_content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_item_by_foreign(conversation, 1, quoted_message.id);
|
||||
ContentItem? quoted_content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_content_item_for_message_id(conversation, reply_to.to_message_id);
|
||||
if (quoted_content_item == null) return;
|
||||
|
||||
set_message_is_reply_to(message, quoted_content_item);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Dino.Entities;
|
||||
using Qlite;
|
||||
|
||||
namespace Dino {
|
||||
|
||||
|
|
|
@ -10,19 +10,44 @@ namespace Dino.Ui {
|
|||
public class FileMetaItem : ConversationSummary.ContentMetaItem {
|
||||
|
||||
private StreamInteractor stream_interactor;
|
||||
private FileItem file_item;
|
||||
private FileTransfer file_transfer;
|
||||
|
||||
public FileMetaItem(ContentItem content_item, StreamInteractor stream_interactor) {
|
||||
base(content_item);
|
||||
this.stream_interactor = stream_interactor;
|
||||
this.file_item = content_item as FileItem;
|
||||
this.file_transfer = file_item.file_transfer;
|
||||
}
|
||||
|
||||
public override Object? get_widget(Plugins.ConversationItemWidgetInterface outer, Plugins.WidgetType type) {
|
||||
FileItem file_item = content_item as FileItem;
|
||||
FileTransfer transfer = file_item.file_transfer;
|
||||
return new FileWidget(stream_interactor, transfer);
|
||||
return new FileWidget(stream_interactor, file_transfer);
|
||||
}
|
||||
|
||||
public override Gee.List<Plugins.MessageAction>? get_item_actions(Plugins.WidgetType type) { return null; }
|
||||
public override Gee.List<Plugins.MessageAction>? get_item_actions(Plugins.WidgetType type) {
|
||||
if (file_transfer.provider != 0 || file_transfer.info == null) return null;
|
||||
|
||||
Gee.List<Plugins.MessageAction> actions = new ArrayList<Plugins.MessageAction>();
|
||||
|
||||
if (stream_interactor.get_module(ContentItemStore.IDENTITY).get_message_id_for_content_item(file_item.conversation, content_item) != null) {
|
||||
Plugins.MessageAction reply_action = new Plugins.MessageAction();
|
||||
reply_action.icon_name = "mail-reply-sender-symbolic";
|
||||
reply_action.callback = (button, content_meta_item_activated, widget) => {
|
||||
GLib.Application.get_default().activate_action("quote", new GLib.Variant.tuple(new GLib.Variant[] { new GLib.Variant.int32(file_item.conversation.id), new GLib.Variant.int32(content_item.id) }));
|
||||
};
|
||||
actions.add(reply_action);
|
||||
|
||||
Plugins.MessageAction action2 = new Plugins.MessageAction();
|
||||
action2.icon_name = "dino-emoticon-add-symbolic";
|
||||
EmojiChooser chooser = new EmojiChooser();
|
||||
chooser.emoji_picked.connect((emoji) => {
|
||||
stream_interactor.get_module(Reactions.IDENTITY).add_reaction(file_item.conversation, content_item, emoji);
|
||||
});
|
||||
action2.popover = chooser;
|
||||
actions.add(action2);
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
}
|
||||
|
||||
public class FileWidget : SizeRequestBox {
|
||||
|
|
|
@ -198,7 +198,7 @@ public class MessageMetaItem : ContentMetaItem {
|
|||
if (quoted_content_item != null) {
|
||||
var quote_model = new Quote.Model.from_content_item(quoted_content_item, message_item.conversation, stream_interactor);
|
||||
quote_model.jump_to.connect(() => {
|
||||
GLib.Application.get_default().activate_action("jump-to-conversation-message", new GLib.Variant.tuple(new GLib.Variant[] { new GLib.Variant.int32(message_item.conversation.id), new GLib.Variant.int32(message_item.id) }));
|
||||
GLib.Application.get_default().activate_action("jump-to-conversation-message", new GLib.Variant.tuple(new GLib.Variant[] { new GLib.Variant.int32(message_item.conversation.id), new GLib.Variant.int32(quoted_content_item.id) }));
|
||||
});
|
||||
var quote_widget = Quote.get_widget(quote_model);
|
||||
outer.set_widget(quote_widget, Plugins.WidgetType.GTK4, 1);
|
||||
|
@ -226,7 +226,7 @@ public class MessageMetaItem : ContentMetaItem {
|
|||
Plugins.MessageAction reply_action = new Plugins.MessageAction();
|
||||
reply_action.icon_name = "mail-reply-sender-symbolic";
|
||||
reply_action.callback = (button, content_meta_item_activated, widget) => {
|
||||
GLib.Application.get_default().activate_action("quote", new GLib.Variant.tuple(new GLib.Variant[] { new GLib.Variant.int32(message_item.conversation.id), new GLib.Variant.int32(message_item.id) }));
|
||||
GLib.Application.get_default().activate_action("quote", new GLib.Variant.tuple(new GLib.Variant[] { new GLib.Variant.int32(message_item.conversation.id), new GLib.Variant.int32(content_item.id) }));
|
||||
};
|
||||
actions.add(reply_action);
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@ namespace Dino.Ui.Quote {
|
|||
var message = ((MessageItem) content_item).message;
|
||||
this.message = Dino.message_body_without_reply_fallback(message);
|
||||
} else if (content_item.type_ == FileItem.TYPE) {
|
||||
this.message = "[File]";
|
||||
var file_transfer = ((FileItem) content_item).file_transfer;
|
||||
this.message = _("File") + ": " + file_transfer.file_name;
|
||||
}
|
||||
this.message_time = content_item.time;
|
||||
|
||||
|
|
|
@ -17,7 +17,11 @@ namespace Xmpp {
|
|||
|
||||
public async void send_message(XmppStream stream, MessageStanza message) throws IOStreamError {
|
||||
yield send_pipeline.run(stream, message);
|
||||
try {
|
||||
yield stream.write_async(message.stanza);
|
||||
} catch (IOStreamError e) {
|
||||
throw new SendError.IO(e.message);
|
||||
}
|
||||
}
|
||||
|
||||
public async void received_message_stanza_async(XmppStream stream, StanzaNode node) {
|
||||
|
|
|
@ -11,7 +11,7 @@ public class Module : XmppStreamModule {
|
|||
|
||||
private ReceivedPipelineListener received_pipeline_listener = new ReceivedPipelineListener();
|
||||
|
||||
public void send_reaction(XmppStream stream, Jid jid, string stanza_type, string message_id, Gee.List<string> reactions) {
|
||||
public async void send_reaction(XmppStream stream, Jid jid, string stanza_type, string message_id, Gee.List<string> reactions) throws SendError {
|
||||
StanzaNode reactions_node = new StanzaNode.build("reactions", NS_URI).add_self_xmlns();
|
||||
reactions_node.put_attribute("id", message_id);
|
||||
foreach (string reaction in reactions) {
|
||||
|
@ -25,7 +25,7 @@ public class Module : XmppStreamModule {
|
|||
|
||||
MessageProcessingHints.set_message_hint(message, MessageProcessingHints.HINT_STORE);
|
||||
|
||||
stream.get_module(MessageModule.IDENTITY).send_message.begin(stream, message);
|
||||
yield stream.get_module(MessageModule.IDENTITY).send_message(stream, message);
|
||||
}
|
||||
|
||||
public override void attach(XmppStream stream) {
|
||||
|
|
|
@ -38,3 +38,11 @@ public long from_hex(string numeral) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Xmpp {
|
||||
public errordomain SendError {
|
||||
IO,
|
||||
NoStream,
|
||||
Misc
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue