Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package dino for openSUSE:Factory checked in at 2023-03-03 22:28:31 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/dino (Old) and /work/SRC/openSUSE:Factory/.dino.new.31432 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "dino" Fri Mar 3 22:28:31 2023 rev:7 rq:1069116 version:0.4.1 Changes: -------- --- /work/SRC/openSUSE:Factory/dino/dino.changes 2023-02-08 17:20:46.974087403 +0100 +++ /work/SRC/openSUSE:Factory/.dino.new.31432/dino.changes 2023-03-03 22:31:37.704087840 +0100 @@ -1,0 +2,12 @@ +Fri Mar 3 08:01:54 UTC 2023 - Michael Vetter <mvet...@suse.com> + +- Update to 0.4.1 bugfix release: + * Consider stream readable when EOS is reached + * Fix critical warnings after DTLS-SRTP calls without OMEMO verification + * Fix typing notifications in groupchats + * Fix some memory leaks + * Stop regenerating message menu buttons + * Clear chat input after /command + * Remove spell check setting + +------------------------------------------------------------------- Old: ---- dino-0.4.0.tar.gz New: ---- dino-0.4.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ dino.spec ++++++ --- /var/tmp/diff_new_pack.abXrWj/_old 2023-03-03 22:31:38.276090279 +0100 +++ /var/tmp/diff_new_pack.abXrWj/_new 2023-03-03 22:31:38.288090330 +0100 @@ -25,7 +25,7 @@ %endif Name: dino -Version: 0.4.0 +Version: 0.4.1 Release: 0 Summary: Modern Jabber/XMPP Client using GTK+/Vala License: GPL-3.0-only ++++++ dino-0.4.0.tar.gz -> dino-0.4.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/VERSION new/dino-0.4.1/VERSION --- old/dino-0.4.0/VERSION 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/VERSION 2023-03-02 00:30:00.000000000 +0100 @@ -1 +1 @@ -RELEASE 0.4.0 +RELEASE 0.4.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/libdino/src/entity/settings.vala new/dino-0.4.1/libdino/src/entity/settings.vala --- old/dino-0.4.0/libdino/src/entity/settings.vala 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/libdino/src/entity/settings.vala 2023-03-02 00:30:00.000000000 +0100 @@ -67,6 +67,7 @@ } } + // There is currently no spell checking for GTK4, thus there is currently no UI for this setting. private bool check_spelling_; public bool check_spelling { get { return check_spelling_; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/libdino/src/plugin/interfaces.vala new/dino-0.4.1/libdino/src/plugin/interfaces.vala --- old/dino-0.4.0/libdino/src/plugin/interfaces.vala 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/libdino/src/plugin/interfaces.vala 2023-03-02 00:30:00.000000000 +0100 @@ -151,8 +151,9 @@ public abstract void set_widget(Object object, WidgetType type, int priority); } -public delegate void MessageActionEvoked(Object button, Plugins.MetaConversationItem evoked_on, Object widget); +public delegate void MessageActionEvoked(Variant? variant); public class MessageAction : Object { + public string name; public bool sensitive = true; public string icon_name; public string? tooltip; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/libdino/src/service/message_processor.vala new/dino-0.4.1/libdino/src/service/message_processor.vala --- old/dino-0.4.0/libdino/src/service/message_processor.vala 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/libdino/src/service/message_processor.vala 2023-03-02 00:30:00.000000000 +0100 @@ -451,6 +451,10 @@ } } + if (conversation.get_send_typing_setting(stream_interactor) == Conversation.Setting.ON) { + ChatStateNotifications.add_state_to_message(new_message, ChatStateNotifications.STATE_ACTIVE); + } + stream.get_module(MessageModule.IDENTITY).send_message.begin(stream, new_message, (_, res) => { try { stream.get_module(MessageModule.IDENTITY).send_message.end(res); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/main/data/icons/scalable/apps/im.dino.Dino-symbolic.svg new/dino-0.4.1/main/data/icons/scalable/apps/im.dino.Dino-symbolic.svg --- old/dino-0.4.0/main/data/icons/scalable/apps/im.dino.Dino-symbolic.svg 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/main/data/icons/scalable/apps/im.dino.Dino-symbolic.svg 2023-03-02 00:30:00.000000000 +0100 @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg width="84.557mm" height="85.895mm" version="1.1" viewBox="0 0 84.557434 85.894989" xmlns="http://www.w3.org/2000/svg"> - <path d="m81.221 84.142s4.1401-7.3953 3.1966-9.0296c-0.82944-1.4366-8.4437-1.0846-8.4437-1.0846s4.1831-7.7568 3.1622-9.525c-1.0051-1.7408-9.6749-1.8226-9.6749-1.8226s10.726-5.3798 11.068-7.3725c0.35889-2.0885-9.4824-9.6358-9.4824-9.6358s10.44-13.588 9.6703-15.442c-0.96601-2.3265-16.818-3.8351-16.818-3.8351s1.7332-17.52-0.39677-18.89c-1.7897-1.1506-16.236 6.9991-16.236 6.9991s-5.9396-14.504-9.2468-14.504c-3.328 0-10.359 14.525-10.359 14.525s-11.671-8.0128-13.832-6.765c-1.9105 1.103-1.2591 15.252-1.2591 15.252z" style="fill-rule:evenodd;opacity:.65"/> - <path d="m36.287 11.792c-20.04 0-36.286 16.246-36.286 36.286 0 1.9247 0.15111 3.8139 0.43977 5.6575 1.4023 6.7619 6.6874 9.3881 6.6874 9.3881 1.1074 0.90879 2.4837 1.8364 4.0731 2.7523l-0.13074-4e-3s3.3315 18.563 9.4439 18.41c4.6229-0.11575 8.2505-9.4523 14.128-9.2646 5.8724 0.18755 8.2564 9.1509 14.1 9.2129 3.3748 0.0358 6.3071-5.7438 8.1597-10.528 0.58645-0.11985 1.1699-0.24995 1.7492-0.39222 5.5562 5.2542 18.398 10.599 23.871 12.412 0.0748-0.0397 0.13499-0.0861 0.17674-0.14056 1.3957-1.8189-7.9538-16.01-12.983-23.371 1.8385-4.3435 2.8556-9.1191 2.8556-14.132 0-20.04-16.246-36.286-36.286-36.286zm-18.351 23.567a2.9104 2.9104 0 0 1 2.9104 2.9104 2.9104 2.9104 0 0 1 -2.9104 2.9104 2.9104 2.9104 0 0 1 -2.9104 -2.9104 2.9104 2.9104 0 0 1 2.9104 -2.9104z" style="fill-rule:evenodd"/> - <path d="m36.286 11.792c-20.04 0-36.286 16.246-36.286 36.286 0 17.981 13.079 32.907 30.242 35.785 1.9655 0.32953 3.9844 0.50074 6.0436 0.50074 2.131 0 4.2195-0.18345 6.2497-0.53588 4.6558-0.80822 9.0061-2.5054 12.873-4.9077 10.413 3.4298 26.069 8.2534 27.291 6.6616 1.3957-1.8189-7.9538-16.01-12.983-23.371 1.8384-4.3435 2.8556-9.1191 2.8556-14.132-1e-5 -20.04-16.246-36.286-36.286-36.286zm-18.353 23.567a2.9104 2.9104 0 0 1 2.9104 2.9104 2.9104 2.9104 0 0 1 -2.9104 2.9104 2.9104 2.9104 0 0 1 -2.9104 -2.9104 2.9104 2.9104 0 0 1 2.9104 -2.9104z" style="fill-rule:evenodd;opacity:.55"/> +<svg width="128" height="128" version="1.1" viewBox="0 0 33.867 33.867" xmlns="http://www.w3.org/2000/svg"> + <path d="m30.892 31.413s1.4916-2.6644 1.1517-3.2532c-0.29883-0.51758-3.0421-0.39076-3.0421-0.39076s1.5071-2.7946 1.1393-3.4317c-0.36212-0.62717-3.4857-0.65664-3.4857-0.65664s3.8643-1.9382 3.9876-2.6562c0.1293-0.75244-3.4163-3.4716-3.4163-3.4716s3.7613-4.8955 3.484-5.5634c-0.34803-0.83819-6.0592-1.3817-6.0592-1.3817s0.62443-6.3121-0.14295-6.8057c-0.64479-0.41454-5.8495 2.5216-5.8495 2.5216s-2.1399-5.2255-3.3314-5.2255c-1.199 0-3.7321 5.233-3.7321 5.233s-4.2048-2.8868-4.9834-2.4373c-0.68831 0.39739-0.45363 5.495-0.45363 5.495z" style="fill-rule:evenodd;opacity:.65"/> + <path d="m14.703 5.3472c-7.22 0-13.073 5.8531-13.073 13.073 0 0.69343 0.054442 1.3741 0.15844 2.0383 0.50522 2.4362 2.4093 3.3823 2.4093 3.3823 0.39897 0.32742 0.89482 0.66161 1.4674 0.99159l-0.047098-0.0015s1.2003 6.6878 3.4024 6.6327c1.6655-0.0417 2.9725-3.4055 5.09-3.3378 2.1157 0.06757 2.9746 3.2969 5.0799 3.3192 1.2159 0.01289 2.2723-2.0694 2.9398-3.793 0.21128-0.04318 0.42149-0.09006 0.6302-0.14131 2.0018 1.893 6.6284 3.8186 8.6002 4.4718 0.02694-0.01431 0.04863-0.03102 0.06368-0.05064 0.50284-0.65531-2.8656-5.7681-4.6775-8.4201 0.66237-1.5649 1.0288-3.2854 1.0288-5.0915 0-7.22-5.8531-13.073-13.073-13.073zm-6.6115 8.4907a1.0486 1.0486 0 0 1 1.0486 1.0486 1.0486 1.0486 0 0 1-1.0486 1.0486 1.0486 1.0486 0 0 1-1.0486-1.0486 1.0486 1.0486 0 0 1 1.0486-1.0486z" style="fill-rule:evenodd"/> + <path d="m14.703 5.3472c-7.22 0-13.073 5.8531-13.073 13.073 0 6.4782 4.7121 11.856 10.896 12.893 0.70813 0.11873 1.4355 0.18041 2.1774 0.18041 0.76775 0 1.5202-0.06608 2.2516-0.19307 1.6774-0.29118 3.2447-0.90264 4.6379-1.7681 3.7516 1.2357 9.3921 2.9735 9.8324 2.4 0.50284-0.65531-2.8656-5.7681-4.6775-8.4201 0.66234-1.5649 1.0288-3.2854 1.0288-5.0915-3e-6 -7.22-5.8531-13.073-13.073-13.073zm-6.6122 8.4907a1.0486 1.0486 0 0 1 1.0486 1.0486 1.0486 1.0486 0 0 1-1.0486 1.0486 1.0486 1.0486 0 0 1-1.0486-1.0486 1.0486 1.0486 0 0 1 1.0486-1.0486z" style="fill-rule:evenodd;opacity:.55"/> </svg> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/main/data/menu_app.ui new/dino-0.4.1/main/data/menu_app.ui --- old/dino-0.4.0/main/data/menu_app.ui 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/main/data/menu_app.ui 2023-03-02 00:30:00.000000000 +0100 @@ -6,12 +6,12 @@ <attribute name="action">app.accounts</attribute> <attribute name="label" translatable="yes">Accounts</attribute> </item> + </section> + <section> <item> <attribute name="action">app.settings</attribute> - <attribute name="label" translatable="yes">Settings</attribute> + <attribute name="label" translatable="yes">Preferences</attribute> </item> - </section> - <section> <item> <attribute name="action">app.open_shortcuts</attribute> <attribute name="label" translatable="yes">Keyboard Shortcuts</attribute> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/main/data/settings_dialog.ui new/dino-0.4.1/main/data/settings_dialog.ui --- old/dino-0.4.0/main/data/settings_dialog.ui 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/main/data/settings_dialog.ui 2023-03-02 00:30:00.000000000 +0100 @@ -1,66 +1,69 @@ <?xml version="1.0" encoding="UTF-8"?> <interface> - <template class="DinoUiSettingsDialog"> - <property name="title" translatable="yes">Settings</property> + <template class="DinoUiSettingsDialog" parent="AdwPreferencesWindow"> + <property name="default-width">500</property> + <property name="default-height">360</property> <property name="modal">True</property> - <child type="titlebar"> - <object class="GtkHeaderBar"> - </object> - </child> - <child internal-child="content_area"> - <object class="GtkBox"> + <property name="search-enabled">False</property> + <child> + <object class="AdwPreferencesPage"> <child> - <object class="GtkGrid"> - <property name="margin_top">10</property> - <property name="margin_bottom">10</property> - <property name="margin_start">10</property> - <property name="margin_end">10</property> - <property name="halign">center</property> - <property name="valign">center</property> - <property name="row-spacing">10</property> + <object class="AdwPreferencesGroup"> <child> - <object class="GtkCheckButton" id="typing_checkbutton"> - <property name="label" translatable="yes">Send typing notifications</property> - <layout> - <property name="column">0</property> - <property name="row">0</property> - </layout> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Send _Typing Notifications</property> + <property name="use-underline">True</property> + <property name="activatable-widget">typing_switch</property> + <child type="suffix"> + <object class="GtkSwitch" id="typing_switch"> + <property name="valign">center</property> + </object> + </child> </object> </child> <child> - <object class="GtkCheckButton" id="marker_checkbutton"> - <property name="label" translatable="yes">Send read receipts</property> - <layout> - <property name="column">0</property> - <property name="row">1</property> - </layout> - </object> - </child> - <child> - <object class="GtkCheckButton" id="notification_checkbutton"> - <property name="label" translatable="yes">Notify when a new message arrives</property> - <layout> - <property name="column">0</property> - <property name="row">2</property> - </layout> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Send _Read Receipts</property> + <property name="use-underline">True</property> + <property name="activatable-widget">marker_switch</property> + <child type="suffix"> + <object class="GtkSwitch" id="marker_switch"> + <property name="valign">center</property> + </object> + </child> </object> </child> + </object> + </child> + <child> + <object class="AdwPreferencesGroup"> <child> - <object class="GtkCheckButton" id="emoji_checkbutton"> - <property name="label" translatable="yes">Convert smileys to emojis</property> - <layout> - <property name="column">0</property> - <property name="row">3</property> - </layout> + <object class="AdwActionRow"> + <property name="title" translatable="yes">_Notifications</property> + <property name="subtitle" translatable="yes">Notify when a new message arrives</property> + <property name="use-underline">True</property> + <property name="activatable-widget">notification_switch</property> + <child type="suffix"> + <object class="GtkSwitch" id="notification_switch"> + <property name="valign">center</property> + </object> + </child> </object> </child> + </object> + </child> + <child> + <object class="AdwPreferencesGroup"> <child> - <object class="GtkCheckButton" id="check_spelling_checkbutton"> - <property name="label" translatable="yes">Check spelling</property> - <layout> - <property name="column">0</property> - <property name="row">4</property> - </layout> + <object class="AdwActionRow"> + <property name="title" translatable="yes">_Convert Smileys to Emoji</property> + <property name="use-underline">True</property> + <property name="activatable-widget">emoji_switch</property> + <child type="suffix"> + <object class="GtkSwitch" id="emoji_switch"> + <property name="valign">center</property> + </object> + </child> </object> </child> </object> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/main/src/ui/chat_input/chat_input_controller.vala new/dino-0.4.1/main/src/ui/chat_input/chat_input_controller.vala --- old/dino-0.4.0/main/src/ui/chat_input/chat_input_controller.vala 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/main/src/ui/chat_input/chat_input_controller.vala 2023-03-02 00:30:00.000000000 +0100 @@ -135,6 +135,12 @@ } string text = chat_input.chat_text_view.text_view.buffer.text; + ContentItem? quoted_content_item_bak = quoted_content_item; + + // Reset input state. Has do be done before parsing commands, because those directly return. + chat_input.chat_text_view.text_view.buffer.text = ""; + chat_input.unset_quoted_message(); + quoted_content_item = null; if (text.has_prefix("/")) { string[] token = text.split(" ", 2); @@ -189,15 +195,10 @@ } } Message out_message = stream_interactor.get_module(MessageProcessor.IDENTITY).create_out_message(text, conversation); - if (quoted_content_item != null) { - stream_interactor.get_module(Replies.IDENTITY).set_message_is_reply_to(out_message, quoted_content_item); + if (quoted_content_item_bak != null) { + stream_interactor.get_module(Replies.IDENTITY).set_message_is_reply_to(out_message, quoted_content_item_bak); } stream_interactor.get_module(MessageProcessor.IDENTITY).send_message(out_message, conversation); - - // Reset input state - chat_input.chat_text_view.text_view.buffer.text = ""; - chat_input.unset_quoted_message(); - quoted_content_item = null; } private void on_text_input_changed() { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/main/src/ui/chat_input/spell_checker.vala new/dino-0.4.1/main/src/ui/chat_input/spell_checker.vala --- old/dino-0.4.0/main/src/ui/chat_input/spell_checker.vala 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/main/src/ui/chat_input/spell_checker.vala 1970-01-01 01:00:00.000000000 +0100 @@ -1,80 +0,0 @@ -using Gdk; -using Gee; - -using Dino.Entities; - -namespace Dino.Ui { - -public class SpellChecker { - - private Conversation? conversation; - private Gtk.TextView text_input; - - public SpellChecker(Gtk.TextView text_input) { - this.text_input = text_input; - - // We can't keep a reference to GspellTextView/Buffer around, otherwise they'd get freed twice - Gspell.TextView text_view = Gspell.TextView.get_from_gtk_text_view(text_input); - Gspell.TextBuffer text_buffer = Gspell.TextBuffer.get_from_gtk_text_buffer(text_view.view.buffer); - - text_view.basic_setup(); - text_buffer.spell_checker.notify["language"].connect(lang_changed); - - // Enable/Disable spell checking live - Dino.Application.get_default().settings.notify["check-spelling"].connect((obj, _) => { - if (((Dino.Entities.Settings) obj).check_spelling) { - initialize_for_conversation(this.conversation); - } else { - text_buffer.set_spell_checker(null); - } - }); - } - - public void initialize_for_conversation(Conversation conversation) { - this.conversation = conversation; - - Gspell.TextView text_view = Gspell.TextView.get_from_gtk_text_view(text_input); - Gspell.TextBuffer text_buffer = Gspell.TextBuffer.get_from_gtk_text_buffer(text_view.view.buffer); - - if (!Dino.Application.get_default().settings.check_spelling) { - text_buffer.set_spell_checker(null); - return; - } - if (text_buffer.spell_checker == null) text_buffer.spell_checker = new Gspell.Checker(null); - - // Set the conversation language (from cache or db) - text_buffer.spell_checker.notify["language"].disconnect(lang_changed); - - var db = Dino.Application.get_default().db; - Qlite.RowOption row_option = db.conversation_settings.select() - .with(db.conversation_settings.conversation_id, "=", conversation.id) - .with(db.conversation_settings.key, "=", "lang") - .single().row(); - if (row_option.is_present()) { - string lang_code = row_option.inner[db.conversation_settings.value]; - Gspell.Language? lang = Gspell.Language.lookup(lang_code); - text_buffer.spell_checker.language = lang; - } else { - text_buffer.spell_checker.language = null; - } - - text_buffer.spell_checker.notify["language"].connect(lang_changed); - } - - private void lang_changed() { - var db = Dino.Application.get_default().db; - - Gspell.TextView text_view = Gspell.TextView.get_from_gtk_text_view(text_input); - Gspell.TextBuffer text_buffer = Gspell.TextBuffer.get_from_gtk_text_buffer(text_view.view.buffer); - Gspell.Checker spell_checker = text_buffer.spell_checker; - if (spell_checker.language.get_code() == null) return; - - db.conversation_settings.upsert() - .value(db.conversation_settings.conversation_id, conversation.id, true) - .value(db.conversation_settings.key, "lang", true) - .value(db.conversation_settings.value, spell_checker.language.get_code()) - .perform(); - } -} - -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/main/src/ui/conversation_content_view/conversation_item_skeleton.vala new/dino-0.4.1/main/src/ui/conversation_content_view/conversation_item_skeleton.vala --- old/dino-0.4.0/main/src/ui/conversation_content_view/conversation_item_skeleton.vala 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/main/src/ui/conversation_content_view/conversation_item_skeleton.vala 2023-03-02 00:30:00.000000000 +0100 @@ -71,9 +71,7 @@ ContentMetaItem? content_meta_item = item as ContentMetaItem; if (content_meta_item != null) { reactions_controller = new ReactionsController(conversation, content_meta_item.content_item, stream_interactor); - reactions_controller.box_activated.connect((widget) => { - set_widget(widget, Plugins.WidgetType.GTK4, 3); - }); + reactions_controller.box_activated.connect(on_reaction_box_activated); reactions_controller.init(); } @@ -152,7 +150,7 @@ if (item.encryption != Encryption.NONE && item.encryption != Encryption.UNKNOWN && ci != null) { string? icon_name = null; var encryption_entry = app.plugin_registry.encryption_list_entries[item.encryption]; - icon_name = encryption_entry.get_encryption_icon_name(conversation, ci.content_item); + if (encryption_entry != null) icon_name = encryption_entry.get_encryption_icon_name(conversation, ci.content_item); encryption_image.icon_name = icon_name ?? "changes-prevent-symbolic"; encryption_image.visible = true; } @@ -170,6 +168,10 @@ } } + private void on_reaction_box_activated(Widget widget) { + set_widget(widget, Plugins.WidgetType.GTK4, 3); + } + private void update_time() { time_label.label = get_relative_time(item.time.to_local()).to_string(); @@ -271,6 +273,34 @@ stream_interactor.get_module(RosterManager.IDENTITY).disconnect(updated_roster_handler_id); updated_roster_handler_id = 0; } + reactions_controller = null; + + // Children won't be disposed automatically + if (name_label != null) { + name_label.unparent(); + name_label.dispose(); + name_label = null; + } + if (time_label != null) { + time_label.unparent(); + time_label.dispose(); + time_label = null; + } + if (avatar_image != null) { + avatar_image.unparent(); + avatar_image.dispose(); + avatar_image = null; + } + if (encryption_image != null) { + encryption_image.unparent(); + encryption_image.dispose(); + encryption_image = null; + } + if (received_image != null) { + received_image.unparent(); + received_image.dispose(); + received_image = null; + } base.dispose(); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/main/src/ui/conversation_content_view/conversation_view.vala new/dino-0.4.1/main/src/ui/conversation_content_view/conversation_view.vala --- old/dino-0.4.0/main/src/ui/conversation_content_view/conversation_view.vala 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/main/src/ui/conversation_content_view/conversation_view.vala 2023-03-02 00:30:00.000000000 +0100 @@ -20,7 +20,7 @@ [GtkChild] private unowned Box main; [GtkChild] private unowned Box main_wrap_box; - private ArrayList<Widget> action_buttons = new ArrayList<Widget>(); + private HashMap<string, Widget> action_buttons = new HashMap<string, Widget>(); private Gee.List<Dino.Plugins.MessageAction>? message_actions = null; private StreamInteractor stream_interactor; @@ -46,6 +46,30 @@ construct { this.layout_manager = new BinLayout(); + + // Setup all message menu buttons + var correction_button = new Button() { name="correction" }; + correction_button.clicked.connect((button) => { + on_action_button_clicked(button, null); + }); + action_buttons["correction"] = correction_button; + message_menu_box.append(correction_button); + + var reply_button = new Button() { name="reply" }; + reply_button.clicked.connect((button) => { + on_action_button_clicked(button, null); + }); + action_buttons["reply"] = reply_button; + message_menu_box.append(reply_button); + + var reaction_button = new MenuButton() { name="reaction" }; + EmojiChooser chooser = new EmojiChooser(); + chooser.emoji_picked.connect((emoji) => { + on_action_button_clicked(reaction_button, new GLib.Variant.string(emoji)); + }); + reaction_button.popover = chooser; + action_buttons["reaction"] = reaction_button; + message_menu_box.append(reaction_button); } public ConversationView init(StreamInteractor stream_interactor) { @@ -112,7 +136,7 @@ } private bool is_highlight_fixed() { - foreach (Widget widget in action_buttons) { + foreach (Widget widget in action_buttons.values) { MenuButton? menu_button = widget as MenuButton; if (menu_button != null && menu_button.popover.visible) return true; @@ -192,40 +216,33 @@ return; } - foreach (Widget widget in action_buttons) { - message_menu_box.remove(widget); - } - action_buttons.clear(); + var current_message_actions = current_meta_item.get_item_actions(Plugins.WidgetType.GTK4); message_actions = current_meta_item.get_item_actions(Plugins.WidgetType.GTK4); if (message_actions != null) { message_menu_box.visible = true; + foreach (Widget widget in action_buttons.values) { + widget.visible = false; + } + // Configure as many buttons as we need with the actions for the current meta item - foreach (var message_action in message_actions) { - if (message_action.popover != null) { - MenuButton button = new MenuButton(); + foreach (var message_action in current_message_actions) { + Widget button_widget = action_buttons[message_action.name]; + button_widget.visible = true; + if (message_action.name == "reaction") { + MenuButton button = (MenuButton) button_widget; button.sensitive = message_action.sensitive; button.icon_name = message_action.icon_name; - button.set_popover(message_action.popover as Popover); button.tooltip_text = Util.string_if_tooltips_active(message_action.tooltip); - action_buttons.add(button); } else if (message_action.callback != null) { - Button button = new Button(); + Button button = (Button) button_widget; button.sensitive = message_action.sensitive; button.icon_name = message_action.icon_name; - button.clicked.connect(() => { - message_action.callback(button, current_meta_item, currently_highlighted); - }); button.tooltip_text = Util.string_if_tooltips_active(message_action.tooltip); - action_buttons.add(button); } } - - foreach (Widget widget in action_buttons) { - message_menu_box.append(widget); - } } else { message_menu_box.visible = false; } @@ -409,6 +426,7 @@ content_items.remove((ContentMetaItem)item); } meta_items.remove(item); + skeleton.dispose(); } removed_item(item); @@ -498,12 +516,10 @@ (upper_item.mark == Message.Marked.WONTSEND) == (lower_item.mark == Message.Marked.WONTSEND); } - private void on_action_button_clicked(ToggleButton button) { - int button_idx = action_buttons.index_of(button); - print(button_idx.to_string() + "\n"); - Plugins.MessageAction message_action = message_actions[button_idx]; - if (message_action.callback != null) { - message_action.callback(button, current_meta_item, currently_highlighted); + private void on_action_button_clicked(Widget widget, GLib.Variant? variant = null) { + foreach (var action in message_actions) { + if (action.name != widget.name) continue; + action.callback(variant); } } @@ -576,12 +592,19 @@ private void clear() { was_upper = null; was_page_size = null; + foreach (var item in content_items) { + item.dispose(); + } content_items.clear(); meta_items.clear(); widget_order.clear(); + foreach (var skeleton in item_item_skeletons.values) { + skeleton.dispose(); + } item_item_skeletons.clear(); foreach (Widget widget in widgets.values) { - main.remove(widget); + widget.unparent(); + widget.dispose(); } widgets.clear(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/main/src/ui/conversation_content_view/file_widget.vala new/dino-0.4.1/main/src/ui/conversation_content_view/file_widget.vala --- old/dino-0.4.0/main/src/ui/conversation_content_view/file_widget.vala 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/main/src/ui/conversation_content_view/file_widget.vala 2023-03-02 00:30:00.000000000 +0100 @@ -135,6 +135,17 @@ } return false; } + + public override void dispose() { + if (default_widget_controller != null) default_widget_controller.dispose(); + default_widget_controller = null; + if (content != null) { + content.unparent(); + content.dispose(); + content = null; + } + base.dispose(); + } } public class FileWidgetController : Object { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/main/src/ui/conversation_content_view/item_actions.vala new/dino-0.4.1/main/src/ui/conversation_content_view/item_actions.vala --- old/dino-0.4.0/main/src/ui/conversation_content_view/item_actions.vala 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/main/src/ui/conversation_content_view/item_actions.vala 2023-03-02 00:30:00.000000000 +0100 @@ -4,14 +4,14 @@ namespace Dino.Ui { public Plugins.MessageAction get_reaction_action(ContentItem content_item, Conversation conversation, StreamInteractor stream_interactor) { Plugins.MessageAction action = new Plugins.MessageAction(); + action.name = "reaction"; action.icon_name = "dino-emoticon-add-symbolic"; action.tooltip = _("Add reaction"); - EmojiChooser chooser = new EmojiChooser(); - chooser.emoji_picked.connect((emoji) => { + action.callback = (variant) => { + string emoji = variant.get_string(); stream_interactor.get_module(Reactions.IDENTITY).add_reaction(conversation, content_item, emoji); - }); - action.popover = chooser; + }; // Disable the button if reaction aren't possible. bool supports_reactions = stream_interactor.get_module(Reactions.IDENTITY).conversation_supports_reactions(conversation); @@ -29,9 +29,10 @@ public Plugins.MessageAction get_reply_action(ContentItem content_item, Conversation conversation, StreamInteractor stream_interactor) { Plugins.MessageAction action = new Plugins.MessageAction(); + action.name = "reply"; action.icon_name = "mail-reply-sender-symbolic"; action.tooltip = _("Reply"); - action.callback = (button, content_meta_item_activated, widget) => { + action.callback = () => { GLib.Application.get_default().activate_action("quote", new GLib.Variant.tuple(new GLib.Variant[] { new GLib.Variant.int32(conversation.id), new GLib.Variant.int32(content_item.id) })); }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/main/src/ui/conversation_content_view/message_widget.vala new/dino-0.4.1/main/src/ui/conversation_content_view/message_widget.vala --- old/dino-0.4.0/main/src/ui/conversation_content_view/message_widget.vala 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/main/src/ui/conversation_content_view/message_widget.vala 2023-03-02 00:30:00.000000000 +0100 @@ -19,6 +19,7 @@ private StreamInteractor stream_interactor; private MessageItem message_item; public Message.Marked marked { get; set; } + public Plugins.ConversationItemWidgetInterface outer = null; MessageItemEditMode? edit_mode = null; ChatTextViewController? controller = null; @@ -35,6 +36,8 @@ message_item = content_item as MessageItem; this.stream_interactor = stream_interactor; + stream_interactor.get_module(MessageCorrection.IDENTITY).received_correction.connect(on_received_correction); + label.activate_link.connect(on_label_activate_link); Message message = ((MessageItem) content_item).message; @@ -146,43 +149,9 @@ } public override Object? get_widget(Plugins.ConversationItemWidgetInterface outer, Plugins.WidgetType type) { + this.outer = outer; - stream_interactor.get_module(MessageCorrection.IDENTITY).received_correction.connect(on_received_correction); - - this.notify["in-edit-mode"].connect(() => { - if (in_edit_mode == false) return; - bool allowed = stream_interactor.get_module(MessageCorrection.IDENTITY).is_own_correction_allowed(message_item.conversation, message_item.message); - if (allowed) { - MessageItem message_item = content_item as MessageItem; - Message message = message_item.message; - - edit_mode = new MessageItemEditMode(); - controller = new ChatTextViewController(edit_mode.chat_text_view, stream_interactor); - Conversation conversation = message_item.conversation; - controller.initialize_for_conversation(conversation); - - edit_mode.cancelled.connect(() => { - in_edit_mode = false; - outer.set_widget(label, Plugins.WidgetType.GTK4, 2); - }); - edit_mode.send.connect(() => { - if (((MessageItem) content_item).message.body != edit_mode.chat_text_view.text_view.buffer.text) { - on_edit_send(edit_mode.chat_text_view.text_view.buffer.text); - } else { -// edit_cancelled(); - } - in_edit_mode = false; - outer.set_widget(label, Plugins.WidgetType.GTK4, 2); - }); - - edit_mode.chat_text_view.text_view.buffer.text = message.body; - - outer.set_widget(edit_mode, Plugins.WidgetType.GTK4, 2); - edit_mode.chat_text_view.text_view.grab_focus(); - } else { - this.in_edit_mode = false; - } - }); + this.notify["in-edit-mode"].connect(on_in_edit_mode_changed); outer.set_widget(label, Plugins.WidgetType.GTK4, 2); @@ -201,7 +170,6 @@ } public override Gee.List<Plugins.MessageAction>? get_item_actions(Plugins.WidgetType type) { - if (content_item as FileItem != null || this.in_edit_mode) return null; if (in_edit_mode) return null; Gee.List<Plugins.MessageAction> actions = new ArrayList<Plugins.MessageAction>(); @@ -209,9 +177,10 @@ bool correction_allowed = stream_interactor.get_module(MessageCorrection.IDENTITY).is_own_correction_allowed(message_item.conversation, message_item.message); if (correction_allowed) { Plugins.MessageAction action1 = new Plugins.MessageAction(); + action1.name = "correction"; action1.icon_name = "document-edit-symbolic"; action1.tooltip = _("Edit message"); - action1.callback = (button, content_meta_item_activated, widget) => { + action1.callback = () => { this.in_edit_mode = true; }; actions.add(action1); @@ -223,6 +192,41 @@ return actions; } + private void on_in_edit_mode_changed() { + if (in_edit_mode == false) return; + bool allowed = stream_interactor.get_module(MessageCorrection.IDENTITY).is_own_correction_allowed(message_item.conversation, message_item.message); + if (allowed) { + MessageItem message_item = content_item as MessageItem; + Message message = message_item.message; + + edit_mode = new MessageItemEditMode(); + controller = new ChatTextViewController(edit_mode.chat_text_view, stream_interactor); + Conversation conversation = message_item.conversation; + controller.initialize_for_conversation(conversation); + + edit_mode.cancelled.connect(() => { + in_edit_mode = false; + outer.set_widget(label, Plugins.WidgetType.GTK4, 2); + }); + edit_mode.send.connect(() => { + if (((MessageItem) content_item).message.body != edit_mode.chat_text_view.text_view.buffer.text) { + on_edit_send(edit_mode.chat_text_view.text_view.buffer.text); + } else { +// edit_cancelled(); + } + in_edit_mode = false; + outer.set_widget(label, Plugins.WidgetType.GTK4, 2); + }); + + edit_mode.chat_text_view.text_view.buffer.text = message.body; + + outer.set_widget(edit_mode, Plugins.WidgetType.GTK4, 2); + edit_mode.chat_text_view.text_view.grab_focus(); + } else { + this.in_edit_mode = false; + } + } + private void on_edit_send(string text) { stream_interactor.get_module(MessageCorrection.IDENTITY).send_correction(message_item.conversation, message_item.message, text); this.in_edit_mode = false; @@ -243,6 +247,17 @@ Dino.Application.get_default().open(new File[]{file}, ""); return true; } + + public override void dispose() { + stream_interactor.get_module(MessageCorrection.IDENTITY).received_correction.disconnect(on_received_correction); + this.notify["in-edit-mode"].disconnect(on_in_edit_mode_changed); + if (label != null) { + label.unparent(); + label.dispose(); + label = null; + } + base.dispose(); + } } [GtkTemplate (ui = "/im/dino/Dino/message_item_widget_edit_mode.ui")] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/main/src/ui/settings_dialog.vala new/dino-0.4.1/main/src/ui/settings_dialog.vala --- old/dino-0.4.0/main/src/ui/settings_dialog.vala 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/main/src/ui/settings_dialog.vala 2023-03-02 00:30:00.000000000 +0100 @@ -3,30 +3,27 @@ namespace Dino.Ui { [GtkTemplate (ui = "/im/dino/Dino/settings_dialog.ui")] -class SettingsDialog : Dialog { +class SettingsDialog : Adw.PreferencesWindow { - [GtkChild] private unowned CheckButton typing_checkbutton; - [GtkChild] private unowned CheckButton marker_checkbutton; - [GtkChild] private unowned CheckButton notification_checkbutton; - [GtkChild] private unowned CheckButton emoji_checkbutton; - [GtkChild] private unowned CheckButton check_spelling_checkbutton; + [GtkChild] private unowned Switch typing_switch; + [GtkChild] private unowned Switch marker_switch; + [GtkChild] private unowned Switch notification_switch; + [GtkChild] private unowned Switch emoji_switch; Dino.Entities.Settings settings = Dino.Application.get_default().settings; public SettingsDialog() { - Object(use_header_bar : Util.use_csd() ? 1 : 0); + Object(); - typing_checkbutton.active = settings.send_typing; - marker_checkbutton.active = settings.send_marker; - notification_checkbutton.active = settings.notifications; - emoji_checkbutton.active = settings.convert_utf8_smileys; - check_spelling_checkbutton.active = settings.check_spelling; - - 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; }); - check_spelling_checkbutton.toggled.connect(() => { settings.check_spelling = check_spelling_checkbutton.active; }); + typing_switch.active = settings.send_typing; + marker_switch.active = settings.send_marker; + notification_switch.active = settings.notifications; + emoji_switch.active = settings.convert_utf8_smileys; + + typing_switch.notify["active"].connect(() => { settings.send_typing = typing_switch.active; } ); + marker_switch.notify["active"].connect(() => { settings.send_marker = marker_switch.active; } ); + notification_switch.notify["active"].connect(() => { settings.notifications = notification_switch.active; } ); + emoji_switch.notify["active"].connect(() => { settings.convert_utf8_smileys = emoji_switch.active; }); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/main/src/ui/widgets/date_separator.vala new/dino-0.4.1/main/src/ui/widgets/date_separator.vala --- old/dino-0.4.0/main/src/ui/widgets/date_separator.vala 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/main/src/ui/widgets/date_separator.vala 2023-03-02 00:30:00.000000000 +0100 @@ -40,8 +40,14 @@ private void update_time_label() { date_label = get_relative_time(date); - time_update_timeout = Timeout.add_seconds((int) get_next_time_change(), () => { - if (time_update_timeout != 0) update_time_label(); + time_update_timeout = set_update_time_label_timeout((int) get_next_time_change(), this); + } + + private static uint set_update_time_label_timeout(int interval, CompatDateSeparatorModel model_) { + WeakRef model_weak = WeakRef(model_); + return Timeout.add_seconds(interval, () => { + CompatDateSeparatorModel? model = (CompatDateSeparatorModel) model_weak.get(); + if (model != null && model.time_update_timeout != 0) model.update_time_label(); return false; }); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/plugins/http-files/src/file_provider.vala new/dino-0.4.1/plugins/http-files/src/file_provider.vala --- old/dino-0.4.0/plugins/http-files/src/file_provider.vala 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/plugins/http-files/src/file_provider.vala 2023-03-02 00:30:00.000000000 +0100 @@ -66,7 +66,7 @@ public bool is_readable() { if (!can_poll()) throw new IOError.NOT_SUPPORTED("Stream is not pollable"); - return ((PollableInputStream)inner).is_readable(); + return remaining_size <= 0 || ((PollableInputStream)inner).is_readable(); } private ssize_t check_limit(ssize_t read) throws IOError { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/plugins/omemo/src/ui/bad_messages_populator.vala new/dino-0.4.1/plugins/omemo/src/ui/bad_messages_populator.vala --- old/dino-0.4.0/plugins/omemo/src/ui/bad_messages_populator.vala 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/plugins/omemo/src/ui/bad_messages_populator.vala 2023-03-02 00:30:00.000000000 +0100 @@ -94,6 +94,7 @@ foreach (BadMessageItem bad_item in bad_items) { item_collection.remove_item(bad_item); } + bad_items.clear(); } public void init(Conversation conversation, Plugins.ConversationItemCollection item_collection, Plugins.WidgetType type) { @@ -103,7 +104,9 @@ init_state(); } - public void close(Conversation conversation) { } + public void close(Conversation conversation) { + clear_state(); + } public void populate_timespan(Conversation conversation, DateTime after, DateTime before) { } } @@ -131,9 +134,17 @@ } public class BadMessagesWidget : Box { + private Plugin plugin; + private Conversation conversation; + private Jid jid; + private Label label; + public BadMessagesWidget(Plugin plugin, Conversation conversation, Jid jid, BadnessType badness_type) { Object(orientation:Orientation.HORIZONTAL, spacing:5); + this.plugin = plugin; + this.conversation = conversation; + this.jid = jid; this.halign = Align.CENTER; this.visible = true; @@ -159,19 +170,29 @@ } else { warning_text += _("%s does not trust this device. That means, you might be missing messages.").printf(who); } - Label label = new Label(warning_text) { margin_start=70, margin_end=70, justify=Justification.CENTER, use_markup=true, selectable=true, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, hexpand=true }; + label = new Label(warning_text) { margin_start=70, margin_end=70, justify=Justification.CENTER, use_markup=true, selectable=true, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, hexpand=true }; label.add_css_class("dim-label"); this.append(label); - label.activate_link.connect(() => { - if (badness_type == BadnessType.UNTRUSTED) { - ContactDetailsDialog dialog = new ContactDetailsDialog(plugin, conversation.account, jid); - dialog.set_transient_for((Window) get_root()); - dialog.present(); - } + if (badness_type == BadnessType.UNTRUSTED) { + label.activate_link.connect(on_label_activate_link); + } + } - return false; - }); + private bool on_label_activate_link() { + ContactDetailsDialog dialog = new ContactDetailsDialog(plugin, conversation.account, jid); + dialog.set_transient_for((Window) get_root()); + dialog.present(); + return false; + } + + public override void dispose() { + if (label != null) { + label.unparent(); + label.dispose(); + label = null; + } + base.dispose(); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.0/xmpp-vala/src/module/xep/0085_chat_state_notifications.vala new/dino-0.4.1/xmpp-vala/src/module/xep/0085_chat_state_notifications.vala --- old/dino-0.4.0/xmpp-vala/src/module/xep/0085_chat_state_notifications.vala 2023-02-07 22:00:00.000000000 +0100 +++ new/dino-0.4.1/xmpp-vala/src/module/xep/0085_chat_state_notifications.vala 2023-03-02 00:30:00.000000000 +0100 @@ -16,14 +16,12 @@ public signal void chat_state_received(XmppStream stream, Jid jid, string state, MessageStanza stanza); - private SendPipelineListener send_pipeline_listener = new SendPipelineListener(); - /** * "A message stanza that does not contain standard messaging content [...] SHOULD be a state other than <active/>" (0085, 5.6) */ public void send_state(XmppStream stream, Jid jid, string message_type, string state) { MessageStanza message = new MessageStanza() { to=jid, type_=message_type }; - message.stanza.put_node(new StanzaNode.build(state, NS_URI).add_self_xmlns()); + add_state_to_message(message, state); MessageProcessingHints.set_message_hint(message, MessageProcessingHints.HINT_NO_STORE); @@ -32,14 +30,12 @@ public override void attach(XmppStream stream) { stream.get_module(ServiceDiscovery.Module.IDENTITY).add_feature(stream, NS_URI); - stream.get_module(MessageModule.IDENTITY).send_pipeline.connect(send_pipeline_listener); stream.get_module(MessageModule.IDENTITY).received_message.connect(on_received_message); } public override void detach(XmppStream stream) { stream.get_module(ServiceDiscovery.Module.IDENTITY).remove_feature(stream, NS_URI); stream.get_module(MessageModule.IDENTITY).received_message.disconnect(on_received_message); - stream.get_module(MessageModule.IDENTITY).send_pipeline.disconnect(send_pipeline_listener); } public override string get_ns() { return NS_URI; } @@ -57,19 +53,8 @@ } } -public class SendPipelineListener : StanzaListener<MessageStanza> { - - private string[] after_actions_const = {"MODIFY_BODY"}; - - public override string action_group { get { return "ADD_NODES"; } } - public override string[] after_actions { get { return after_actions_const; } } - - public override async bool run(XmppStream stream, MessageStanza message) { - if (message.body == null) return false; - if (message.type_ != MessageStanza.TYPE_CHAT) return false; - message.stanza.put_node(new StanzaNode.build(STATE_ACTIVE, NS_URI).add_self_xmlns()); - return false; - } +public static void add_state_to_message(MessageStanza message, string state) { + message.stanza.put_node(new StanzaNode.build(state, NS_URI).add_self_xmlns()); } }