diff --git a/CHANGELOG.md b/CHANGELOG.md index e233f6d7e..a3db1204e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,10 @@ * target Android 15 * improve readability of info messages in dark mode +* drop too short disappearing messages options * fix Direct Share shortcuts * fix: don't show error message when cancelling profile creation +* enable permanent notification by default if push notifications are not available ## v2.11.0 2025-08 diff --git a/flake.lock b/flake.lock index 4bd2500b4..290045b63 100644 --- a/flake.lock +++ b/flake.lock @@ -7,11 +7,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1733948466, - "narHash": "sha256-o/uq/tU458Ykudi8Zk3sRga5iazkuSczt9wDOCUDOSU=", + "lastModified": 1756239746, + "narHash": "sha256-0ibN685tT+u/Nbmbrrq9G3mRUzct2Votyv/a7Wwv26s=", "owner": "tadfisher", "repo": "android-nixpkgs", - "rev": "0bf99ffaea6a7c0948ae10cf2e40c2905e4e4d6b", + "rev": "256631d162ec883b2341ee59621516e1f65f0f6b", "type": "github" }, "original": { @@ -28,11 +28,11 @@ ] }, "locked": { - "lastModified": 1728330715, - "narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=", + "lastModified": 1741473158, + "narHash": "sha256-kWNaq6wQUbUMlPgw8Y+9/9wP0F8SHkjy24/mN3UAppg=", "owner": "numtide", "repo": "devshell", - "rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef", + "rev": "7c9e793ebe66bcba8292989a68c0419b737a22a0", "type": "github" }, "original": { @@ -79,11 +79,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1733759999, - "narHash": "sha256-463SNPWmz46iLzJKRzO3Q2b0Aurff3U1n0nYItxq7jU=", + "lastModified": 1756125398, + "narHash": "sha256-XexyKZpf46cMiO5Vbj+dWSAXOnr285GHsMch8FBoHbc=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a73246e2eef4c6ed172979932bc80e1404ba2d56", + "rev": "3b9f00d7a7bf68acd4c4abb9d43695afb04e03a5", "type": "github" }, "original": { @@ -95,11 +95,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1733749988, - "narHash": "sha256-+5qdtgXceqhK5ZR1YbP1fAUsweBIrhL38726oIEAtDs=", + "lastModified": 1756159630, + "narHash": "sha256-ohMvsjtSVdT/bruXf5ClBh8ZYXRmD4krmjKrXhEvwMg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "bc27f0fde01ce4e1bfec1ab122d72b7380278e68", + "rev": "84c256e42600cb0fdf25763b48d28df2f25a0c8b", "type": "github" }, "original": { @@ -138,11 +138,11 @@ "nixpkgs": "nixpkgs_3" }, "locked": { - "lastModified": 1747017456, - "narHash": "sha256-C/U12fcO+HEF071b5mK65lt4XtAIZyJSSJAg9hdlvTk=", + "lastModified": 1756197489, + "narHash": "sha256-S16rPaBH1TnMbDyL5NlGSJcYd7wPlOEWTStdBDL7BHw=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "5b07506ae89b025b14de91f697eba23b48654c52", + "rev": "8ec04f46f1edeeed3f870da62191745b93975da7", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index a7b137f39..f460f5959 100644 --- a/flake.nix +++ b/flake.nix @@ -18,7 +18,7 @@ build-tools-35-0-0 cmdline-tools-latest platform-tools - platforms-android-34 + platforms-android-35 ndk-27-2-12479018 ]); rust-version = pkgs.lib.removeSuffix "\n" diff --git a/src/main/java/com/b44t/messenger/DcAccounts.java b/src/main/java/com/b44t/messenger/DcAccounts.java index 630932408..782979921 100644 --- a/src/main/java/com/b44t/messenger/DcAccounts.java +++ b/src/main/java/com/b44t/messenger/DcAccounts.java @@ -42,4 +42,14 @@ public class DcAccounts { private native long getJsonrpcInstanceCPtr (); private native long getAccountCPtr (int accountId); private native long getSelectedAccountCPtr (); + + public boolean isAllChatmail() { + for (int accountId : getAll()) { + DcContext dcContext = getAccount(accountId); + if (!dcContext.isChatmail()) { + return false; + } + } + return true; + } } diff --git a/src/main/java/org/thoughtcrime/securesms/EphemeralMessagesDialog.java b/src/main/java/org/thoughtcrime/securesms/EphemeralMessagesDialog.java index ecc0881cf..338660eef 100644 --- a/src/main/java/org/thoughtcrime/securesms/EphemeralMessagesDialog.java +++ b/src/main/java/org/thoughtcrime/securesms/EphemeralMessagesDialog.java @@ -60,14 +60,12 @@ public class EphemeralMessagesDialog { .setPositiveButton(R.string.ok, (dialog, which) -> { final long burnAfter; switch (selectedChoice[0]) { - case 1: burnAfter = TimeUnit.MINUTES.toSeconds(1); break; - case 2: burnAfter = TimeUnit.MINUTES.toSeconds(5); break; - case 3: burnAfter = TimeUnit.MINUTES.toSeconds(30); break; - case 4: burnAfter = TimeUnit.HOURS.toSeconds(1); break; - case 5: burnAfter = TimeUnit.DAYS.toSeconds(1); break; - case 6: burnAfter = TimeUnit.DAYS.toSeconds(7); break; - case 7: burnAfter = TimeUnit.DAYS.toSeconds(35); break; - case 8: burnAfter = TimeUnit.DAYS.toSeconds(365); break; + case 1: burnAfter = TimeUnit.MINUTES.toSeconds(5); break; + case 2: burnAfter = TimeUnit.HOURS.toSeconds(1); break; + case 3: burnAfter = TimeUnit.DAYS.toSeconds(1); break; + case 4: burnAfter = TimeUnit.DAYS.toSeconds(7); break; + case 5: burnAfter = TimeUnit.DAYS.toSeconds(35); break; + case 6: burnAfter = TimeUnit.DAYS.toSeconds(365); break; default: burnAfter = 0; break; } listener.onTimeSelected(burnAfter); @@ -84,30 +82,23 @@ public class EphemeralMessagesDialog { if (timespan == 0) { return 0; // off } - // Choose timespan close to the current one out of available options. - if (timespan < TimeUnit.MINUTES.toSeconds(5)) { - return 1; // 1 minute - } - if (timespan < TimeUnit.MINUTES.toSeconds(30)) { - return 2; // 5 minutes - } if (timespan < TimeUnit.HOURS.toSeconds(1)) { - return 3; // 30 minutes + return 1; // 5 minutes } if (timespan < TimeUnit.DAYS.toSeconds(1)) { - return 4; // 1 hour + return 2; // 1 hour } if (timespan < TimeUnit.DAYS.toSeconds(7)) { - return 5; // 1 day + return 3; // 1 day } if (timespan < TimeUnit.DAYS.toSeconds(35)) { - return 6; // 1 week + return 4; // 1 week } if (timespan < TimeUnit.DAYS.toSeconds(365)) { - return 7; // 5 weeks + return 5; // 5 weeks } - return 8; // 1 year + return 6; // 1 year } } diff --git a/src/main/java/org/thoughtcrime/securesms/components/reminder/DozeReminder.java b/src/main/java/org/thoughtcrime/securesms/components/reminder/DozeReminder.java index a6bcab74c..611dc8a6b 100644 --- a/src/main/java/org/thoughtcrime/securesms/components/reminder/DozeReminder.java +++ b/src/main/java/org/thoughtcrime/securesms/components/reminder/DozeReminder.java @@ -109,18 +109,9 @@ public class DozeReminder { } } - private static boolean isAllChatmail() { - for (int accountId : ApplicationContext.dcAccounts.getAll()) { - DcContext context = ApplicationContext.dcAccounts.getAccount(accountId); - if (!context.isChatmail()) { - return false; - } - } - return true; - } - private static boolean isPushAvailableAndSufficient() { - return isAllChatmail() && FcmReceiveService.getToken() != null; + return ApplicationContext.dcAccounts.isAllChatmail() + && FcmReceiveService.getToken() != null; } public static void maybeAskDirectly(Context context) { diff --git a/src/main/java/org/thoughtcrime/securesms/preferences/NotificationsPreferenceFragment.java b/src/main/java/org/thoughtcrime/securesms/preferences/NotificationsPreferenceFragment.java index 2356e89d0..47f663f48 100644 --- a/src/main/java/org/thoughtcrime/securesms/preferences/NotificationsPreferenceFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/preferences/NotificationsPreferenceFragment.java @@ -30,7 +30,7 @@ import org.thoughtcrime.securesms.connect.DcHelper; import org.thoughtcrime.securesms.connect.KeepAliveService; import org.thoughtcrime.securesms.util.Prefs; -public class NotificationsPreferenceFragment extends ListSummaryPreferenceFragment { +public class NotificationsPreferenceFragment extends ListSummaryPreferenceFragment implements Preference.OnPreferenceChangeListener { private static final String TAG = NotificationsPreferenceFragment.class.getSimpleName(); private static final int REQUEST_CODE_NOTIFICATION_SELECTED = 1; @@ -38,6 +38,7 @@ public class NotificationsPreferenceFragment extends ListSummaryPreferenceFragme private CheckBoxPreference ignoreBattery; private CheckBoxPreference notificationsEnabled; private CheckBoxPreference mentionNotifEnabled; + private CheckBoxPreference reliableService; @Override public void onCreate(Bundle paramBundle) { @@ -85,18 +86,12 @@ public class NotificationsPreferenceFragment extends ListSummaryPreferenceFragme } - CheckBoxPreference reliableService = this.findPreference("pref_reliable_service"); + // reliableService is just used for displaying the actual value + // of the reliable service preference that is managed via + // Prefs.setReliableService() and Prefs.reliableService() + reliableService = this.findPreference("pref_reliable_service2"); if (reliableService != null) { - reliableService.setOnPreferenceChangeListener((preference, newValue) -> { - Context context = getContext(); - boolean enabled = (Boolean) newValue; // Prefs.reliableService() still has the old value - if (enabled) { - KeepAliveService.startSelf(context); - } else { - context.stopService(new Intent(context, KeepAliveService.class)); - } - return true; - }); + reliableService.setOnPreferenceChangeListener(this); } notificationsEnabled = this.findPreference("pref_enable_notifications"); @@ -132,6 +127,11 @@ public class NotificationsPreferenceFragment extends ListSummaryPreferenceFragme ignoreBattery.setChecked(isIgnoringBatteryOptimizations()); notificationsEnabled.setChecked(!dcContext.isMuted()); mentionNotifEnabled.setChecked(dcContext.isMentionsEnabled()); + + // set without altering "unset" state of the preference + reliableService.setOnPreferenceChangeListener(null); + reliableService.setChecked(Prefs.reliableService(getActivity())); + reliableService.setOnPreferenceChangeListener(this); } @Override @@ -150,6 +150,19 @@ public class NotificationsPreferenceFragment extends ListSummaryPreferenceFragme } } + @Override + public boolean onPreferenceChange(@NonNull Preference preference, Object newValue) { + Context context = getContext(); + boolean enabled = (Boolean) newValue; + Prefs.setReliableService(context, enabled); + if (enabled) { + KeepAliveService.startSelf(context); + } else { + context.stopService(new Intent(context, KeepAliveService.class)); + } + return true; + } + private class RingtoneSummaryListener implements Preference.OnPreferenceChangeListener { @Override public boolean onPreferenceChange(@NonNull Preference preference, Object newValue) { diff --git a/src/main/java/org/thoughtcrime/securesms/util/Prefs.java b/src/main/java/org/thoughtcrime/securesms/util/Prefs.java index 4df6b2deb..b7a3ee0c4 100644 --- a/src/main/java/org/thoughtcrime/securesms/util/Prefs.java +++ b/src/main/java/org/thoughtcrime/securesms/util/Prefs.java @@ -12,10 +12,12 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; +import com.b44t.messenger.DcAccounts; import com.b44t.messenger.DcContext; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.connect.DcHelper; +import org.thoughtcrime.securesms.notifications.FcmReceiveService; import org.thoughtcrime.securesms.preferences.widgets.NotificationPrivacyPreference; import java.util.ArrayList; @@ -28,6 +30,7 @@ public class Prefs { private static final String TAG = Prefs.class.getSimpleName(); + public static final String RELIABLE_SERVICE_PREF = "pref_reliable_service"; public static final String DISABLE_PASSPHRASE_PREF = "pref_disable_passphrase"; public static final String THEME_PREF = "pref_theme"; public static final String BACKGROUND_PREF = "pref_chat_background"; @@ -212,13 +215,20 @@ public class Prefs { return result==null? null : Uri.parse(result); } + public static void setReliableService(Context context, boolean value) { + setBooleanPreference(context, RELIABLE_SERVICE_PREF, value); + } + public static boolean reliableService(Context context) { - try { - return getBooleanPreference(context, "pref_reliable_service", false); - } - catch(Exception e) { - return false; + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + if (prefs.contains(RELIABLE_SERVICE_PREF)) { + try { + return prefs.getBoolean(RELIABLE_SERVICE_PREF, true); + } catch(Exception e) {} } + + // if the key was unset, then calculate default value + return isPushEnabled(context) || !DcHelper.getAccounts(context).isAllChatmail(); } // vibrate diff --git a/src/main/res/values/arrays.xml b/src/main/res/values/arrays.xml index c48e1bf4f..1d7556af4 100644 --- a/src/main/res/values/arrays.xml +++ b/src/main/res/values/arrays.xml @@ -49,14 +49,12 @@ @string/off - @string/after_1_minute - @string/after_5_minutes - @string/after_30_minutes - @string/autodel_after_1_hour - @string/autodel_after_1_day - @string/autodel_after_1_week - @string/after_5_weeks - @string/autodel_after_1_year + @string/after_5_minutes + @string/autodel_after_1_hour + @string/autodel_after_1_day + @string/autodel_after_1_week + @string/after_5_weeks + @string/autodel_after_1_year diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index cced2242a..8914a2144 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -240,12 +240,6 @@ Chat with… Clone Chat - - Broadcast List - - Broadcast Lists - - New Broadcast List Channel @@ -253,12 +247,6 @@ New Channel Add Recipients - - Edit Broadcast List - - Broadcast List Name - - Please enter a name for the broadcast list. Channel Name E-Mail @@ -424,8 +412,6 @@ Chat with %1$s? Remove %1$s from group? - - Remove %1$s from broadcast list? Remove %1$s from channel? Do you want to open this link? @@ -457,8 +443,6 @@ Send a message to %1$s. - - In a broadcast list, recipients will receive messages in a read-only chat with you. Channels are a one-to-many tool for broadcasting your messages. Others will only see this group after you sent a first message. @@ -569,11 +553,6 @@ Square Grid Send Message - - %1$s changed their address from %2$s to %3$s - - You changed your email address from %1$s to %2$s.\n\nIf you now send a message to a verified group, contacts there will automatically replace the old with your new address.\n\nIt\'s highly advised to set up your old email provider to forward all emails to your new email address. Otherwise you might miss messages of contacts who did not get your new address yet. - @@ -975,14 +954,8 @@ You set disappearing messages timer to %1$s weeks. Disappearing messages timer set to %1$s weeks by %2$s. - - %1$s sent a message from another device. Messages are end-to-end encrypted. Tap to learn more. All messages in this chat are end-to-end encrypted.\n\nEnd-to-end encryption keeps messages private between you and your chat partners. Not even servers, providers or relays can read them. - - %1$s sent a message from another device. Tap to learn more. - - End-to-end encryption cannot be guaranteed anymore, likely because %1$s reinstalled Delta Chat or sent a message from another device.\n\nYou may meet them in person and scan their QR code again to reestablish guaranteed end-to-end encryption. ⚠️ %1$s requires end-to-end encryption which is not setup for this chat yet. Tap to learn more. To establish end-to-end-encryption, you may meet contacts in person and scan their QR Code to introduce them. Learn More @@ -1041,19 +1014,11 @@ %1$s replied, waiting for being added to the group… Establishing end-to-end encryption, please wait… - - Could not yet establish guaranteed end-to-end encryption, but you may already send a message. - - The contact must be online to proceed.\n\nThis process will continue automatically in background. %1$s introduced. - - Cannot establish end-to-end encryption with %1$s. Introduced by %1$s Introduced by me Introduced - - Changed setup for %1$s. To guarantee end-to-end-encryption, you can only add contacts with a green checkmark to this group.\n\nYou may meet contacts in person and scan their QR Code to introduce them. Select chat to send the message to @@ -1096,9 +1061,6 @@ Flip Rotate - - Encrypted message - This is the official Delta Chat Desktop app. This software is licensed under GNU GPL version 3 and the source code is available on GitHub. @@ -1213,7 +1175,6 @@ Delta Chat wants to save images to your photo library. Delta Chat can use Face ID to protect your local profile, backup creation and second device setup. - Instant Delivery Use Background Connection @@ -1228,8 +1189,4 @@ What\'s new?\n\n💯 End-to-end encryption is reliable and forever now. Padlocks 🔒 are gone!\n\n✉️ Classic email without end-to-end encryption is marked with a letter symbol\n\n😻 New enhanced profile screen for all your contacts\n\n🔲 New button for quick access to apps used in a chat\n\n❤️ Please donate to help us remain independent and continue to bring improvements: %1$s - - What\'s new?\n\n❤️‍🔥 New emojis picker with more emoji\n\n🎮 Enhanced in-chat apps: Get notifications and open supporting apps in context, i.e. open an added calendar entry directly\n\n👍 Get notified about reactions to your messages\n\n... 🛠️ FIXES and EVEN MORE at %1$s - - ℹ️ \"Switch Profile\" option moved: Tap your profile image in the upper corner of the main screen to add or switch profiles 💡 diff --git a/src/main/res/xml/preferences_notifications.xml b/src/main/res/xml/preferences_notifications.xml index 612b34c6f..b96873fc6 100644 --- a/src/main/res/xml/preferences_notifications.xml +++ b/src/main/res/xml/preferences_notifications.xml @@ -64,7 +64,7 @@ android:summary="@string/pref_background_notifications_explain"/>