dino/libdino/src/entity/message.vala

197 lines
6.8 KiB
Vala
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Gee;
using Xmpp;
namespace Dino.Entities {
public class Message : Object {
public const bool DIRECTION_SENT = true;
public const bool DIRECTION_RECEIVED = false;
public enum Marked {
NONE,
RECEIVED,
READ,
ACKNOWLEDGED,
UNSENT,
WONTSEND
}
public enum Type {
ERROR,
CHAT,
GROUPCHAT,
GROUPCHAT_PM,
UNKNOWN
}
public int id { get; set; default = -1; }
public Account account { get; set; }
public Jid? counterpart { get; set; }
public Jid? ourpart { get; set; }
public Jid? from {
get { return direction == DIRECTION_SENT ? ourpart : counterpart; }
}
public Jid? to {
get { return direction == DIRECTION_SENT ? counterpart : ourpart; }
}
public bool direction { get; set; }
public Jid? real_jid { get; set; }
public Type type_ { get; set; default = Type.UNKNOWN; }
public string? body { get; set; }
public string? stanza_id { get; set; }
public DateTime? time { get; set; }
/** UTC **/
public DateTime? local_time { get; set; }
public Encryption encryption { get; set; default = Encryption.NONE; }
private Marked marked_ = Marked.NONE;
public Marked marked {
get { return marked_; }
set {
if (value == Marked.RECEIVED && marked == Marked.READ) return;
marked_ = value;
}
}
public Xmpp.MessageStanza stanza { get; set; }
private Database? db;
public Message(string? body) {
this.body = body;
}
public Message.from_row(Database db, Qlite.Row row) {
this.db = db;
id = row[db.message.id];
account = db.get_account_by_id(row[db.message.account_id]); // TODO dont have to generate acc new
stanza_id = row[db.message.stanza_id];
type_ = (Message.Type) row[db.message.type_];
counterpart = Jid.parse(db.get_jid_by_id(row[db.message.counterpart_id]));
string counterpart_resource = row[db.message.counterpart_resource];
if (counterpart_resource != null) counterpart = counterpart.with_resource(counterpart_resource);
string our_resource = row[db.message.our_resource];
if (type_ == Type.GROUPCHAT && our_resource != null) {
ourpart = counterpart.with_resource(our_resource);
} else if (our_resource != null) {
ourpart = account.bare_jid.with_resource(our_resource);
} else {
ourpart = account.bare_jid;
}
direction = row[db.message.direction];
time = new DateTime.from_unix_utc(row[db.message.time]);
local_time = new DateTime.from_unix_utc(row[db.message.time]);
body = row[db.message.body];
marked = (Message.Marked) row[db.message.marked];
encryption = (Encryption) row[db.message.encryption];
string? real_jid_str = db.real_jid.select({db.real_jid.real_jid}).with(db.real_jid.message_id, "=", id)[db.real_jid.real_jid];
if (real_jid_str != null) real_jid = new Jid(real_jid_str);
notify.connect(on_update);
}
public void persist(Database db) {
if (id != -1) return;
this.db = db;
Qlite.InsertBuilder builder = db.message.insert()
.value(db.message.account_id, account.id)
.value(db.message.counterpart_id, db.get_jid_id(counterpart))
.value(db.message.counterpart_resource, counterpart.resourcepart)
.value(db.message.our_resource, ourpart.resourcepart)
.value(db.message.direction, direction)
.value(db.message.type_, type_)
.value(db.message.time, (long) time.to_unix())
.value(db.message.local_time, (long) local_time.to_unix())
.value(db.message.body, body)
.value(db.message.encryption, encryption)
.value(db.message.marked, marked);
if (stanza_id != null) builder.value(db.message.stanza_id, stanza_id);
id = (int) builder.perform();
if (real_jid != null) {
db.real_jid.insert()
.value(db.real_jid.message_id, id)
.value(db.real_jid.real_jid, real_jid.to_string())
.perform();
}
notify.connect(on_update);
}
public void set_type_string(string type) {
switch (type) {
case Xmpp.MessageStanza.TYPE_CHAT:
type_ = Type.CHAT; break;
case Xmpp.MessageStanza.TYPE_GROUPCHAT:
type_ = Type.GROUPCHAT; break;
}
}
public new string get_type_string() {
switch (type_) {
case Type.CHAT:
return Xmpp.MessageStanza.TYPE_CHAT;
case Type.GROUPCHAT:
return Xmpp.MessageStanza.TYPE_GROUPCHAT;
default:
return Xmpp.MessageStanza.TYPE_NORMAL;
}
}
public bool equals(Message? m) {
if (m == null) return false;
return equals_func(this, m);
}
public static bool equals_func(Message m1, Message m2) {
if (m1.stanza_id == m2.stanza_id &&
m1.body == m2.body) {
return true;
}
return false;
}
public static uint hash_func(Message message) {
return message.body.hash();
}
private void on_update(Object o, ParamSpec sp) {
Qlite.UpdateBuilder update_builder = db.message.update().with(db.message.id, "=", id);
switch (sp.name) {
case "stanza-id":
update_builder.set(db.message.stanza_id, stanza_id); break;
case "counterpart":
update_builder.set(db.message.counterpart_id, db.get_jid_id(counterpart));
update_builder.set(db.message.counterpart_resource, counterpart.resourcepart); break;
case "ourpart":
update_builder.set(db.message.our_resource, ourpart.resourcepart); break;
case "direction":
update_builder.set(db.message.direction, direction); break;
case "type-":
update_builder.set(db.message.type_, type_); break;
case "time":
update_builder.set(db.message.time, (long) time.to_unix()); break;
case "local-time":
update_builder.set(db.message.local_time, (long) local_time.to_unix()); break;
case "body":
update_builder.set(db.message.body, body); break;
case "encryption":
update_builder.set(db.message.encryption, encryption); break;
case "marked":
update_builder.set(db.message.marked, marked); break;
}
update_builder.perform();
if (sp.get_name() == "real-jid") {
db.real_jid.insert().or("REPLACE")
.value(db.real_jid.message_id, id)
.value(db.real_jid.real_jid, real_jid.to_string())
.perform();
}
}
}
}