197 lines
6.8 KiB
Vala
197 lines
6.8 KiB
Vala
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 don’t 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.local_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();
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|