From 716dfa6577ab5d28690301d003d5e574476df681 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Fri, 22 Nov 2024 17:23:05 +0100 Subject: [PATCH 01/11] Add permanent hint when battery optimization is not ignored Also add an option to not show the hint, when user doesn't want to ignore battery optimization. Only show these features when gplay services are available. Otherwise don't show them as it would pretend notifications would be possible without gplay. Signed-off-by: Marcel Hibbe --- .../ConversationsListActivity.kt | 67 ++++++++++++------- .../talk/settings/SettingsActivity.kt | 14 ++++ .../utils/preferences/AppPreferences.java | 3 + .../utils/preferences/AppPreferencesImpl.kt | 14 ++++ .../res/layout/activity_conversations.xml | 12 ++++ app/src/main/res/layout/activity_settings.xml | 35 ++++++++++ app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/strings.xml | 2 + 8 files changed, 123 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index 68b0e14e1..46d52cbdc 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -273,6 +273,12 @@ class ConversationsListActivity : adapter!!.addListener(this) prepareViews() + if (shouldShowIgnoreBatteryOptimizationHint()) { + showIgnoreBatteryOptimizationHint() + } else { + binding.chatListBatteryOptimizationIgnoredHint.visibility = View.GONE + } + showShareToScreen = hasActivityActionSendIntent() if (!eventBus.isRegistered(this)) { @@ -1453,32 +1459,8 @@ class ConversationsListActivity : } REQUEST_POST_NOTIFICATIONS_PERMISSION -> { - // whenever user allowed notifications, also check to ignore battery optimization if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - if (!PowerManagerUtils().isIgnoringBatteryOptimizations() && - ClosedInterfaceImpl().isGooglePlayServicesAvailable - ) { - val dialogText = String.format( - context.resources.getString(R.string.nc_ignore_battery_optimization_dialog_text), - context.resources.getString(R.string.nc_app_name) - ) - - val dialogBuilder = MaterialAlertDialogBuilder(this) - .setTitle(R.string.nc_ignore_battery_optimization_dialog_title) - .setMessage(dialogText) - .setPositiveButton(R.string.nc_ok) { _, _ -> - startActivity( - Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS) - ) - } - .setNegativeButton(R.string.nc_common_dismiss, null) - viewThemeUtils.dialog.colorMaterialAlertDialogBackground(this, dialogBuilder) - val dialog = dialogBuilder.show() - viewThemeUtils.platform.colorTextButtons( - dialog.getButton(AlertDialog.BUTTON_POSITIVE), - dialog.getButton(AlertDialog.BUTTON_NEGATIVE) - ) - } + Log.d(TAG, "Notification permission was granted") } else { Log.d( TAG, @@ -1490,6 +1472,41 @@ class ConversationsListActivity : } } + @SuppressLint("StringFormatInvalid") + private fun showIgnoreBatteryOptimizationHint() { + binding.chatListBatteryOptimizationIgnoredHint.visibility = View.VISIBLE + + val dialogText = String.format( + context.resources.getString(R.string.nc_ignore_battery_optimization_dialog_text), + context.resources.getString(R.string.nc_app_name) + ) + + val dialogBuilder = MaterialAlertDialogBuilder(this) + .setTitle(R.string.nc_ignore_battery_optimization_dialog_title) + .setMessage(dialogText) + .setPositiveButton(R.string.nc_ok) { _, _ -> + startActivity( + Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS) + ) + } + .setNegativeButton(R.string.nc_common_dismiss, null) + viewThemeUtils.dialog.colorMaterialAlertDialogBackground(this, dialogBuilder) + + binding.chatListBatteryOptimizationIgnoredHint.setOnClickListener { + val dialog = dialogBuilder.show() + viewThemeUtils.platform.colorTextButtons( + dialog.getButton(AlertDialog.BUTTON_POSITIVE), + dialog.getButton(AlertDialog.BUTTON_NEGATIVE) + ) + } + } + + private fun shouldShowIgnoreBatteryOptimizationHint() : Boolean { + return !PowerManagerUtils().isIgnoringBatteryOptimizations() && + ClosedInterfaceImpl().isGooglePlayServicesAvailable && + appPreferences.getShowIgnoreBatteryOptimizationHint() + } + private fun openConversation(textToPaste: String? = "") { if (CallActivity.active && selectedConversation!!.token != ApplicationWideCurrentRoomHolder.getInstance().currentRoomToken diff --git a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt index 72a7e9795..493bcae75 100644 --- a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt @@ -662,6 +662,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu private fun themeSwitchPreferences() { binding.run { listOf( + settingsShowIgnoreBatteryOptimizationHintSwitch, settingsScreenLockSwitch, settingsScreenSecuritySwitch, settingsIncognitoKeyboardSwitch, @@ -857,6 +858,19 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu } private fun setupCheckables() { + binding.settingsShowIgnoreBatteryOptimizationHintSwitch.isChecked = + appPreferences.showIgnoreBatteryOptimizationHint + + if (ClosedInterfaceImpl().isGooglePlayServicesAvailable) { + binding.settingsShowIgnoreBatteryOptimizationHint.setOnClickListener { + val isChecked = binding.settingsShowIgnoreBatteryOptimizationHintSwitch.isChecked + binding.settingsShowIgnoreBatteryOptimizationHintSwitch.isChecked = !isChecked + appPreferences.setShowIgnoreBatteryOptimizationHint(!isChecked) + } + } else { + binding.settingsShowIgnoreBatteryOptimizationHint.visibility = View.GONE + } + binding.settingsScreenSecuritySwitch.isChecked = appPreferences.isScreenSecured binding.settingsIncognitoKeyboardSwitch.isChecked = appPreferences.isKeyboardIncognito diff --git a/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferences.java b/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferences.java index 606614a72..b779337ed 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferences.java +++ b/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferences.java @@ -178,6 +178,9 @@ public interface AppPreferences { void deleteAllMessageQueuesFor(String userId); + boolean getShowIgnoreBatteryOptimizationHint(); + + void setShowIgnoreBatteryOptimizationHint(boolean showIgnoreBatteryOptimizationHint); void clear(); } diff --git a/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferencesImpl.kt b/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferencesImpl.kt index c3e2fcc48..6a913ea19 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferencesImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferencesImpl.kt @@ -544,6 +544,19 @@ class AppPreferencesImpl(val context: Context) : AppPreferences { } } + override fun getShowIgnoreBatteryOptimizationHint(): Boolean { + return runBlocking { async { + readBoolean(SHOW_IGNORE_BATTERY_OPTIMIZATION_HINT, true).first() + } }.getCompleted() + } + + override fun setShowIgnoreBatteryOptimizationHint(showIgnoreBatteryOptimizationHint: Boolean) = + runBlocking { + async { + writeBoolean(SHOW_IGNORE_BATTERY_OPTIMIZATION_HINT, showIgnoreBatteryOptimizationHint) + } + } + override fun clear() {} private suspend fun writeString(key: String, value: String) = @@ -628,6 +641,7 @@ class AppPreferencesImpl(val context: Context) : AppPreferences { const val PHONE_BOOK_INTEGRATION_LAST_RUN = "phone_book_integration_last_run" const val TYPING_STATUS = "typing_status" const val MESSAGE_QUEUE = "@message_queue" + const val SHOW_IGNORE_BATTERY_OPTIMIZATION_HINT = "show_ignore_battery_optimization_hint" private fun String.convertStringToArray(): Array { var varString = this val floatList = mutableListOf() diff --git a/app/src/main/res/layout/activity_conversations.xml b/app/src/main/res/layout/activity_conversations.xml index bdf5880e1..0c71bb4ba 100644 --- a/app/src/main/res/layout/activity_conversations.xml +++ b/app/src/main/res/layout/activity_conversations.xml @@ -37,6 +37,18 @@ android:visibility="gone" tools:visibility="visible" /> + + + + + + + + + + + + + + #99000000 #EF3B02 #DBE2E9 + #FF9800 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ca4c364cf..01f10ccdf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -181,6 +181,8 @@ How to translate with transifex: Ignore battery optimization Battery optimization is not ignored. This should be changed to make sure that notifications work in the background! Please click OK and select \"All apps\" -> %1$s -> Do not optimize + Show battery optimization hint + When the battery optimization is not ignored, show a hint Meta information Generation of system report From b1e550b049a28dcf8b174828da75f2211ee428bc Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 25 Nov 2024 13:18:51 +0100 Subject: [PATCH 02/11] Show a warning if notifications are not allowed or battery optimization is enabled Open notification settings when click on warning Also, still offer to enable notifications and disable battery optimization on first install Signed-off-by: Marcel Hibbe --- .../ConversationsListActivity.kt | 89 +++++++++++-------- .../talk/settings/SettingsActivity.kt | 42 ++++++--- .../nextcloud/talk/utils/bundle/BundleKeys.kt | 1 + .../utils/preferences/AppPreferences.java | 4 +- .../utils/preferences/AppPreferencesImpl.kt | 10 +-- .../res/layout/activity_conversations.xml | 4 +- app/src/main/res/layout/activity_settings.xml | 74 +++++++-------- app/src/main/res/values/strings.xml | 6 +- 8 files changed, 135 insertions(+), 95 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index 46d52cbdc..f9807199e 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -121,6 +121,7 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FORWARD_MSG_TEXT import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NEW_CONVERSATION import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN +import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SCROLL_TO_NOTIFICATION_CATEGORY import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SHARED_TEXT import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil import com.nextcloud.talk.utils.power.PowerManagerUtils @@ -273,11 +274,7 @@ class ConversationsListActivity : adapter!!.addListener(this) prepareViews() - if (shouldShowIgnoreBatteryOptimizationHint()) { - showIgnoreBatteryOptimizationHint() - } else { - binding.chatListBatteryOptimizationIgnoredHint.visibility = View.GONE - } + updateNotificationWarning() showShareToScreen = hasActivityActionSendIntent() @@ -309,6 +306,14 @@ class ConversationsListActivity : showSearchOrToolbar() } + private fun updateNotificationWarning() { + if (shouldShowNotificationWarning()) { + showNotificationWarning() + } else { + binding.chatListNotificationWarning.visibility = View.GONE + } + } + private fun initObservers() { this.lifecycleScope.launch { networkMonitor.isOnline.onEach { isOnline -> @@ -1461,6 +1466,31 @@ class ConversationsListActivity : REQUEST_POST_NOTIFICATIONS_PERMISSION -> { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Log.d(TAG, "Notification permission was granted") + + if (!PowerManagerUtils().isIgnoringBatteryOptimizations() && + ClosedInterfaceImpl().isGooglePlayServicesAvailable + ) { + val dialogText = String.format( + context.resources.getString(R.string.nc_ignore_battery_optimization_dialog_text), + context.resources.getString(R.string.nc_app_name) + ) + + val dialogBuilder = MaterialAlertDialogBuilder(this) + .setTitle(R.string.nc_ignore_battery_optimization_dialog_title) + .setMessage(dialogText) + .setPositiveButton(R.string.nc_ok) { _, _ -> + startActivity( + Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS) + ) + } + .setNegativeButton(R.string.nc_common_dismiss, null) + viewThemeUtils.dialog.colorMaterialAlertDialogBackground(this, dialogBuilder) + val dialog = dialogBuilder.show() + viewThemeUtils.platform.colorTextButtons( + dialog.getButton(AlertDialog.BUTTON_POSITIVE), + dialog.getButton(AlertDialog.BUTTON_NEGATIVE) + ) + } } else { Log.d( TAG, @@ -1472,39 +1502,28 @@ class ConversationsListActivity : } } - @SuppressLint("StringFormatInvalid") - private fun showIgnoreBatteryOptimizationHint() { - binding.chatListBatteryOptimizationIgnoredHint.visibility = View.VISIBLE - - val dialogText = String.format( - context.resources.getString(R.string.nc_ignore_battery_optimization_dialog_text), - context.resources.getString(R.string.nc_app_name) - ) - - val dialogBuilder = MaterialAlertDialogBuilder(this) - .setTitle(R.string.nc_ignore_battery_optimization_dialog_title) - .setMessage(dialogText) - .setPositiveButton(R.string.nc_ok) { _, _ -> - startActivity( - Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS) - ) - } - .setNegativeButton(R.string.nc_common_dismiss, null) - viewThemeUtils.dialog.colorMaterialAlertDialogBackground(this, dialogBuilder) - - binding.chatListBatteryOptimizationIgnoredHint.setOnClickListener { - val dialog = dialogBuilder.show() - viewThemeUtils.platform.colorTextButtons( - dialog.getButton(AlertDialog.BUTTON_POSITIVE), - dialog.getButton(AlertDialog.BUTTON_NEGATIVE) - ) + private fun showNotificationWarning() { + binding.chatListNotificationWarning.visibility = View.VISIBLE + binding.chatListNotificationWarning.setOnClickListener { + val bundle = Bundle() + bundle.putBoolean(KEY_SCROLL_TO_NOTIFICATION_CATEGORY, true) + val settingsIntent = Intent(context, SettingsActivity::class.java) + settingsIntent.putExtras(bundle) + startActivity(settingsIntent) } } - private fun shouldShowIgnoreBatteryOptimizationHint() : Boolean { - return !PowerManagerUtils().isIgnoringBatteryOptimizations() && - ClosedInterfaceImpl().isGooglePlayServicesAvailable && - appPreferences.getShowIgnoreBatteryOptimizationHint() + private fun shouldShowNotificationWarning() : Boolean { + val notificationPermissionNotGranted = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && + !platformPermissionUtil.isPostNotificationsPermissionGranted() + val batteryOptimizationNotIgnored = !PowerManagerUtils().isIgnoringBatteryOptimizations() + + val settingsOfUserAreWrong = notificationPermissionNotGranted || batteryOptimizationNotIgnored + val userWantsToBeNotifiedAboutWrongSettings = appPreferences.getShowNotificationWarning() + + return settingsOfUserAreWrong && + userWantsToBeNotifiedAboutWrongSettings && + ClosedInterfaceImpl().isGooglePlayServicesAvailable } private fun openConversation(textToPaste: String? = "") { diff --git a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt index 493bcae75..da04c9305 100644 --- a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt @@ -77,6 +77,7 @@ import com.nextcloud.talk.utils.NotificationUtils.getCallRingtoneUri import com.nextcloud.talk.utils.NotificationUtils.getMessageRingtoneUri import com.nextcloud.talk.utils.SecurityUtils import com.nextcloud.talk.utils.SpreedFeatures +import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SCROLL_TO_NOTIFICATION_CATEGORY import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil import com.nextcloud.talk.utils.power.PowerManagerUtils import com.nextcloud.talk.utils.preferences.AppPreferencesImpl @@ -129,6 +130,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu private lateinit var phoneBookIntegrationFlow: Flow private var profileQueryDisposable: Disposable? = null private var dbQueryDisposable: Disposable? = null + private var scrollToNotificationCategory: Boolean? = false @SuppressLint("StringFormatInvalid") override fun onCreate(savedInstanceState: Bundle?) { @@ -143,6 +145,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu binding.avatarImage.let { ViewCompat.setTransitionName(it, "userAvatar.transitionTag") } getCurrentUser() + handleIntent(intent) setupLicenceSetting() @@ -162,6 +165,11 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu setupClientCertView() } + private fun handleIntent(intent: Intent) { + val extras: Bundle? = intent.extras + scrollToNotificationCategory = extras?.getBoolean(KEY_SCROLL_TO_NOTIFICATION_CATEGORY) + } + override fun onResume() { super.onResume() supportActionBar?.show() @@ -210,6 +218,21 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu themeTitles() themeSwitchPreferences() + + if (scrollToNotificationCategory == true) { + scrollToNotificationCategory() + } + } + + private fun scrollToNotificationCategory() { + binding.scrollView.post { + val scrollViewLocation = IntArray(2) + val targetLocation = IntArray(2) + binding.scrollView.getLocationOnScreen(scrollViewLocation) + binding.settingsNotificationsCategory.getLocationOnScreen(targetLocation) + val offset = targetLocation[1] - scrollViewLocation[1] + binding.scrollView.smoothScrollBy(0, offset) + } } private fun loadCapabilitiesAndUpdateSettings() { @@ -255,9 +278,6 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu } private fun setupNotificationSettings() { - binding.settingsNotificationsTitle.text = resources!!.getString( - R.string.nc_settings_notification_sounds_post_oreo - ) setupNotificationSoundsSettings() setupNotificationPermissionSettings() } @@ -662,7 +682,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu private fun themeSwitchPreferences() { binding.run { listOf( - settingsShowIgnoreBatteryOptimizationHintSwitch, + settingsShowNotificationWarningSwitch, settingsScreenLockSwitch, settingsScreenSecuritySwitch, settingsIncognitoKeyboardSwitch, @@ -858,17 +878,17 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu } private fun setupCheckables() { - binding.settingsShowIgnoreBatteryOptimizationHintSwitch.isChecked = - appPreferences.showIgnoreBatteryOptimizationHint + binding.settingsShowNotificationWarningSwitch.isChecked = + appPreferences.showNotificationWarning if (ClosedInterfaceImpl().isGooglePlayServicesAvailable) { - binding.settingsShowIgnoreBatteryOptimizationHint.setOnClickListener { - val isChecked = binding.settingsShowIgnoreBatteryOptimizationHintSwitch.isChecked - binding.settingsShowIgnoreBatteryOptimizationHintSwitch.isChecked = !isChecked - appPreferences.setShowIgnoreBatteryOptimizationHint(!isChecked) + binding.settingsShowNotificationWarning.setOnClickListener { + val isChecked = binding.settingsShowNotificationWarningSwitch.isChecked + binding.settingsShowNotificationWarningSwitch.isChecked = !isChecked + appPreferences.setShowNotificationWarning(!isChecked) } } else { - binding.settingsShowIgnoreBatteryOptimizationHint.visibility = View.GONE + binding.settingsShowNotificationWarning.visibility = View.GONE } binding.settingsScreenSecuritySwitch.isChecked = appPreferences.isScreenSecured diff --git a/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt b/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt index 53de01b27..4080f315a 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt @@ -80,4 +80,5 @@ object BundleKeys { const val KEY_CREDENTIALS: String = "KEY_CREDENTIALS" const val KEY_FIELD_MAP: String = "KEY_FIELD_MAP" const val KEY_CHAT_URL: String = "KEY_CHAT_URL" + const val KEY_SCROLL_TO_NOTIFICATION_CATEGORY: String = "KEY_SCROLL_TO_NOTIFICATION_CATEGORY" } diff --git a/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferences.java b/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferences.java index b779337ed..ffe3e063b 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferences.java +++ b/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferences.java @@ -178,9 +178,9 @@ public interface AppPreferences { void deleteAllMessageQueuesFor(String userId); - boolean getShowIgnoreBatteryOptimizationHint(); + boolean getShowNotificationWarning(); - void setShowIgnoreBatteryOptimizationHint(boolean showIgnoreBatteryOptimizationHint); + void setShowNotificationWarning(boolean showNotificationWarning); void clear(); } diff --git a/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferencesImpl.kt b/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferencesImpl.kt index 6a913ea19..a576fe9a0 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferencesImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/preferences/AppPreferencesImpl.kt @@ -544,16 +544,16 @@ class AppPreferencesImpl(val context: Context) : AppPreferences { } } - override fun getShowIgnoreBatteryOptimizationHint(): Boolean { + override fun getShowNotificationWarning(): Boolean { return runBlocking { async { - readBoolean(SHOW_IGNORE_BATTERY_OPTIMIZATION_HINT, true).first() + readBoolean(SHOW_NOTIFICATION_WARNING, true).first() } }.getCompleted() } - override fun setShowIgnoreBatteryOptimizationHint(showIgnoreBatteryOptimizationHint: Boolean) = + override fun setShowNotificationWarning(showNotificationWarning: Boolean) = runBlocking { async { - writeBoolean(SHOW_IGNORE_BATTERY_OPTIMIZATION_HINT, showIgnoreBatteryOptimizationHint) + writeBoolean(SHOW_NOTIFICATION_WARNING, showNotificationWarning) } } @@ -641,7 +641,7 @@ class AppPreferencesImpl(val context: Context) : AppPreferences { const val PHONE_BOOK_INTEGRATION_LAST_RUN = "phone_book_integration_last_run" const val TYPING_STATUS = "typing_status" const val MESSAGE_QUEUE = "@message_queue" - const val SHOW_IGNORE_BATTERY_OPTIMIZATION_HINT = "show_ignore_battery_optimization_hint" + const val SHOW_NOTIFICATION_WARNING = "show_notification_warning" private fun String.convertStringToArray(): Array { var varString = this val floatList = mutableListOf() diff --git a/app/src/main/res/layout/activity_conversations.xml b/app/src/main/res/layout/activity_conversations.xml index 0c71bb4ba..7518b482d 100644 --- a/app/src/main/res/layout/activity_conversations.xml +++ b/app/src/main/res/layout/activity_conversations.xml @@ -38,13 +38,13 @@ tools:visibility="visible" /> diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index c69b5b8c7..4011b26a9 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -201,7 +201,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="@dimen/standard_margin" - android:text="@string/nc_settings_notification_sounds" + android:text="@string/nc_settings_notification_sounds_post_oreo" android:textSize="@dimen/headline_text_size" android:textStyle="bold"/> @@ -211,6 +211,42 @@ android:layout_height="wrap_content" android:orientation="vertical"> + + + + + + + + + + + + + - - - - - - - - - - - - - Talk app is not installed on the server you tried to authenticate against Your already existing account was updated, instead of adding a new one The account is scheduled for deletion, and cannot be changed - Notification sounds Notifications Calls call_ringtone @@ -181,8 +180,9 @@ How to translate with transifex: Ignore battery optimization Battery optimization is not ignored. This should be changed to make sure that notifications work in the background! Please click OK and select \"All apps\" -> %1$s -> Do not optimize - Show battery optimization hint - When the battery optimization is not ignored, show a hint + Show notification warning + When notifications are not set up correctly, show a warning + Notifications are not set up correctly Meta information Generation of system report From b63325ae8d527d161aabdc61cf3b49edaee8abdc Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 25 Nov 2024 19:29:09 +0100 Subject: [PATCH 03/11] open full notification settings from talk settings as fallback if dialog for asking direct permission was not shown by android Signed-off-by: Marcel Hibbe --- .../talk/settings/SettingsActivity.kt | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt index da04c9305..61e07ca60 100644 --- a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt @@ -1101,16 +1101,14 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu ConversationsListActivity.REQUEST_POST_NOTIFICATIONS_PERMISSION -> { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_DENIED) { - Snackbar.make( - binding.root, - context.resources.getString(R.string.nc_settings_notifications_declined_hint), - Snackbar.LENGTH_LONG - ).show() - Log.d( - TAG, - "Notification permission is denied. Either because user denied it when being asked. " + - "Or permission is already denied and android decided to not offer the dialog." - ) + try { + val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + intent.putExtra(Settings.EXTRA_APP_PACKAGE, BuildConfig.APPLICATION_ID) + startActivity(intent) + } catch (e: Exception) { + Log.e(TAG, "Failed to open notification settings as fallback", e) + } } } } From c2b99c591ffed520efbf0b8fd94bdb0f44c70423 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 25 Nov 2024 19:55:36 +0100 Subject: [PATCH 04/11] disable sound notification settings when main notification permission is is not permitted. Otherwise user can't enable them anyway Signed-off-by: Marcel Hibbe --- .../talk/settings/SettingsActivity.kt | 10 +++ app/src/main/res/layout/activity_settings.xml | 75 +++++++++---------- 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt index 61e07ca60..558133cb4 100644 --- a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt @@ -333,12 +333,22 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu binding.ncDiagnoseNotificationPermissionSubtitle.setTextColor( resources.getColor(R.color.high_emphasis_text, null) ) + binding.settingsCallSound.isEnabled = true + binding.settingsCallSound.alpha = ENABLED_ALPHA + binding.settingsMessageSound.isEnabled = true + binding.settingsMessageSound.alpha = ENABLED_ALPHA } else { binding.ncDiagnoseNotificationPermissionSubtitle.text = resources.getString(R.string.nc_settings_notifications_declined) binding.ncDiagnoseNotificationPermissionSubtitle.setTextColor( resources.getColor(R.color.nc_darkRed, null) ) + + binding.settingsCallSound.isEnabled = false + binding.settingsCallSound.alpha = DISABLED_ALPHA + binding.settingsMessageSound.isEnabled = false + binding.settingsMessageSound.alpha = DISABLED_ALPHA + binding.settingsNotificationsPermissionWrapper.setOnClickListener { requestPermissions( arrayOf(Manifest.permission.POST_NOTIFICATIONS), diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 4011b26a9..882e885fb 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -247,46 +247,25 @@ - + + + android:text="@string/nc_diagnose_notification_permission" + android:textSize="@dimen/headline_text_size" /> - - - - - - - - - - - + + + + + + + + From a9ec8c2eed46cc610b824945bc0f178d55b929a6 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 25 Nov 2024 20:09:52 +0100 Subject: [PATCH 05/11] fix to hide notification setting for generic build variant Signed-off-by: Marcel Hibbe --- app/src/main/res/layout/activity_settings.xml | 76 ++++++++++--------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 882e885fb..f317aae33 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -245,26 +245,49 @@ android:clickable="false" android:gravity="center_vertical"/> - - - + android:background="?android:attr/selectableItemBackground" + android:orientation="vertical" + android:padding="@dimen/standard_padding"> + + + + + + + + + + + + - - - - - - - - Date: Mon, 25 Nov 2024 22:47:52 +0100 Subject: [PATCH 06/11] blink items when opened by notification warning Signed-off-by: Marcel Hibbe --- .../talk/settings/SettingsActivity.kt | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt index 558133cb4..c33fff0ea 100644 --- a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt @@ -21,6 +21,8 @@ import android.content.Intent import android.content.pm.PackageManager import android.graphics.PorterDuff import android.graphics.drawable.ColorDrawable +import android.graphics.drawable.Drawable +import android.graphics.drawable.RippleDrawable import android.media.RingtoneManager import android.net.Uri import android.os.Build @@ -89,6 +91,7 @@ import io.reactivex.schedulers.Schedulers import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -130,7 +133,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu private lateinit var phoneBookIntegrationFlow: Flow private var profileQueryDisposable: Disposable? = null private var dbQueryDisposable: Disposable? = null - private var scrollToNotificationCategory: Boolean? = false + private var openedByNotificationWarning: Boolean = false @SuppressLint("StringFormatInvalid") override fun onCreate(savedInstanceState: Bundle?) { @@ -167,7 +170,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu private fun handleIntent(intent: Intent) { val extras: Bundle? = intent.extras - scrollToNotificationCategory = extras?.getBoolean(KEY_SCROLL_TO_NOTIFICATION_CATEGORY) + openedByNotificationWarning = extras?.getBoolean(KEY_SCROLL_TO_NOTIFICATION_CATEGORY) ?: false } override fun onResume() { @@ -219,11 +222,12 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu themeTitles() themeSwitchPreferences() - if (scrollToNotificationCategory == true) { + if (openedByNotificationWarning) { scrollToNotificationCategory() } } + @Suppress("MagicNumber") private fun scrollToNotificationCategory() { binding.scrollView.post { val scrollViewLocation = IntArray(2) @@ -231,7 +235,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu binding.scrollView.getLocationOnScreen(scrollViewLocation) binding.settingsNotificationsCategory.getLocationOnScreen(targetLocation) val offset = targetLocation[1] - scrollViewLocation[1] - binding.scrollView.smoothScrollBy(0, offset) + binding.scrollView.scrollBy(0, offset) } } @@ -301,6 +305,10 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu resources!!.getString(R.string.nc_diagnose_battery_optimization_not_ignored) binding.batteryOptimizationIgnored.setTextColor(resources.getColor(R.color.nc_darkRed, null)) + if (openedByNotificationWarning){ + blinkRipple(binding.settingsBatteryOptimizationWrapper.background) + } + binding.settingsBatteryOptimizationWrapper.setOnClickListener { val dialogText = String.format( context.resources.getString(R.string.nc_ignore_battery_optimization_dialog_text), @@ -344,6 +352,10 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu resources.getColor(R.color.nc_darkRed, null) ) + if (openedByNotificationWarning){ + blinkRipple(binding.settingsNotificationsPermissionWrapper.background) + } + binding.settingsCallSound.isEnabled = false binding.settingsCallSound.alpha = DISABLED_ALPHA binding.settingsMessageSound.isEnabled = false @@ -1380,6 +1392,21 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu } } + @Suppress("MagicNumber") + private fun blinkRipple(rippleView: Drawable) { + (rippleView as RippleDrawable).let { rippleDrawable -> + CoroutineScope(Dispatchers.Main).launch { + delay(1000L) // Wait 2 seconds before starting + repeat(3) { + rippleDrawable.state = intArrayOf(android.R.attr.state_pressed, android.R.attr.state_enabled) + delay(250L) // Ripple active duration + rippleDrawable.state = intArrayOf() // Reset state + delay(250L) // Time between blinks + } + } + } + } + companion object { private val TAG = SettingsActivity::class.java.simpleName private const val DURATION: Long = 2500 From c559c6b0b483861ad74d312c24831cbf41a91d30 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 25 Nov 2024 23:00:24 +0100 Subject: [PATCH 07/11] blink notification channels Signed-off-by: Marcel Hibbe --- .../talk/conversationlist/ConversationsListActivity.kt | 8 +++++++- .../java/com/nextcloud/talk/settings/SettingsActivity.kt | 8 ++++++++ app/src/main/res/layout/activity_settings.xml | 5 +++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index f9807199e..c318d6e50 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -110,6 +110,7 @@ import com.nextcloud.talk.utils.ClosedInterfaceImpl import com.nextcloud.talk.utils.ConversationUtils import com.nextcloud.talk.utils.FileUtils import com.nextcloud.talk.utils.Mimetype +import com.nextcloud.talk.utils.NotificationUtils import com.nextcloud.talk.utils.ParticipantPermissions import com.nextcloud.talk.utils.SpreedFeatures import com.nextcloud.talk.utils.UserIdUtils @@ -1518,7 +1519,12 @@ class ConversationsListActivity : !platformPermissionUtil.isPostNotificationsPermissionGranted() val batteryOptimizationNotIgnored = !PowerManagerUtils().isIgnoringBatteryOptimizations() - val settingsOfUserAreWrong = notificationPermissionNotGranted || batteryOptimizationNotIgnored + val messagesChannelNotEnabled = !NotificationUtils.isMessagesNotificationChannelEnabled(this) + val callsChannelNotEnabled = !NotificationUtils.isCallsNotificationChannelEnabled(this) + + val settingsOfUserAreWrong = notificationPermissionNotGranted || batteryOptimizationNotIgnored || + messagesChannelNotEnabled || callsChannelNotEnabled + val userWantsToBeNotifiedAboutWrongSettings = appPreferences.getShowNotificationWarning() return settingsOfUserAreWrong && diff --git a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt index c33fff0ea..8bdba8ccc 100644 --- a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt @@ -388,6 +388,10 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu ResourcesCompat.getColor(context.resources, R.color.nc_darkRed, null) ) binding.callsRingtone.text = resources!!.getString(R.string.nc_common_disabled) + + if (openedByNotificationWarning){ + blinkRipple(binding.settingsCallSound.background) + } } if (NotificationUtils.isMessagesNotificationChannelEnabled(this)) { @@ -399,6 +403,10 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu ResourcesCompat.getColor(context.resources, R.color.nc_darkRed, null) ) binding.messagesRingtone.text = resources!!.getString(R.string.nc_common_disabled) + + if (openedByNotificationWarning){ + blinkRipple(binding.settingsMessageSound.background) + } } binding.settingsCallSound.setOnClickListener { diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index f317aae33..412403443 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -310,6 +310,7 @@ android:id="@+id/settings_call_sound" android:layout_width="match_parent" android:layout_height="wrap_content" + android:background="?android:attr/selectableItemBackground" android:orientation="vertical"> + android:background="?android:attr/selectableItemBackground" + android:orientation="vertical"> Date: Tue, 26 Nov 2024 00:01:33 +0100 Subject: [PATCH 08/11] add check if server notification app is installed for current user Signed-off-by: Marcel Hibbe --- .../ConversationsListActivity.kt | 5 ++- .../talk/settings/SettingsActivity.kt | 20 +++++++++++ app/src/main/res/layout/activity_settings.xml | 35 ++++++++++++++----- app/src/main/res/values/strings.xml | 2 ++ 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index c318d6e50..bfc7bce2c 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -1522,8 +1522,11 @@ class ConversationsListActivity : val messagesChannelNotEnabled = !NotificationUtils.isMessagesNotificationChannelEnabled(this) val callsChannelNotEnabled = !NotificationUtils.isCallsNotificationChannelEnabled(this) + val serverNotificationAppInstalled = + userManager.currentUser.blockingGet().capabilities?.notificationsCapability?.features?.isNotEmpty() ?: false + val settingsOfUserAreWrong = notificationPermissionNotGranted || batteryOptimizationNotIgnored || - messagesChannelNotEnabled || callsChannelNotEnabled + messagesChannelNotEnabled || callsChannelNotEnabled || !serverNotificationAppInstalled val userWantsToBeNotifiedAboutWrongSettings = appPreferences.getShowNotificationWarning() diff --git a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt index 8bdba8ccc..ab3caa003 100644 --- a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt @@ -284,6 +284,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu private fun setupNotificationSettings() { setupNotificationSoundsSettings() setupNotificationPermissionSettings() + setupServerNotificationAppCheck() } @SuppressLint("StringFormatInvalid") @@ -476,6 +477,24 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu } } + private fun setupServerNotificationAppCheck() { + val serverNotificationAppInstalled = + userManager.currentUser.blockingGet().capabilities?.notificationsCapability?.features?.isNotEmpty() ?: false + if (!serverNotificationAppInstalled) { + binding.settingsServerNotificationAppWrapper.visibility = View.VISIBLE + + val description = context.getString(R.string.nc_settings_contact_admin_of) + LINEBREAK + + userManager.currentUser.blockingGet().baseUrl!! + + binding.settingsServerNotificationAppDescription.text = description + if (openedByNotificationWarning) { + blinkRipple(binding.settingsServerNotificationAppWrapper.background) + } + } else { + binding.settingsServerNotificationAppWrapper.visibility = View.GONE + } + } + private fun setupSourceCodeUrl() { if (!TextUtils.isEmpty(resources!!.getString(R.string.nc_source_code_url))) { binding.settingsSourceCode.setOnClickListener { @@ -1421,6 +1440,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu private const val START_DELAY: Long = 5000 private const val DISABLED_ALPHA: Float = 0.38f private const val ENABLED_ALPHA: Float = 1.0f + private const val LINEBREAK = "\n" const val HTTP_CODE_OK: Int = 200 const val HTTP_ERROR_CODE_BAD_REQUEST: Int = 400 } diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 412403443..beb24732f 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -311,12 +311,12 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:attr/selectableItemBackground" - android:orientation="vertical"> + android:orientation="vertical" + android:padding="@dimen/standard_padding"> @@ -324,8 +324,6 @@ android:id="@+id/calls_ringtone" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/standard_margin" - android:layout_marginBottom="@dimen/standard_margin" android:text="@string/nc_settings_default_ringtone" android:textSize="@dimen/supporting_text_text_size"/> @@ -335,12 +333,12 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:attr/selectableItemBackground" - android:orientation="vertical"> + android:orientation="vertical" + android:padding="@dimen/standard_padding"> @@ -348,12 +346,33 @@ android:id="@+id/messages_ringtone" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/standard_margin" - android:layout_marginBottom="@dimen/standard_margin" android:text="@string/nc_settings_default_ringtone" android:textSize="@dimen/supporting_text_text_size"/> + + + + + + + message_ringtone Librem by feandesign No sound + Server notification app not installed + Please contact the administrator of Appearance Theme From 8e6072bbc74b7e270a16204217f930658817ac02 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Tue, 26 Nov 2024 12:35:06 +0100 Subject: [PATCH 09/11] extract blink method, move server notification app hint to gplay block Signed-off-by: Marcel Hibbe --- .../talk/settings/SettingsActivity.kt | 31 +++--------- .../com/nextcloud/talk/utils/DrawableUtils.kt | 27 +++++++++++ app/src/main/res/layout/activity_settings.xml | 47 +++++++++---------- 3 files changed, 56 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt index ab3caa003..5ef8ffe5a 100644 --- a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt @@ -21,8 +21,6 @@ import android.content.Intent import android.content.pm.PackageManager import android.graphics.PorterDuff import android.graphics.drawable.ColorDrawable -import android.graphics.drawable.Drawable -import android.graphics.drawable.RippleDrawable import android.media.RingtoneManager import android.net.Uri import android.os.Build @@ -73,6 +71,7 @@ import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.CapabilitiesUtil import com.nextcloud.talk.utils.ClosedInterfaceImpl import com.nextcloud.talk.utils.DisplayUtils +import com.nextcloud.talk.utils.DrawableUtils import com.nextcloud.talk.utils.LoggingUtils.sendMailWithAttachment import com.nextcloud.talk.utils.NotificationUtils import com.nextcloud.talk.utils.NotificationUtils.getCallRingtoneUri @@ -91,7 +90,6 @@ import io.reactivex.schedulers.Schedulers import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -306,8 +304,8 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu resources!!.getString(R.string.nc_diagnose_battery_optimization_not_ignored) binding.batteryOptimizationIgnored.setTextColor(resources.getColor(R.color.nc_darkRed, null)) - if (openedByNotificationWarning){ - blinkRipple(binding.settingsBatteryOptimizationWrapper.background) + if (openedByNotificationWarning) { + DrawableUtils.blinkDrawable(binding.settingsBatteryOptimizationWrapper.background) } binding.settingsBatteryOptimizationWrapper.setOnClickListener { @@ -354,7 +352,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu ) if (openedByNotificationWarning){ - blinkRipple(binding.settingsNotificationsPermissionWrapper.background) + DrawableUtils.blinkDrawable(binding.settingsNotificationsPermissionWrapper.background) } binding.settingsCallSound.isEnabled = false @@ -391,7 +389,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu binding.callsRingtone.text = resources!!.getString(R.string.nc_common_disabled) if (openedByNotificationWarning){ - blinkRipple(binding.settingsCallSound.background) + DrawableUtils.blinkDrawable(binding.settingsCallSound.background) } } @@ -406,7 +404,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu binding.messagesRingtone.text = resources!!.getString(R.string.nc_common_disabled) if (openedByNotificationWarning){ - blinkRipple(binding.settingsMessageSound.background) + DrawableUtils.blinkDrawable(binding.settingsMessageSound.background) } } @@ -488,7 +486,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu binding.settingsServerNotificationAppDescription.text = description if (openedByNotificationWarning) { - blinkRipple(binding.settingsServerNotificationAppWrapper.background) + DrawableUtils.blinkDrawable(binding.settingsServerNotificationAppWrapper.background) } } else { binding.settingsServerNotificationAppWrapper.visibility = View.GONE @@ -1419,21 +1417,6 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu } } - @Suppress("MagicNumber") - private fun blinkRipple(rippleView: Drawable) { - (rippleView as RippleDrawable).let { rippleDrawable -> - CoroutineScope(Dispatchers.Main).launch { - delay(1000L) // Wait 2 seconds before starting - repeat(3) { - rippleDrawable.state = intArrayOf(android.R.attr.state_pressed, android.R.attr.state_enabled) - delay(250L) // Ripple active duration - rippleDrawable.state = intArrayOf() // Reset state - delay(250L) // Time between blinks - } - } - } - } - companion object { private val TAG = SettingsActivity::class.java.simpleName private const val DURATION: Long = 2500 diff --git a/app/src/main/java/com/nextcloud/talk/utils/DrawableUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/DrawableUtils.kt index 13303dfda..bd3ec84b3 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/DrawableUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/DrawableUtils.kt @@ -6,14 +6,22 @@ */ package com.nextcloud.talk.utils +import android.graphics.drawable.Drawable +import android.graphics.drawable.RippleDrawable +import android.util.Log import com.nextcloud.talk.R import com.nextcloud.talk.utils.Mimetype.AUDIO_PREFIX import com.nextcloud.talk.utils.Mimetype.FOLDER import com.nextcloud.talk.utils.Mimetype.IMAGE_PREFIX import com.nextcloud.talk.utils.Mimetype.TEXT_PREFIX import com.nextcloud.talk.utils.Mimetype.VIDEO_PREFIX +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch object DrawableUtils { + private val TAG = DrawableUtils::class.java.simpleName @Suppress("Detekt.LongMethod") fun getDrawableResourceIdForMimeType(mimetype: String?): Int { @@ -153,4 +161,23 @@ object DrawableUtils { drawableMap["unknown"]!! } } + + @Suppress("MagicNumber") + fun blinkDrawable(rippleView: Drawable) { + try { + (rippleView as RippleDrawable).let { rippleDrawable -> + CoroutineScope(Dispatchers.Main).launch { + delay(1000L) // Wait 2 seconds before starting + repeat(3) { + rippleDrawable.state = intArrayOf(android.R.attr.state_pressed, android.R.attr.state_enabled) + delay(250L) // Ripple active duration + rippleDrawable.state = intArrayOf() // Reset state + delay(250L) // Time between blinks + } + } + } + } catch (e: Exception){ + Log.e(TAG, "Failed to blink Drawable", e) + } + } } diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index beb24732f..5283d60c3 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -185,7 +185,6 @@ android:text="" tools:ignore="SpeakableTextPresentCheck" /> - @@ -246,6 +245,28 @@ android:gravity="center_vertical"/> + + + + + + - - - - - - - - Date: Tue, 26 Nov 2024 13:35:01 +0100 Subject: [PATCH 10/11] reformat code Signed-off-by: Marcel Hibbe --- .../ConversationsListActivity.kt | 19 ++++++++++--------- .../talk/settings/SettingsActivity.kt | 15 ++++++++------- .../com/nextcloud/talk/utils/DrawableUtils.kt | 4 ++-- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index bfc7bce2c..79c2185d0 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -775,9 +775,8 @@ class ConversationsListActivity : ) } - private fun hasActivityActionSendIntent(): Boolean { - return Intent.ACTION_SEND == intent.action || Intent.ACTION_SEND_MULTIPLE == intent.action - } + private fun hasActivityActionSendIntent(): Boolean = + Intent.ACTION_SEND == intent.action || Intent.ACTION_SEND_MULTIPLE == intent.action private fun showSearchView(searchView: SearchView?, searchItem: MenuItem?) { binding.conversationListAppbar.stateListAnimator = AnimatorInflater.loadStateListAnimator( @@ -1286,10 +1285,9 @@ class ConversationsListActivity : !participantPermissions.canIgnoreLobby() } - private fun isReadOnlyConversation(conversation: ConversationModel): Boolean { - return conversation.conversationReadOnlyState === + private fun isReadOnlyConversation(conversation: ConversationModel): Boolean = + conversation.conversationReadOnlyState === ConversationEnums.ConversationReadOnlyState.CONVERSATION_READ_ONLY - } private fun handleSharedData() { collectDataFromIntent() @@ -1514,7 +1512,7 @@ class ConversationsListActivity : } } - private fun shouldShowNotificationWarning() : Boolean { + private fun shouldShowNotificationWarning(): Boolean { val notificationPermissionNotGranted = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && !platformPermissionUtil.isPostNotificationsPermissionGranted() val batteryOptimizationNotIgnored = !PowerManagerUtils().isIgnoringBatteryOptimizations() @@ -1525,8 +1523,11 @@ class ConversationsListActivity : val serverNotificationAppInstalled = userManager.currentUser.blockingGet().capabilities?.notificationsCapability?.features?.isNotEmpty() ?: false - val settingsOfUserAreWrong = notificationPermissionNotGranted || batteryOptimizationNotIgnored || - messagesChannelNotEnabled || callsChannelNotEnabled || !serverNotificationAppInstalled + val settingsOfUserAreWrong = notificationPermissionNotGranted || + batteryOptimizationNotIgnored || + messagesChannelNotEnabled || + callsChannelNotEnabled || + !serverNotificationAppInstalled val userWantsToBeNotifiedAboutWrongSettings = appPreferences.getShowNotificationWarning() diff --git a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt index 5ef8ffe5a..06dd2e80f 100644 --- a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt @@ -103,7 +103,9 @@ import javax.inject.Inject @Suppress("LargeClass", "TooManyFunctions") @AutoInjector(NextcloudTalkApplication::class) -class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNumberDialogClickListener { +class SettingsActivity : + BaseActivity(), + SetPhoneNumberDialogFragment.SetPhoneNumberDialogClickListener { private lateinit var binding: ActivitySettingsBinding @Inject @@ -351,7 +353,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu resources.getColor(R.color.nc_darkRed, null) ) - if (openedByNotificationWarning){ + if (openedByNotificationWarning) { DrawableUtils.blinkDrawable(binding.settingsNotificationsPermissionWrapper.background) } @@ -388,7 +390,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu ) binding.callsRingtone.text = resources!!.getString(R.string.nc_common_disabled) - if (openedByNotificationWarning){ + if (openedByNotificationWarning) { DrawableUtils.blinkDrawable(binding.settingsCallSound.background) } } @@ -403,7 +405,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu ) binding.messagesRingtone.text = resources!!.getString(R.string.nc_common_disabled) - if (openedByNotificationWarning){ + if (openedByNotificationWarning) { DrawableUtils.blinkDrawable(binding.settingsMessageSound.background) } } @@ -713,8 +715,8 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu startActivity(intent) } - private fun getRingtoneName(context: Context, ringtoneUri: Uri?): String { - return if (ringtoneUri == null) { + private fun getRingtoneName(context: Context, ringtoneUri: Uri?): String = + if (ringtoneUri == null) { resources!!.getString(R.string.nc_settings_no_ringtone) } else if ((NotificationUtils.DEFAULT_CALL_RINGTONE_URI == ringtoneUri.toString()) || (NotificationUtils.DEFAULT_MESSAGE_RINGTONE_URI == ringtoneUri.toString()) @@ -724,7 +726,6 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu val r = RingtoneManager.getRingtone(context, ringtoneUri) r.getTitle(context) } - } private fun themeSwitchPreferences() { binding.run { diff --git a/app/src/main/java/com/nextcloud/talk/utils/DrawableUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/DrawableUtils.kt index bd3ec84b3..827cb55b3 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/DrawableUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/DrawableUtils.kt @@ -162,7 +162,7 @@ object DrawableUtils { } } - @Suppress("MagicNumber") + @Suppress("MagicNumber", "TooGenericExceptionCaught") fun blinkDrawable(rippleView: Drawable) { try { (rippleView as RippleDrawable).let { rippleDrawable -> @@ -176,7 +176,7 @@ object DrawableUtils { } } } - } catch (e: Exception){ + } catch (e: Exception) { Log.e(TAG, "Failed to blink Drawable", e) } } From 6dc52fe27dccf144fafbc79287ac7612d00a37fc Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Tue, 26 Nov 2024 15:24:29 +0100 Subject: [PATCH 11/11] change strings in notification settings Signed-off-by: Marcel Hibbe --- app/src/main/res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 20e158544..a4c02a73f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -108,7 +108,7 @@ How to translate with transifex: message_ringtone Librem by feandesign No sound - Server notification app not installed + Server notifications app not installed Please contact the administrator of Appearance @@ -199,7 +199,7 @@ How to translate with transifex: Google Play services are available Google Play services are not available. Notifications are not supported Battery settings - Battery optimization is not ignored. This should be changed! + Battery optimization is enabled which might cause issues. You should disable battery optimization! Battery optimization is ignored, all fine Notification permissions Calls notification channel enabled?