Notifications + typing notifications + message marker settings per conversation
This commit is contained in:
parent
3a8df2069e
commit
387433ebb9
|
@ -1,9 +1,19 @@
|
||||||
<schemalist>
|
<schemalist>
|
||||||
<schema id="org.dino-im" path="/org/dino-im/" gettext-domain="dino">
|
<schema id="org.dino-im" path="/org/dino-im/" gettext-domain="dino">
|
||||||
|
|
||||||
<key name="send-read" type="b">
|
<key name="send-typing" type="b">
|
||||||
<default>true</default>
|
<default>true</default>
|
||||||
<summary>Whether to confirm that a message was received per default</summary>
|
<summary>Whether to send typing notifications</summary>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="send-marker" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Whether to confirm that a message was received or read</summary>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="notifications" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Whether to get notifications</summary>
|
||||||
</key>
|
</key>
|
||||||
|
|
||||||
<key name="convert-utf8-smileys" type="b">
|
<key name="convert-utf8-smileys" type="b">
|
||||||
|
|
|
@ -28,6 +28,14 @@ public class Conversation : Object {
|
||||||
public Type type_ { get; set; }
|
public Type type_ { get; set; }
|
||||||
public Message read_up_to { get; set; }
|
public Message read_up_to { get; set; }
|
||||||
|
|
||||||
|
public enum NotifySetting { DEFAULT, ON, OFF, HIGHLIGHT }
|
||||||
|
public NotifySetting notify_setting { get; set; default = NotifySetting.DEFAULT; }
|
||||||
|
|
||||||
|
public enum Setting { DEFAULT, ON, OFF }
|
||||||
|
public Setting send_typing { get; set; default = Setting.DEFAULT; }
|
||||||
|
|
||||||
|
public Setting send_marker { get; set; default = Setting.DEFAULT; }
|
||||||
|
|
||||||
private Database? db;
|
private Database? db;
|
||||||
|
|
||||||
public Conversation(Jid jid, Account account, Type type) {
|
public Conversation(Jid jid, Account account, Type type) {
|
||||||
|
@ -51,6 +59,9 @@ public class Conversation : Object {
|
||||||
encryption = (Encryption) row[db.conversation.encryption];
|
encryption = (Encryption) row[db.conversation.encryption];
|
||||||
int? read_up_to = row[db.conversation.read_up_to];
|
int? read_up_to = row[db.conversation.read_up_to];
|
||||||
if (read_up_to != null) this.read_up_to = db.get_message_by_id(read_up_to);
|
if (read_up_to != null) this.read_up_to = db.get_message_by_id(read_up_to);
|
||||||
|
notify_setting = (NotifySetting) row[db.conversation.notification];
|
||||||
|
send_typing = (Setting) row[db.conversation.send_typing];
|
||||||
|
send_marker = (Setting) row[db.conversation.send_marker];
|
||||||
|
|
||||||
notify.connect(on_update);
|
notify.connect(on_update);
|
||||||
}
|
}
|
||||||
|
@ -62,7 +73,7 @@ public class Conversation : Object {
|
||||||
.value(db.conversation.jid_id, db.get_jid_id(counterpart))
|
.value(db.conversation.jid_id, db.get_jid_id(counterpart))
|
||||||
.value(db.conversation.type_, type_)
|
.value(db.conversation.type_, type_)
|
||||||
.value(db.conversation.encryption, encryption)
|
.value(db.conversation.encryption, encryption)
|
||||||
//.value(conversation.read_up_to, new_conversation.read_up_to)
|
.value(db.conversation.read_up_to, read_up_to.id)
|
||||||
.value(db.conversation.active, active);
|
.value(db.conversation.active, active);
|
||||||
if (counterpart.is_full()) {
|
if (counterpart.is_full()) {
|
||||||
insert.value(db.conversation.resource, counterpart.resourcepart);
|
insert.value(db.conversation.resource, counterpart.resourcepart);
|
||||||
|
@ -70,10 +81,35 @@ public class Conversation : Object {
|
||||||
if (last_active != null) {
|
if (last_active != null) {
|
||||||
insert.value(db.conversation.last_active, (long) last_active.to_unix());
|
insert.value(db.conversation.last_active, (long) last_active.to_unix());
|
||||||
}
|
}
|
||||||
|
insert.value(db.conversation.notification, notify_setting);
|
||||||
|
insert.value(db.conversation.send_typing, send_typing);
|
||||||
|
insert.value(db.conversation.send_marker, send_marker);
|
||||||
id = (int) insert.perform();
|
id = (int) insert.perform();
|
||||||
notify.connect(on_update);
|
notify.connect(on_update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NotifySetting get_notification_setting(StreamInteractor stream_interactor) {
|
||||||
|
Xmpp.Core.XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
|
if (notify_setting != NotifySetting.DEFAULT) return notify_setting;
|
||||||
|
if (!Settings.instance().notifications) return NotifySetting.OFF;
|
||||||
|
if (type_ == Type.GROUPCHAT) {
|
||||||
|
bool members_only = stream.get_flag(Xmpp.Xep.Muc.Flag.IDENTITY).has_room_feature(counterpart.bare_jid.to_string(), Xmpp.Xep.Muc.Feature.MEMBERS_ONLY);
|
||||||
|
return members_only ? NotifySetting.ON : NotifySetting.HIGHLIGHT;
|
||||||
|
} else {
|
||||||
|
return NotifySetting.ON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Setting get_send_typing_setting() {
|
||||||
|
if (send_typing != Setting.DEFAULT) return send_typing;
|
||||||
|
return Settings.instance().send_typing ? Setting.ON : Setting.OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Setting get_send_marker_setting() {
|
||||||
|
if (send_marker != Setting.DEFAULT) return send_marker;
|
||||||
|
return Settings.instance().send_marker ? Setting.ON : Setting.OFF;
|
||||||
|
}
|
||||||
|
|
||||||
public bool equals(Conversation? conversation) {
|
public bool equals(Conversation? conversation) {
|
||||||
if (conversation == null) return false;
|
if (conversation == null) return false;
|
||||||
return equals_func(this, conversation);
|
return equals_func(this, conversation);
|
||||||
|
@ -110,6 +146,12 @@ public class Conversation : Object {
|
||||||
update.set_null(db.conversation.last_active);
|
update.set_null(db.conversation.last_active);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "notify-setting":
|
||||||
|
update.set(db.conversation.notification, notify_setting); break;
|
||||||
|
case "send-typing":
|
||||||
|
update.set(db.conversation.send_typing, send_typing); break;
|
||||||
|
case "send-marker":
|
||||||
|
update.set(db.conversation.send_marker, send_marker); break;
|
||||||
}
|
}
|
||||||
update.perform();
|
update.perform();
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ public class ChatInteraction : StreamInteractionModule, Object {
|
||||||
|
|
||||||
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_read &&
|
if (stream != null && Settings.instance().send_marker &&
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ public class ChatInteraction : StreamInteractionModule, Object {
|
||||||
|
|
||||||
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_read &&
|
if (stream != null && Settings.instance().send_typing &&
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ using Dino.Entities;
|
||||||
namespace Dino {
|
namespace Dino {
|
||||||
|
|
||||||
public class Database : Qlite.Database {
|
public class Database : Qlite.Database {
|
||||||
private const int VERSION = 2;
|
private const int VERSION = 3;
|
||||||
|
|
||||||
public class AccountTable : Table {
|
public class AccountTable : Table {
|
||||||
public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true };
|
public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true };
|
||||||
|
@ -86,10 +86,13 @@ public class Database : Qlite.Database {
|
||||||
public Column<int> type_ = new Column.Integer("type");
|
public Column<int> type_ = new Column.Integer("type");
|
||||||
public Column<int> encryption = new Column.Integer("encryption");
|
public Column<int> encryption = new Column.Integer("encryption");
|
||||||
public Column<int> read_up_to = new Column.Integer("read_up_to");
|
public Column<int> read_up_to = new Column.Integer("read_up_to");
|
||||||
|
public Column<int> notification = new Column.Integer("notification") { min_version=3 };
|
||||||
|
public Column<int> send_typing = new Column.Integer("send_typing") { min_version=3 };
|
||||||
|
public Column<int> send_marker = new Column.Integer("send_marker") { min_version=3 };
|
||||||
|
|
||||||
internal ConversationTable(Database db) {
|
internal ConversationTable(Database db) {
|
||||||
base(db, "conversation");
|
base(db, "conversation");
|
||||||
init({id, account_id, jid_id, resource, active, last_active, type_, encryption, read_up_to});
|
init({id, account_id, jid_id, resource, active, last_active, type_, encryption, read_up_to, notification, send_typing, send_marker});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,19 @@ public class Settings {
|
||||||
|
|
||||||
private GLib.Settings gsettings;
|
private GLib.Settings gsettings;
|
||||||
|
|
||||||
public bool send_read {
|
public bool send_typing {
|
||||||
get { return gsettings.get_boolean("send-read"); }
|
get { return gsettings.get_boolean("send-typing"); }
|
||||||
set { gsettings.set_boolean("send-read", value); }
|
set { gsettings.set_boolean("send-typing", value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool send_marker {
|
||||||
|
get { return gsettings.get_boolean("send-marker"); }
|
||||||
|
set { gsettings.set_boolean("send-marker", value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool notifications {
|
||||||
|
get { return gsettings.get_boolean("notifications"); }
|
||||||
|
set { gsettings.set_boolean("notifications", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool convert_utf8_smileys {
|
public bool convert_utf8_smileys {
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
<property name="row-spacing">10</property>
|
<property name="row-spacing">10</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckButton" id="marker_checkbutton">
|
<object class="GtkCheckButton" id="typing_checkbutton">
|
||||||
<property name="label" translatable="yes">Send typing notifications and message marker</property>
|
<property name="label" translatable="yes">Send typing notifications</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
|
@ -29,6 +29,30 @@
|
||||||
<property name="height">1</property>
|
<property name="height">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCheckButton" id="marker_checkbutton">
|
||||||
|
<property name="label" translatable="yes">Send message marker</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
<property name="width">1</property>
|
||||||
|
<property name="height">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCheckButton" id="notification_checkbutton">
|
||||||
|
<property name="label" translatable="yes">Notify when a new message arrives</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">2</property>
|
||||||
|
<property name="width">1</property>
|
||||||
|
<property name="height">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckButton" id="emoji_checkbutton">
|
<object class="GtkCheckButton" id="emoji_checkbutton">
|
||||||
<property name="label" translatable="yes">Convert smileys to emojis</property>
|
<property name="label" translatable="yes">Convert smileys to emojis</property>
|
||||||
|
@ -36,7 +60,7 @@
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">0</property>
|
<property name="left_attach">0</property>
|
||||||
<property name="top_attach">1</property>
|
<property name="top_attach">3</property>
|
||||||
<property name="width">1</property>
|
<property name="width">1</property>
|
||||||
<property name="height">1</property>
|
<property name="height">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
|
|
|
@ -31,6 +31,8 @@ public class Notifications : Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_message_received(Entities.Message message, Conversation conversation) {
|
private void on_message_received(Entities.Message message, Conversation conversation) {
|
||||||
|
if (!should_notify_message(message, conversation)) return;
|
||||||
|
|
||||||
if (!notifications.has_key(conversation)) {
|
if (!notifications.has_key(conversation)) {
|
||||||
notifications[conversation] = new Notify.Notification("", null, null);
|
notifications[conversation] = new Notify.Notification("", null, null);
|
||||||
notifications[conversation].set_hint("transient", true);
|
notifications[conversation].set_hint("transient", true);
|
||||||
|
@ -74,7 +76,7 @@ public class Notifications : Object {
|
||||||
AddConversation.Chat.AddContactDialog dialog = new AddConversation.Chat.AddContactDialog(stream_interactor);
|
AddConversation.Chat.AddContactDialog dialog = new AddConversation.Chat.AddContactDialog(stream_interactor);
|
||||||
dialog.jid = jid.bare_jid.to_string();
|
dialog.jid = jid.bare_jid.to_string();
|
||||||
dialog.account = account;
|
dialog.account = account;
|
||||||
dialog.show();
|
dialog.present();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
notification.close();
|
notification.close();
|
||||||
|
@ -90,6 +92,14 @@ public class Notifications : Object {
|
||||||
notification.show();
|
notification.show();
|
||||||
} catch (Error error) { }
|
} catch (Error error) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool should_notify_message(Entities.Message message, Conversation conversation) {
|
||||||
|
Conversation.NotifySetting notify = conversation.get_notification_setting(stream_interactor);
|
||||||
|
if (notify == Conversation.NotifySetting.OFF) return false;
|
||||||
|
string? nick = stream_interactor.get_module(MucManager.IDENTITY).get_nick(conversation.counterpart, conversation.account);
|
||||||
|
if (notify == Conversation.NotifySetting.HIGHLIGHT && nick != null && !message.body.contains(nick)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -5,7 +5,9 @@ namespace Dino.Ui {
|
||||||
[GtkTemplate (ui = "/org/dino-im/settings_dialog.ui")]
|
[GtkTemplate (ui = "/org/dino-im/settings_dialog.ui")]
|
||||||
class SettingsDialog : Dialog {
|
class SettingsDialog : Dialog {
|
||||||
|
|
||||||
|
[GtkChild] private CheckButton typing_checkbutton;
|
||||||
[GtkChild] private CheckButton marker_checkbutton;
|
[GtkChild] private CheckButton marker_checkbutton;
|
||||||
|
[GtkChild] private CheckButton notification_checkbutton;
|
||||||
[GtkChild] private CheckButton emoji_checkbutton;
|
[GtkChild] private CheckButton emoji_checkbutton;
|
||||||
|
|
||||||
Dino.Settings settings = Dino.Settings.instance();
|
Dino.Settings settings = Dino.Settings.instance();
|
||||||
|
@ -13,10 +15,14 @@ class SettingsDialog : Dialog {
|
||||||
public SettingsDialog() {
|
public SettingsDialog() {
|
||||||
Object(use_header_bar : 1);
|
Object(use_header_bar : 1);
|
||||||
|
|
||||||
marker_checkbutton.active = settings.send_read;
|
typing_checkbutton.active = settings.send_typing;
|
||||||
|
marker_checkbutton.active = settings.send_marker;
|
||||||
|
notification_checkbutton.active = settings.notifications;
|
||||||
emoji_checkbutton.active = settings.convert_utf8_smileys;
|
emoji_checkbutton.active = settings.convert_utf8_smileys;
|
||||||
|
|
||||||
marker_checkbutton.toggled.connect(() => { settings.send_read = marker_checkbutton.active; });
|
typing_checkbutton.toggled.connect(() => { settings.send_typing = typing_checkbutton.active; } );
|
||||||
|
marker_checkbutton.toggled.connect(() => { settings.send_marker = marker_checkbutton.active; } );
|
||||||
|
notification_checkbutton.toggled.connect(() => { settings.notifications = notification_checkbutton.active; } );
|
||||||
emoji_checkbutton.toggled.connect(() => { settings.convert_utf8_smileys = emoji_checkbutton.active; });
|
emoji_checkbutton.toggled.connect(() => { settings.convert_utf8_smileys = emoji_checkbutton.active; });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue