Skip to content

Commit

Permalink
Merge branch 'master' into allow-blocking-entire-domain
Browse files Browse the repository at this point in the history
  • Loading branch information
eerielili authored Jun 21, 2024
2 parents 8cb26d5 + 8b15417 commit d9f5b70
Show file tree
Hide file tree
Showing 153 changed files with 2,226 additions and 864 deletions.
2 changes: 1 addition & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ while true; do
--enable-plugin ) if [ -z "$ENABLED_PLUGINS" ]; then ENABLED_PLUGINS="$2"; else ENABLED_PLUGINS="$ENABLED_PLUGINS;$2"; fi; shift; shift ;;
--disable-plugin ) if [ -z "$DISABLED_PLUGINS" ]; then DISABLED_PLUGINS="$2"; else DISABLED_PLUGINS="$DISABLED_PLUGINS;$2"; fi; shift; shift ;;
--valac ) VALA_EXECUTABLE="$2"; shift; shift ;;
--valac-flags ) VALAC_FLAGS="$2"; shift; shift ;;
--valac-flags ) VALACFLAGS="$2"; shift; shift ;;
--lib-suffix ) LIB_SUFFIX="$2"; shift; shift ;;
--with-libsoup3 ) USE_SOUP3=yes; shift ;;
--disable-fast-vapi ) DISABLE_FAST_VAPI=yes; shift ;;
Expand Down
2 changes: 1 addition & 1 deletion dino.doap
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<Project>
<name>Dino</name>
<short-name>dino</short-name>
<shortdesc xml:lang="en">Modern XMPP Chat Client</shortdesc>
<shortdesc xml:lang="en">Modern XMPP chat client</shortdesc>
<shortdesc xml:lang="zh-TW">現代化的 XMPP 用戶端聊天軟件</shortdesc>
<shortdesc xml:lang="zh-CN">现代 XMPP 聊天客户端</shortdesc>
<shortdesc xml:lang="tr">Modern XMPP Sohbet İstemcisi</shortdesc>
Expand Down
2 changes: 1 addition & 1 deletion dino.doap.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<name>Dino</name>
<short-name>dino</short-name>

<shortdesc xml:lang="en">Modern XMPP Chat Client</shortdesc>
<shortdesc xml:lang="en">Modern XMPP chat client</shortdesc>
<description xml:lang="en">
Dino is a modern open-source chat client for the desktop. It focuses on providing a clean and reliable Jabber/XMPP experience while having your privacy in mind.
It supports end-to-end encryption with OMEMO and OpenPGP and allows configuring privacy-related features such as read receipts and typing notifications.
Expand Down
4 changes: 2 additions & 2 deletions im.dino.Dino.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "im.dino.Dino",
"runtime": "org.gnome.Platform",
"runtime-version": "44",
"runtime-version": "46",
"sdk": "org.gnome.Sdk",
"command": "dino",
"finish-args": [
Expand Down Expand Up @@ -73,4 +73,4 @@
]
}
]
}
}
1 change: 1 addition & 0 deletions libdino/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ SOURCES
src/util/display_name.vala
src/util/util.vala
src/util/weak_map.vala
src/util/weak_timeout.vala
CUSTOM_VAPIS
"${CMAKE_BINARY_DIR}/exports/xmpp-vala.vapi"
"${CMAKE_BINARY_DIR}/exports/qlite.vapi"
Expand Down
1 change: 1 addition & 0 deletions libdino/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ sources = files(
'src/util/display_name.vala',
'src/util/util.vala',
'src/util/weak_map.vala',
'src/util/weak_timeout.vala',
)
sources += [version_vala]
c_args = [
Expand Down
2 changes: 1 addition & 1 deletion libdino/src/application.vala
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ public interface Application : GLib.Application {
PresenceManager.start(stream_interactor);
CounterpartInteractionManager.start(stream_interactor);
BlockingManager.start(stream_interactor);
Calls.start(stream_interactor, db);
ConversationManager.start(stream_interactor, db);
MucManager.start(stream_interactor);
AvatarManager.start(stream_interactor, db);
RosterManager.start(stream_interactor, db);
FileManager.start(stream_interactor, db);
Calls.start(stream_interactor, db);
CallStore.start(stream_interactor, db);
ContentItemStore.start(stream_interactor, db);
ChatInteraction.start(stream_interactor);
Expand Down
2 changes: 1 addition & 1 deletion libdino/src/entity/conversation.vala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class Conversation : Object {
}
}
}
public Encryption encryption { get; set; default = Encryption.NONE; }
public Encryption encryption { get; set; default = Encryption.UNKNOWN; }
public Message? read_up_to { get; set; }
public int read_up_to_item { get; set; default=-1; }

Expand Down
18 changes: 18 additions & 0 deletions libdino/src/entity/settings.vala
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,24 @@ public class Settings : Object {
check_spelling_ = value;
}
}

public Encryption get_default_encryption(Account account) {
string? setting = db.account_settings.get_value(account.id, "default-encryption");
if (setting != null) {
return (Encryption) int.parse(setting);
}
return Encryption.NONE;
}

public void set_default_encryption(Account account, Encryption encryption) {
db.account_settings.upsert()
.value(db.account_settings.key, "default-encryption", true)
.value(db.account_settings.account_id, account.id, true)
.value(db.account_settings.value, ((int)encryption).to_string())
.perform();


}
}

}
7 changes: 7 additions & 0 deletions libdino/src/plugin/interfaces.vala
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public abstract class AccountSettingsEntry : Object {
public abstract Object? get_widget(WidgetType type);
}

public abstract class EncryptionPreferencesEntry : Object {
public abstract string id { get; }
public virtual Priority priority { get { return Priority.DEFAULT; } }

public abstract Object? get_widget(Account account, WidgetType type);
}

public interface ContactDetailsProvider : Object {
public abstract string id { get; }

Expand Down
13 changes: 13 additions & 0 deletions libdino/src/plugin/registry.vala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public class Registry {
public HashMap<Entities.Encryption, EncryptionListEntry> encryption_list_entries = new HashMap<Entities.Encryption, EncryptionListEntry>();
public HashMap<string, CallEncryptionEntry> call_encryption_entries = new HashMap<string, CallEncryptionEntry>();
public ArrayList<AccountSettingsEntry> account_settings_entries = new ArrayList<AccountSettingsEntry>();
public ArrayList<EncryptionPreferencesEntry> encryption_preferences_entries = new ArrayList<EncryptionPreferencesEntry>();
public ArrayList<ContactDetailsProvider> contact_details_entries = new ArrayList<ContactDetailsProvider>();
public Map<string, TextCommand> text_commands = new HashMap<string, TextCommand>();
public Gee.List<ConversationAdditionPopulator> conversation_addition_populators = new ArrayList<ConversationAdditionPopulator>();
Expand Down Expand Up @@ -43,6 +44,18 @@ public class Registry {
}
}

public bool register_encryption_preferences_entry(EncryptionPreferencesEntry entry) {
lock(encryption_preferences_entries) {
foreach(var e in encryption_preferences_entries) {
if (e.id == entry.id) return false;
}
encryption_preferences_entries.add(entry);
// TODO: Order by priority
// encryption_preferences_entries.sort((a,b) => b.name.collate(a.name));
return true;
}
}

public bool register_contact_details_entry(ContactDetailsProvider entry) {
lock(contact_details_entries) {
foreach(ContactDetailsProvider e in contact_details_entries) {
Expand Down
41 changes: 29 additions & 12 deletions libdino/src/service/avatar_manager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public class AvatarManager : StreamInteractionModule, Object {
if (hash == null) return null;
File file = File.new_for_path(Path.build_filename(folder, hash));
if (!file.query_exists()) {
fetch_and_store_for_jid(account, jid_);
fetch_and_store_for_jid.begin(account, jid_);
return null;
} else {
return file;
Expand Down Expand Up @@ -160,30 +160,32 @@ public class AvatarManager : StreamInteractionModule, Object {
}
}

public void unset_avatar(Account account) {
XmppStream stream = stream_interactor.get_stream(account);
if (stream == null) return;
Xmpp.Xep.UserAvatars.unset_avatar(stream);
}

private void on_account_added(Account account) {
stream_interactor.module_manager.get_module(account, Xep.UserAvatars.Module.IDENTITY).received_avatar_hash.connect((stream, jid, id) =>
on_user_avatar_received.begin(account, jid, id)
on_user_avatar_received(account, jid, id)
);
stream_interactor.module_manager.get_module(account, Xep.UserAvatars.Module.IDENTITY).avatar_removed.connect((stream, jid) => {
on_user_avatar_removed(account, jid);
});
stream_interactor.module_manager.get_module(account, Xep.VCard.Module.IDENTITY).received_avatar_hash.connect((stream, jid, id) =>
on_vcard_avatar_received.begin(account, jid, id)
on_vcard_avatar_received(account, jid, id)
);

foreach (var entry in get_avatar_hashes(account, Source.USER_AVATARS).entries) {
on_user_avatar_received(account, entry.key, entry.value);
}
foreach (var entry in get_avatar_hashes(account, Source.VCARD).entries) {

// FIXME: remove. temporary to remove falsely saved avatars.
if (stream_interactor.get_module(MucManager.IDENTITY).is_groupchat(entry.key, account)) {
db.avatar.delete().with(db.avatar.jid_id, "=", db.get_jid_id(entry.key)).perform();
continue;
}

on_vcard_avatar_received(account, entry.key, entry.value);
}
}

private async void on_user_avatar_received(Account account, Jid jid_, string id) {
private void on_user_avatar_received(Account account, Jid jid_, string id) {
Jid jid = jid_.bare_jid;

if (!user_avatars.has_key(jid) || user_avatars[jid] != id) {
Expand All @@ -193,7 +195,14 @@ public class AvatarManager : StreamInteractionModule, Object {
received_avatar(jid, account);
}

private async void on_vcard_avatar_received(Account account, Jid jid_, string id) {
private void on_user_avatar_removed(Account account, Jid jid_) {
Jid jid = jid_.bare_jid;
user_avatars.unset(jid);
remove_avatar_hash(account, jid, Source.USER_AVATARS);
received_avatar(jid, account);
}

private void on_vcard_avatar_received(Account account, Jid jid_, string id) {
bool is_gc = stream_interactor.get_module(MucManager.IDENTITY).might_be_groupchat(jid_.bare_jid, account);
Jid jid = is_gc ? jid_ : jid_.bare_jid;

Expand All @@ -215,6 +224,14 @@ public class AvatarManager : StreamInteractionModule, Object {
.perform();
}

public void remove_avatar_hash(Account account, Jid jid, int type) {
db.avatar.delete()
.with(db.avatar.jid_id, "=", db.get_jid_id(jid))
.with(db.avatar.account_id, "=", account.id)
.with(db.avatar.type_, "=", type)
.perform();
}

public HashMap<Jid, string> get_avatar_hashes(Account account, int type) {
HashMap<Jid, string> ret = new HashMap<Jid, string>(Jid.hash_func, Jid.equals_func);
foreach (Row row in db.avatar.select({db.avatar.jid_id, db.avatar.hash})
Expand Down
6 changes: 3 additions & 3 deletions libdino/src/service/call_peer_state.vala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class Dino.PeerState : Object {

public signal void connection_ready();
public signal void session_terminated(bool we_terminated, string? reason_name, string? reason_text);
public signal void encryption_updated(Xep.Jingle.ContentEncryption? audio_encryption, Xep.Jingle.ContentEncryption? video_encryption, bool same);
public signal void encryption_updated(Xep.Jingle.ContentEncryption? audio_encryption, Xep.Jingle.ContentEncryption? video_encryption);

public StreamInteractor stream_interactor;
public CallState call_state;
Expand Down Expand Up @@ -412,7 +412,7 @@ public class Dino.PeerState : Object {

if ((audio_encryptions != null && audio_encryptions.is_empty) || (video_encryptions != null && video_encryptions.is_empty)) {
call.encryption = Encryption.NONE;
encryption_updated(null, null, true);
encryption_updated(null, null);
return;
}

Expand Down Expand Up @@ -462,7 +462,7 @@ public class Dino.PeerState : Object {
encryption_keys_same = true;
}

encryption_updated(audio_encryption, video_encryption, encryption_keys_same);
encryption_updated(audio_encryption, video_encryption);
}
}

Expand Down
5 changes: 0 additions & 5 deletions libdino/src/service/calls.vala
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ namespace Dino {
call_state.initiate_groupchat_call.begin(conversation.counterpart);
}

conversation.last_active = call.time;

call_outgoing(call, call_state, conversation);

return call_state;
Expand Down Expand Up @@ -221,7 +219,6 @@ namespace Dino {

Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(call.counterpart.bare_jid, account, Conversation.Type.CHAT);
stream_interactor.get_module(CallStore.IDENTITY).add_call(call, conversation);
conversation.last_active = call.time;

var call_state = new CallState(call, stream_interactor);
connect_call_state_signals(call_state);
Expand Down Expand Up @@ -294,7 +291,6 @@ namespace Dino {
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(inviter_jid.bare_jid, account);
if (conversation == null) return null;
stream_interactor.get_module(CallStore.IDENTITY).add_call(call, conversation);
conversation.last_active = call.time;

CallState call_state = new CallState(call, stream_interactor);
connect_call_state_signals(call_state);
Expand Down Expand Up @@ -465,7 +461,6 @@ namespace Dino {

Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).approx_conversation_for_stanza(from_jid, to_jid, account, message_stanza.type_);
if (conversation == null) return;
conversation.last_active = call_state.call.time;

if (call_state.call.direction == Call.DIRECTION_INCOMING) {
call_incoming(call_state.call, call_state, conversation, video_requested, multiparty);
Expand Down
15 changes: 15 additions & 0 deletions libdino/src/service/conversation_manager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public class ConversationManager : StreamInteractionModule, Object {
stream_interactor.account_removed.connect(on_account_removed);
stream_interactor.get_module(MessageProcessor.IDENTITY).received_pipeline.connect(new MessageListener(stream_interactor));
stream_interactor.get_module(MessageProcessor.IDENTITY).message_sent.connect(handle_sent_message);
stream_interactor.get_module(Calls.IDENTITY).call_incoming.connect(handle_new_call);
stream_interactor.get_module(Calls.IDENTITY).call_outgoing.connect(handle_new_call);
}

public Conversation create_conversation(Jid jid, Account account, Conversation.Type? type = null) {
Expand All @@ -46,6 +48,14 @@ public class ConversationManager : StreamInteractionModule, Object {

// Create a new converation
Conversation conversation = new Conversation(jid, account, type);
// Set encryption for conversation
if (type == Conversation.Type.CHAT ||
(type == Conversation.Type.GROUPCHAT && stream_interactor.get_module(MucManager.IDENTITY).is_private_room(account, jid))) {
conversation.encryption = Application.get_default().settings.get_default_encryption(account);
} else {
conversation.encryption = Encryption.NONE;
}

add_conversation(conversation);
conversation.persist(db);
return conversation;
Expand Down Expand Up @@ -194,6 +204,11 @@ public class ConversationManager : StreamInteractionModule, Object {
}
}

private void handle_new_call(Call call, CallState state, Conversation conversation) {
conversation.last_active = call.time;
start_conversation(conversation);
}

private void add_conversation(Conversation conversation) {
if (!conversations[conversation.account].has_key(conversation.counterpart)) {
conversations[conversation.account][conversation.counterpart] = new ArrayList<Conversation>(Conversation.equals_func);
Expand Down
32 changes: 30 additions & 2 deletions libdino/src/service/database.vala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ using Dino.Entities;
namespace Dino {

public class Database : Qlite.Database {
private const int VERSION = 26;
private const int VERSION = 27;

public class AccountTable : Table {
public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true };
Expand Down Expand Up @@ -354,6 +354,29 @@ public class Database : Qlite.Database {
}
}

public class AccountSettingsTable : Table {
public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true };
public Column<int> account_id = new Column.Integer("account_id") { not_null = true };
public Column<string> key = new Column.Text("key") { not_null = true };
public Column<string> value = new Column.Text("value");

internal AccountSettingsTable(Database db) {
base(db, "account_settings");
init({id, account_id, key, value});
unique({account_id, key}, "REPLACE");
}

public string? get_value(int account_id, string key) {
var row_opt = select({value})
.with(this.account_id, "=", account_id)
.with(this.key, "=", key)
.single()
.row();
if (row_opt.is_present()) return row_opt[value];
return null;
}
}

public class ConversationSettingsTable : Table {
public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true };
public Column<int> conversation_id = new Column.Integer("conversation_id") {not_null=true};
Expand Down Expand Up @@ -388,6 +411,7 @@ public class Database : Qlite.Database {
public MamCatchupTable mam_catchup { get; private set; }
public ReactionTable reaction { get; private set; }
public SettingsTable settings { get; private set; }
public AccountSettingsTable account_settings { get; private set; }
public ConversationSettingsTable conversation_settings { get; private set; }

public Map<int, Jid> jid_table_cache = new HashMap<int, Jid>();
Expand Down Expand Up @@ -417,8 +441,9 @@ public class Database : Qlite.Database {
mam_catchup = new MamCatchupTable(this);
reaction = new ReactionTable(this);
settings = new SettingsTable(this);
account_settings = new AccountSettingsTable(this);
conversation_settings = new ConversationSettingsTable(this);
init({ account, jid, entity, content_item, message, body_meta, message_correction, reply, real_jid, occupantid, file_transfer, call, call_counterpart, conversation, avatar, entity_identity, entity_feature, roster, mam_catchup, reaction, settings, conversation_settings });
init({ account, jid, entity, content_item, message, body_meta, message_correction, reply, real_jid, occupantid, file_transfer, call, call_counterpart, conversation, avatar, entity_identity, entity_feature, roster, mam_catchup, reaction, settings, account_settings, conversation_settings });

try {
exec("PRAGMA journal_mode = WAL");
Expand Down Expand Up @@ -576,6 +601,9 @@ public class Database : Qlite.Database {
foreach(Row row in account.select()) {
try {
Account account = new Account.from_row(this, row);
if (account_table_cache.has_key(account.id)) {
account = account_table_cache[account.id];
}
ret.add(account);
account_table_cache[account.id] = account;
} catch (InvalidJidError e) {
Expand Down
Loading

0 comments on commit d9f5b70

Please sign in to comment.