From ed8128ba874ef126ae0b21f1d418c527187a4533 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Thu, 30 Mar 2023 18:27:16 +0200 Subject: [PATCH 01/70] Migrate main app UI to Material Design 3 --- app/build.gradle | 3 +- .../java/io/heckel/ntfy/app/Application.kt | 6 ++++ .../java/io/heckel/ntfy/ui/AddFragment.kt | 3 +- app/src/main/java/io/heckel/ntfy/ui/Colors.kt | 29 +++++++++---------- .../java/io/heckel/ntfy/ui/DetailActivity.kt | 20 +++++-------- .../java/io/heckel/ntfy/ui/MainActivity.kt | 14 ++++----- .../java/io/heckel/ntfy/ui/MainAdapter.kt | 2 +- .../io/heckel/ntfy/ui/NotificationFragment.kt | 3 +- .../io/heckel/ntfy/ui/SettingsActivity.kt | 3 +- .../java/io/heckel/ntfy/ui/UserFragment.kt | 3 +- app/src/main/java/io/heckel/ntfy/util/Util.kt | 2 +- ...ifications_off_time_white_outline_24dp.xml | 1 + ...c_notifications_off_white_outline_24dp.xml | 1 + .../drawable/ic_notifications_white_24dp.xml | 1 + app/src/main/res/layout/activity_share.xml | 2 ++ .../main/res/layout/fragment_add_dialog.xml | 3 ++ .../main/res/layout/fragment_user_dialog.xml | 2 ++ app/src/main/res/values-night/styles.xml | 15 +++------- app/src/main/res/values/styles.xml | 19 ++++-------- 19 files changed, 63 insertions(+), 69 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index a9a28c52..76d078b6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -36,6 +36,7 @@ android { debug { minifyEnabled false debuggable true + applicationIdSuffix '.debug' } } @@ -120,7 +121,7 @@ dependencies { implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' // Material design - implementation "com.google.android.material:material:1.6.1" + implementation "com.google.android.material:material:1.8.0" // LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" diff --git a/app/src/main/java/io/heckel/ntfy/app/Application.kt b/app/src/main/java/io/heckel/ntfy/app/Application.kt index f6cb30ce..d07c7cbe 100644 --- a/app/src/main/java/io/heckel/ntfy/app/Application.kt +++ b/app/src/main/java/io/heckel/ntfy/app/Application.kt @@ -1,6 +1,7 @@ package io.heckel.ntfy.app import android.app.Application +import com.google.android.material.color.DynamicColors import io.heckel.ntfy.db.Repository import io.heckel.ntfy.util.Log @@ -12,4 +13,9 @@ class Application : Application() { } repository } + + override fun onCreate() { + DynamicColors.applyToActivitiesIfAvailable(this) + super.onCreate() + } } diff --git a/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt b/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt index 8e56bab9..256108a1 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt @@ -11,6 +11,7 @@ import android.view.inputmethod.InputMethodManager import android.widget.* import androidx.fragment.app.DialogFragment import androidx.lifecycle.lifecycleScope +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout import io.heckel.ntfy.BuildConfig @@ -144,7 +145,7 @@ class AddFragment : DialogFragment() { loginPasswordText.addTextChangedListener(loginTextWatcher) // Build dialog - val dialog = AlertDialog.Builder(activity) + val dialog = MaterialAlertDialogBuilder(requireContext()) .setView(view) .setPositiveButton(R.string.add_dialog_button_subscribe) { _, _ -> // This will be overridden below to avoid closing the dialog immediately diff --git a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt index ada14cbf..be5b499e 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt @@ -1,48 +1,45 @@ package io.heckel.ntfy.ui import android.content.Context +import android.graphics.Color import androidx.core.content.ContextCompat +import com.google.android.material.color.MaterialColors +import com.google.android.material.elevation.SurfaceColors import io.heckel.ntfy.R import io.heckel.ntfy.util.isDarkThemeOn class Colors { companion object { - const val refreshProgressIndicator = R.color.teal - fun notificationIcon(context: Context): Int { return if (isDarkThemeOn(context)) R.color.teal_light else R.color.teal } fun itemSelectedBackground(context: Context): Int { - return if (isDarkThemeOn(context)) R.color.black_800b else R.color.gray_400 - } - - fun cardBackground(context: Context): Int { - return if (isDarkThemeOn(context)) R.color.black_800b else R.color.white - } - - fun cardSelectedBackground(context: Context): Int { - return if (isDarkThemeOn(context)) R.color.black_700b else R.color.gray_500 + return SurfaceColors.getColorForElevation(context, 10f) } fun cardBackgroundColor(context: Context): Int { - return ContextCompat.getColor(context, cardBackground(context)) + return SurfaceColors.getColorForElevation(context, 5f) } fun cardSelectedBackgroundColor(context: Context): Int { - return ContextCompat.getColor(context, cardSelectedBackground(context)) + return SurfaceColors.getColorForElevation(context, 20f) } fun statusBarNormal(context: Context): Int { - return if (isDarkThemeOn(context)) R.color.black_900 else R.color.teal + return MaterialColors.getColor(context, R.attr.backgroundColor, Color.BLACK) } fun statusBarActionMode(context: Context): Int { - return if (isDarkThemeOn(context)) R.color.black_900 else R.color.teal_dark + return MaterialColors.getColor(context, R.attr.backgroundColor, Color.BLACK) } fun dangerText(context: Context): Int { - return if (isDarkThemeOn(context)) R.color.red_light else R.color.red_dark + return MaterialColors.getColor(context, R.attr.colorError, Color.RED) + } + + fun swipeToRefreshColor(context: Context): Int { + return MaterialColors.getColor(context, R.attr.colorPrimary, Color.GREEN) } } } diff --git a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt index 851f43ac..afda3e92 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt @@ -23,6 +23,7 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import io.heckel.ntfy.BuildConfig import io.heckel.ntfy.R @@ -190,7 +191,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra // Swipe to refresh mainListContainer = findViewById(R.id.detail_notification_list_container) mainListContainer.setOnRefreshListener { refresh() } - mainListContainer.setColorSchemeResources(Colors.refreshProgressIndicator) + mainListContainer.setColorSchemeColors(Colors.swipeToRefreshColor(this)) // Update main list based on viewModel (& its datasource/livedata) val noEntriesText: View = findViewById(R.id.detail_no_notifications) @@ -568,8 +569,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra private fun onClearClick() { Log.d(TAG, "Clearing all notifications for ${topicShortUrl(subscriptionBaseUrl, subscriptionTopic)}") - val builder = AlertDialog.Builder(this) - val dialog = builder + val dialog = MaterialAlertDialogBuilder(this) .setMessage(R.string.detail_clear_dialog_message) .setPositiveButton(R.string.detail_clear_dialog_permanently_delete) { _, _ -> lifecycleScope.launch(Dispatchers.IO) { @@ -600,8 +600,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra private fun onDeleteClick() { Log.d(TAG, "Deleting subscription ${topicShortUrl(subscriptionBaseUrl, subscriptionTopic)}") - val builder = AlertDialog.Builder(this) - val dialog = builder + val dialog = MaterialAlertDialogBuilder(this) .setMessage(R.string.detail_delete_dialog_message) .setPositiveButton(R.string.detail_delete_dialog_permanently_delete) { _, _ -> Log.d(TAG, "Deleting subscription with subscription ID $subscriptionId (topic: $subscriptionTopic)") @@ -716,8 +715,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra private fun onMultiDeleteClick() { Log.d(TAG, "Showing multi-delete dialog for selected items") - val builder = AlertDialog.Builder(this) - val dialog = builder + val dialog = MaterialAlertDialogBuilder(this) .setMessage(R.string.detail_action_mode_delete_dialog_message) .setPositiveButton(R.string.detail_action_mode_delete_dialog_permanently_delete) { _, _ -> adapter.selected.map { notificationId -> viewModel.markAsDeleted(notificationId) } @@ -744,9 +742,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra adapter.toggleSelection(notification.id) // Fade status bar color - val fromColor = ContextCompat.getColor(this, Colors.statusBarNormal(this)) - val toColor = ContextCompat.getColor(this, Colors.statusBarActionMode(this)) - fadeStatusBarColor(window, fromColor, toColor) + fadeStatusBarColor(window, Colors.statusBarNormal(this), Colors.statusBarActionMode(this)) } private fun finishActionMode() { @@ -760,9 +756,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra adapter.notifyItemRangeChanged(0, adapter.currentList.size) // Fade status bar color - val fromColor = ContextCompat.getColor(this, Colors.statusBarActionMode(this)) - val toColor = ContextCompat.getColor(this, Colors.statusBarNormal(this)) - fadeStatusBarColor(window, fromColor, toColor) + fadeStatusBarColor(window, Colors.statusBarActionMode(this), Colors.statusBarNormal(this)) } companion object { diff --git a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt index e131f32c..4daec6b7 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt @@ -28,6 +28,7 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.work.* +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.floatingactionbutton.FloatingActionButton import io.heckel.ntfy.BuildConfig import io.heckel.ntfy.R @@ -96,7 +97,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc // Swipe to refresh mainListContainer = findViewById(R.id.main_subscriptions_list_container) mainListContainer.setOnRefreshListener { refreshAllSubscriptions() } - mainListContainer.setColorSchemeResources(Colors.refreshProgressIndicator) + mainListContainer.setColorSchemeColors(Colors.swipeToRefreshColor(this)) // Update main list based on viewModel (& its datasource/livedata) val noEntries: View = findViewById(R.id.main_no_subscriptions) @@ -608,8 +609,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc private fun onMultiDeleteClick() { Log.d(DetailActivity.TAG, "Showing multi-delete dialog for selected items") - val builder = AlertDialog.Builder(this) - val dialog = builder + val dialog = MaterialAlertDialogBuilder(this) .setMessage(R.string.main_action_mode_delete_dialog_message) .setPositiveButton(R.string.main_action_mode_delete_dialog_permanently_delete) { _, _ -> adapter.selected.map { subscriptionId -> viewModel.remove(this, subscriptionId) } @@ -648,9 +648,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc }) // Fade status bar color - val fromColor = ContextCompat.getColor(this, Colors.statusBarNormal(this)) - val toColor = ContextCompat.getColor(this, Colors.statusBarActionMode(this)) - fadeStatusBarColor(window, fromColor, toColor) + fadeStatusBarColor(window, Colors.statusBarNormal(this), Colors.statusBarActionMode(this)) } private fun finishActionMode() { @@ -677,9 +675,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc }) // Fade status bar color - val fromColor = ContextCompat.getColor(this, Colors.statusBarActionMode(this)) - val toColor = ContextCompat.getColor(this, Colors.statusBarNormal(this)) - fadeStatusBarColor(window, fromColor, toColor) + fadeStatusBarColor(window, Colors.statusBarActionMode(this), Colors.statusBarNormal(this)) } private fun redrawList() { diff --git a/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt b/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt index ed0d2bd0..4aa7e5b6 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt @@ -115,7 +115,7 @@ class MainAdapter(private val repository: Repository, private val onClick: (Subs itemView.setOnClickListener { onClick(subscription) } itemView.setOnLongClickListener { onLongClick(subscription); true } if (selected.contains(subscription.id)) { - itemView.setBackgroundResource(Colors.itemSelectedBackground(context)) + itemView.setBackgroundColor(Colors.itemSelectedBackground(context)) } else { itemView.setBackgroundColor(Color.TRANSPARENT) } diff --git a/app/src/main/java/io/heckel/ntfy/ui/NotificationFragment.kt b/app/src/main/java/io/heckel/ntfy/ui/NotificationFragment.kt index 2d84879c..920d1bd4 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/NotificationFragment.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/NotificationFragment.kt @@ -7,6 +7,7 @@ import android.os.Bundle import android.widget.RadioButton import androidx.fragment.app.DialogFragment import androidx.lifecycle.lifecycleScope +import com.google.android.material.dialog.MaterialAlertDialogBuilder import io.heckel.ntfy.R import io.heckel.ntfy.db.Repository import kotlinx.coroutines.Dispatchers @@ -74,7 +75,7 @@ class NotificationFragment : DialogFragment() { muteForeverButton = view.findViewById(R.id.notification_dialog_forever) muteForeverButton.setOnClickListener{ onClick(Repository.MUTED_UNTIL_FOREVER) } - return AlertDialog.Builder(activity) + return MaterialAlertDialogBuilder(requireContext()) .setView(view) .create() } diff --git a/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt index f4ef5d86..1ce185e9 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt @@ -23,6 +23,7 @@ import androidx.fragment.app.DialogFragment import androidx.lifecycle.lifecycleScope import androidx.preference.* import androidx.preference.Preference.OnPreferenceClickListener +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.gson.Gson import io.heckel.ntfy.BuildConfig import io.heckel.ntfy.R @@ -658,7 +659,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere } else { getString(R.string.settings_advanced_export_logs_scrub_dialog_empty) } - val dialog = AlertDialog.Builder(activity) + val dialog = MaterialAlertDialogBuilder(requireContext()) .setTitle(title) .setMessage(scrubbedText) .setPositiveButton(R.string.settings_advanced_export_logs_scrub_dialog_button_ok) { _, _ -> /* Nothing */ } diff --git a/app/src/main/java/io/heckel/ntfy/ui/UserFragment.kt b/app/src/main/java/io/heckel/ntfy/ui/UserFragment.kt index 6da8304a..a6c50202 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/UserFragment.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/UserFragment.kt @@ -9,6 +9,7 @@ import android.view.WindowManager import android.widget.Button import android.widget.TextView import androidx.fragment.app.DialogFragment +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.textfield.TextInputEditText import io.heckel.ntfy.R import io.heckel.ntfy.db.User @@ -75,7 +76,7 @@ class UserFragment : DialogFragment() { } // Build dialog - val builder = AlertDialog.Builder(activity) + val builder = MaterialAlertDialogBuilder(requireContext()) .setView(view) .setPositiveButton(positiveButtonTextResId) { _, _ -> saveClicked() diff --git a/app/src/main/java/io/heckel/ntfy/util/Util.kt b/app/src/main/java/io/heckel/ntfy/util/Util.kt index 2ffbb766..d177e0b7 100644 --- a/app/src/main/java/io/heckel/ntfy/util/Util.kt +++ b/app/src/main/java/io/heckel/ntfy/util/Util.kt @@ -501,7 +501,7 @@ fun Button.dangerButton(context: Context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { setTextAppearance(R.style.DangerText) } else { - setTextColor(ContextCompat.getColor(context, Colors.dangerText(context))) + setTextColor(Colors.dangerText(context)) } } diff --git a/app/src/main/res/drawable/ic_notifications_off_time_white_outline_24dp.xml b/app/src/main/res/drawable/ic_notifications_off_time_white_outline_24dp.xml index f3c0ad0b..09425d1c 100644 --- a/app/src/main/res/drawable/ic_notifications_off_time_white_outline_24dp.xml +++ b/app/src/main/res/drawable/ic_notifications_off_time_white_outline_24dp.xml @@ -1,6 +1,7 @@ diff --git a/app/src/main/res/layout/fragment_add_dialog.xml b/app/src/main/res/layout/fragment_add_dialog.xml index ad0c7d49..77b603b9 100644 --- a/app/src/main/res/layout/fragment_add_dialog.xml +++ b/app/src/main/res/layout/fragment_add_dialog.xml @@ -47,6 +47,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/add_dialog_topic_name_hint" android:importantForAutofill="no" + android:backgroundTint="?attr/colorPrimary" android:maxLines="1" android:inputType="text" android:maxLength="64" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/add_dialog_subscribe_description"/> @@ -187,6 +188,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/add_dialog_login_username_hint" android:importantForAutofill="no" + android:backgroundTint="?attr/colorPrimary" android:maxLines="1" android:inputType="text" android:maxLength="64" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_marginTop="10dp" app:layout_constraintTop_toBottomOf="@+id/add_dialog_login_description"/> @@ -195,6 +197,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/add_dialog_login_password_hint" android:importantForAutofill="no" + android:backgroundTint="?attr/colorPrimary" android:maxLines="1" android:inputType="textPassword" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/add_dialog_login_username"/> diff --git a/app/src/main/res/layout/fragment_user_dialog.xml b/app/src/main/res/layout/fragment_user_dialog.xml index f6ed2715..b28ae577 100644 --- a/app/src/main/res/layout/fragment_user_dialog.xml +++ b/app/src/main/res/layout/fragment_user_dialog.xml @@ -32,6 +32,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/user_dialog_base_url_hint" android:importantForAutofill="no" + android:backgroundTint="?attr/colorPrimary" android:maxLines="1" android:inputType="text" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_marginTop="6dp" app:layout_constraintTop_toBottomOf="@id/user_dialog_description"/> @@ -40,6 +41,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/user_dialog_username_hint" android:importantForAutofill="no" + android:backgroundTint="?attr/colorPrimary" android:maxLines="1" android:inputType="text" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_marginTop="6dp" app:layout_constraintTop_toBottomOf="@id/user_dialog_base_url"/> diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml index a71491b4..bb89181d 100644 --- a/app/src/main/res/values-night/styles.xml +++ b/app/src/main/res/values-night/styles.xml @@ -10,7 +10,7 @@ - https://developer.android.com/guide/topics/ui/look-and-feel/themes --> - - + + + - + + + + + + diff --git a/app/src/main/res/xml/detail_preferences.xml b/app/src/main/res/xml/detail_preferences.xml index 38cd18b7..4cb105b1 100644 --- a/app/src/main/res/xml/detail_preferences.xml +++ b/app/src/main/res/xml/detail_preferences.xml @@ -3,7 +3,7 @@ - @@ -35,7 +35,7 @@ app:entryValues="@array/detail_settings_notifications_insistent_max_priority_values" app:defaultValue="-1" app:isPreferenceVisible="false"/> - diff --git a/app/src/main/res/xml/main_preferences.xml b/app/src/main/res/xml/main_preferences.xml index 0be2442a..589ae829 100644 --- a/app/src/main/res/xml/main_preferences.xml +++ b/app/src/main/res/xml/main_preferences.xml @@ -25,7 +25,7 @@ app:entries="@array/settings_notifications_auto_delete_entries" app:entryValues="@array/settings_notifications_auto_delete_values" app:defaultValue="2592000"/> - @@ -72,15 +72,15 @@ app:entries="@array/settings_advanced_connection_protocol_entries" app:entryValues="@array/settings_advanced_connection_protocol_values" app:defaultValue="jsonhttp"/> - - - From 339e8d281488b2bac6fb32bfd724036e06d8c354 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Sat, 20 May 2023 15:50:44 +0200 Subject: [PATCH 03/70] Fix status and top bar color issues --- .../drawable/ic_bolt_outline_white_24dp.xml | 1 + .../main/res/drawable/ic_bolt_white_24dp.xml | 1 + app/src/main/res/values-night/styles.xml | 18 ++++-------------- app/src/main/res/values/styles.xml | 8 +++++--- 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/app/src/main/res/drawable/ic_bolt_outline_white_24dp.xml b/app/src/main/res/drawable/ic_bolt_outline_white_24dp.xml index 9ecde1ff..1a91ebc8 100644 --- a/app/src/main/res/drawable/ic_bolt_outline_white_24dp.xml +++ b/app/src/main/res/drawable/ic_bolt_outline_white_24dp.xml @@ -1,6 +1,7 @@ @color/teal_light @color/teal_light - @color/black_900 - @color/black_900 - @color/black_900 - @color/black_800b @color/white + ?backgroundColor + @android:color/transparent + ?backgroundColor + @style/MaterialSwitch - - - - From 256a0a3bdb236ddd9fce6ea9625add22c4c8b586 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Sat, 20 May 2023 16:04:07 +0200 Subject: [PATCH 04/70] Use default app theme generated by Material 3 Theme Builder --- app/src/main/java/io/heckel/ntfy/ui/Colors.kt | 2 +- app/src/main/res/values-night/colors.xml | 33 ++++++++++++++ app/src/main/res/values-night/styles.xml | 16 ++----- app/src/main/res/values/colors.xml | 43 +++++++++++++------ app/src/main/res/values/styles.xml | 40 ++++++++++++++--- 5 files changed, 100 insertions(+), 34 deletions(-) create mode 100644 app/src/main/res/values-night/colors.xml diff --git a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt index be5b499e..50492922 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt @@ -11,7 +11,7 @@ import io.heckel.ntfy.util.isDarkThemeOn class Colors { companion object { fun notificationIcon(context: Context): Int { - return if (isDarkThemeOn(context)) R.color.teal_light else R.color.teal + return MaterialColors.getColor(context, R.attr.colorPrimary, Color.GREEN) } fun itemSelectedBackground(context: Context): Int { diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml new file mode 100644 index 00000000..6ad2866e --- /dev/null +++ b/app/src/main/res/values-night/colors.xml @@ -0,0 +1,33 @@ + + + #5ADBC0 + #00382E + #005144 + #79F8DC + #B1CCC4 + #1D352F + #334B45 + #CDE8DF + #AACBE4 + #113447 + #2A4A5F + #C8E6FF + #FFB4AB + #93000A + #690005 + #FFDAD6 + #191C1B + #E0E3E1 + #191C1B + #E0E3E1 + #3F4946 + #BFC9C4 + #89938F + #191C1B + #E0E3E1 + #006B5B + #000000 + #5ADBC0 + #3F4946 + #000000 + \ No newline at end of file diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml index fdf5cf9e..397d1cb5 100644 --- a/app/src/main/res/values-night/styles.xml +++ b/app/src/main/res/values-night/styles.xml @@ -1,4 +1,4 @@ - + - diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 00ae9757..684cfbff 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,17 +1,34 @@ - #ff000000 - #121212 - #1b2023 - #282F33 - #dddddd - #eeeeee - #ffffffff - - #338574 - #65b5a3 - #2a6e60 - #fe4d2e - #c30000 + #006B5B + #FFFFFF + #79F8DC + #00201A + #4B635C + #FFFFFF + #CDE8DF + #06201A + #436278 + #FFFFFF + #C8E6FF + #001E2E + #BA1A1A + #FFDAD6 + #FFFFFF + #410002 + #FAFDFA + #191C1B + #FAFDFA + #191C1B + #DBE5E0 + #3F4946 + #6F7976 + #EFF1EF + #2E3130 + #5ADBC0 + #000000 + #006B5B + #BFC9C4 + #000000 diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index c5939b81..fb7407d2 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,14 +1,40 @@ - + + + + + From 9d1ba8fd9c7b93cac74a3542cd9339ade2893583 Mon Sep 17 00:00:00 2001 From: Niko Diamadis Date: Thu, 18 Sep 2025 20:06:08 +0200 Subject: [PATCH 06/70] Migrate to M3 toolbar design --- app/build.gradle | 2 +- .../java/io/heckel/ntfy/ui/DetailActivity.kt | 1 + .../heckel/ntfy/ui/DetailSettingsActivity.kt | 2 + .../java/io/heckel/ntfy/ui/MainActivity.kt | 1 + .../io/heckel/ntfy/ui/SettingsActivity.kt | 4 +- .../java/io/heckel/ntfy/ui/ShareActivity.kt | 1 + app/src/main/res/layout/activity_detail.xml | 19 +- app/src/main/res/layout/activity_main.xml | 487 +++++++++--------- app/src/main/res/layout/activity_settings.xml | 30 +- app/src/main/res/layout/activity_share.xml | 25 +- app/src/main/res/layout/app_bar_drawer.xml | 13 + app/src/main/res/values/colors.xml | 1 - app/src/main/res/values/styles.xml | 2 +- 13 files changed, 337 insertions(+), 251 deletions(-) create mode 100644 app/src/main/res/layout/app_bar_drawer.xml diff --git a/app/build.gradle b/app/build.gradle index a3485805..0ca834cd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -131,7 +131,7 @@ dependencies { implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' // Material design - implementation "com.google.android.material:material:1.9.0" + implementation "com.google.android.material:material:1.13.0" // LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.1" diff --git a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt index afda3e92..498bbc1b 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt @@ -79,6 +79,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra notifier = NotificationService(this) appBaseUrl = getString(R.string.app_base_url) + setSupportActionBar(findViewById(R.id.app_bar_drawer).findViewById(R.id.toolbar)) // Show 'Back' button supportActionBar?.setDisplayHomeAsUpEnabled(true) diff --git a/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt index d2e76a84..946b3fd7 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt @@ -9,6 +9,7 @@ import android.net.Uri import android.os.Bundle import android.provider.Settings import android.text.TextUtils +import android.view.View import android.widget.Toast import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts @@ -65,6 +66,7 @@ class DetailSettingsActivity : AppCompatActivity() { // Title val displayName = intent.getStringExtra(DetailActivity.EXTRA_SUBSCRIPTION_DISPLAY_NAME) ?: return + setSupportActionBar(findViewById(R.id.app_bar_drawer).findViewById(R.id.toolbar)) title = displayName // Show 'Back' button diff --git a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt index 7271233f..883c5400 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt @@ -88,6 +88,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc appBaseUrl = getString(R.string.app_base_url) // Action bar + setSupportActionBar(findViewById(R.id.app_bar_drawer).findViewById(R.id.toolbar)) title = getString(R.string.main_action_bar_title) // Floating action button ("+") diff --git a/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt index f513e424..a790e69d 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt @@ -2,7 +2,6 @@ package io.heckel.ntfy.ui import android.Manifest import android.app.AlarmManager -import android.app.AlertDialog import android.content.ClipData import android.content.ClipboardManager import android.content.Context @@ -13,6 +12,7 @@ import android.os.Bundle import android.provider.Settings import android.provider.Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM import android.text.TextUtils +import android.view.View import android.widget.Button import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts @@ -66,6 +66,8 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere repository = Repository.getInstance(this) serviceManager = SubscriberServiceManager(this) + setSupportActionBar(findViewById(R.id.app_bar_drawer).findViewById(R.id.toolbar)) + if (savedInstanceState == null) { settingsFragment = SettingsFragment() // Empty constructor! supportFragmentManager diff --git a/app/src/main/java/io/heckel/ntfy/ui/ShareActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/ShareActivity.kt index 984f6afe..7f65ad37 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/ShareActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/ShareActivity.kt @@ -55,6 +55,7 @@ class ShareActivity : AppCompatActivity() { Log.d(TAG, "Create $this with intent $intent") // Action bar + setSupportActionBar(findViewById(R.id.app_bar_drawer).findViewById(R.id.toolbar)) title = getString(R.string.share_title) // Show 'Back' button diff --git a/app/src/main/res/layout/activity_detail.xml b/app/src/main/res/layout/activity_detail.xml index 67a2df3a..b4dbd523 100644 --- a/app/src/main/res/layout/activity_detail.xml +++ b/app/src/main/res/layout/activity_detail.xml @@ -1,12 +1,25 @@ - + + + + - + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index d532db64..a391d370 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,290 +1,307 @@ - + - - + + + + - - - + + android:id="@+id/main_banner_battery_constraint" android:elevation="5dp"> - + + - + - - - - + - + + + + + + + + + + + + + + + + + + + + + + + app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/main_banner_websocket" + android:id="@+id/main_banner_websocket_reconnect" android:visibility="visible"> - + android:id="@+id/main_banner_websocket_reconnect_constraint" android:elevation="5dp"> - - + /> - - - - - - + + - - - + + + + + android:layout_width="match_parent" + android:layout_height="wrap_content" app:srcCompat="@drawable/ic_sms_gray_48dp" + android:id="@+id/main_no_subscriptions_image"/> + + + + + + style="@style/FloatingActionButton" + /> - + - - - - - - - - - - - - - - - - - - - - - - + diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index f02c645d..087faaa2 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -1,9 +1,27 @@ - + + - + + + + - + android:layout_height="match_parent" /> + + + + diff --git a/app/src/main/res/layout/activity_share.xml b/app/src/main/res/layout/activity_share.xml index 4fed4f86..fd5ea44c 100644 --- a/app/src/main/res/layout/activity_share.xml +++ b/app/src/main/res/layout/activity_share.xml @@ -1,9 +1,23 @@ - + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fitsSystemWindows="true"> + + + + + - + + + + diff --git a/app/src/main/res/layout/app_bar_drawer.xml b/app/src/main/res/layout/app_bar_drawer.xml new file mode 100644 index 00000000..a01b3bd6 --- /dev/null +++ b/app/src/main/res/layout/app_bar_drawer.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 684cfbff..14167ee1 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -31,4 +31,3 @@ #BFC9C4 #000000 - diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index e0f2fa91..2130545a 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,6 +1,6 @@ - - - - From 80eb4900c3221115c9bad4ebb54c40ce0cc192a7 Mon Sep 17 00:00:00 2001 From: Niko Diamadis Date: Mon, 22 Sep 2025 18:44:04 +0200 Subject: [PATCH 11/70] Use primary color for action bar --- app/src/main/res/layout/app_bar_drawer.xml | 8 +++- .../main/res/menu/menu_main_action_bar.xml | 48 ++++++++++++++----- app/src/main/res/values-night/colors.xml | 2 +- app/src/main/res/values-night/styles.xml | 16 ------- app/src/main/res/values/colors.xml | 2 + app/src/main/res/values/styles.xml | 8 ++-- 6 files changed, 50 insertions(+), 34 deletions(-) delete mode 100644 app/src/main/res/values-night/styles.xml diff --git a/app/src/main/res/layout/app_bar_drawer.xml b/app/src/main/res/layout/app_bar_drawer.xml index ea082220..b6de6971 100644 --- a/app/src/main/res/layout/app_bar_drawer.xml +++ b/app/src/main/res/layout/app_bar_drawer.xml @@ -1,14 +1,18 @@ + android:fitsSystemWindows="true" + android:background="@color/action_bar"> + android:layout_height="?attr/actionBarSize" + app:navigationIconTint="@android:color/white" + app:titleTextColor="@android:color/white" /> diff --git a/app/src/main/res/menu/menu_main_action_bar.xml b/app/src/main/res/menu/menu_main_action_bar.xml index 75068746..4804a940 100644 --- a/app/src/main/res/menu/menu_main_action_bar.xml +++ b/app/src/main/res/menu/menu_main_action_bar.xml @@ -1,13 +1,37 @@ - - - - - - - - - + + + + + + + + + diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 6ad2866e..8e90d52e 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -30,4 +30,4 @@ #5ADBC0 #3F4946 #000000 - \ No newline at end of file + diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml deleted file mode 100644 index 397d1cb5..00000000 --- a/app/src/main/res/values-night/styles.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index e2065224..bc7685d5 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -31,6 +31,8 @@ #BFC9C4 #000000 + #006B5B + @android:color/transparent @android:color/transparent diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 22319c72..0f27480f 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,6 +1,6 @@ - - + + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/themes.xml similarity index 67% rename from app/src/main/res/values/styles.xml rename to app/src/main/res/values/themes.xml index 0f27480f..6182e5ee 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/themes.xml @@ -1,5 +1,4 @@ - + + + + + From 83ee39fd2b3ea5343e642f1ec36ef70827887f72 Mon Sep 17 00:00:00 2001 From: Gringo Date: Mon, 29 Sep 2025 21:48:27 +0200 Subject: [PATCH 26/70] Translated using Weblate (Italian) Currently translated at 100.0% (340 of 340 strings) Translation: ntfy/Android app Translate-URL: https://hosted.weblate.org/projects/ntfy/android/it/ --- app/src/main/res/values-it/strings.xml | 62 +++++++++++++------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 7601ae90..e92ac133 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -31,7 +31,7 @@ riconnessione… ieri %1$s (UnifiedPush) - Istruzioni dettagliate disponibili su ntfy.sh, e nella documentazione. + Istruzioni dettagliate disponibili su ntfy.sh e nella documentazione. Questa iscrizione è gestita da %1$s via UnifiedPush Chiedi in seguito Abbandona @@ -43,53 +43,53 @@ Usa un altro server Inserisci gli URL dei servizi qui sotto per iscriversi agli argomenti di altri server. Consegna istantanea in modalità doze - La consegna istantanea è sempre attiva per gli host diversi da %1$s. - Cancella - Log in + La consegna istantanea è sempre attiva per i sistemi diversi da %1$s. + Annulla + Accesso Connessione fallita: %1$s - Login richiesto - Username + Accesso richiesto + Nome utente Password - Login fallito. Utente %1$s non autorizzato. + Accesso fallito. Utente %1$s non autorizzato. Nuovo utente Per inviare notifiche a questo argomento, usa PUT o POST all\'URL dell\'argomento. - Istruzioni dettagliate disponibili su ntfy.sh, e nella documentazione. + Istruzioni dettagliate disponibili su ntfy.sh e nella documentazione. Eliminare tutte le notifiche in questo argomento? Elimina definitivamente - Cancella + Annulla Disiscriversi da questo argomento ed eliminare tutte le notifiche ricevute? Elimina definitivamente - Cancella + Annulla Test: Puoi impostare un titolo, se vuoi. Impossibile inviare il messaggio: Pubblicazione anonima non permessa. Impossibile inviare il messaggio: L\'utente \"%1$s\" non è autorizzato. Copiato negli appunti Consegna istantanea ATTIVATA - Tags: %1$s + Etichette: %1$s Impossibile inviare il messaggio: L\'allegato è troppo grande. Notifica eliminata Annulla Notifica copiata negli appunti - Impossibile aprire o scaricare l\'allegato. Il link è scaduto e nessun file locale è stato trovato. + Impossibile aprire o scaricare l\'allegato. Il collegamento è scaduto e nessun file locale è stato trovato. Impossibile aprire l\'allegato: %1$s Impossibile aprire URL: %1$s Impossibile eliminare l\'allegato: %1$s Impossibile scaricare l\'allegato: %1$s non scaricato - non scaricato, link scaduto + non scaricato, collegamento scaduto non scaricato, scadenza %1$s %1$d%% scaricato eliminato - eliminato, link scaduto - eliminato, scadenza link %1$s + eliminato, collegamento scaduto + eliminato, scadenza collegamento %1$s download fallito - download fallito, link scaduto + download fallito, collegamento scaduto Notifiche disattivate Notifiche disattivate fino a %1$s Abilita consegna istantanea Disabilita consegna istantanea Invia notifica di test - download fallito, scadenza link %1$s + download fallito, scadenza collegamento %1$s Cancella tutte le notifiche Elimina Eliminare definitivamente le notifiche selezionate\? @@ -103,7 +103,7 @@ Impossibile leggere l\'immagine: %1$s Condividi con Messaggio pubblicato - Cancella + Annulla Mostra tutte le notifiche 1 ora Fino a domani @@ -161,17 +161,17 @@ Nessun argomento/nome di sistema è stato redatto. Forse non hai iscrizioni? Questi argomenti/nomi di sistema sono stati sostituiti con nomi di frutta, così puoi condividere i log senza preoccupazioni: \n \n%1$s \n \nLe password sono state ripulite, ma non sono elencate qui. Ok - Cancella i log + Cancella i registri Usa stream JSON over HTTP per collegarti al server. Questo metodo è collaudato, ma può consumare più batteria. Stream JSON over HTTP Puoi aggiungere un utente qui. Tutti gli argomenti per il server specificato utilizzeranno questo utente. - Puoi modificare username/password per l\'utente selezionato, oppure eliminarlo. + Puoi modificare nome utente/password per l\'utente selezionato, oppure eliminarlo. URL del servizio - Username + Nome utente Password Password (non modificata se il campo viene lasciato vuoto) Aggiungi utente - Cancella + Annulla Elimina utente Salva Iscritto a %1$d argomenti @@ -184,7 +184,7 @@ Clicca + per creare o iscriversi ad un argomento. In seguito, riceverai notifiche sul tuo dispositivo quando invierai messaggi via PUT o POST. L\'ottimizzazione della batteria deve essere disabilitata per l\'app per evitare problemi di consegna delle notifiche. Aggiungi iscrizione - Cancella + Annulla Sembra che non ci sia nessuna iscrizione al momento. Segnala un problema Valuta l\'app ⭐ @@ -204,7 +204,7 @@ URL copiato negli appunti Notifiche ON Impossibile inviare il messaggio: %1$s - Interrompi il download + Annulla download Copia notifica Salvato con nome \"%1$s\" nella cartella \"Downloads\" Impossibile salvare l\'allegato: %1$s @@ -226,14 +226,14 @@ Scarica allegati Scarica file Scarica - Cancella + Annulla Scarica tutto automaticamente Se sotto 1 MB Se sotto 10 MB Se sotto 50 MB - Impossibile aprire l\'allegato: Il file può essere stato cancellato oppure nessuna app installata è in grado di aprire il file. + Impossibile aprire l\'allegato: Il file può essere stato eliminato oppure nessuna app installata è in grado di aprire il file. Disiscriviti - Cancella + Annulla Notifiche Impossibile leggere le informazioni del file: %1$s Apri @@ -270,15 +270,15 @@ Registrazione (fino a 1.000 voci) sul dispositivo … Ripristino riuscito Le app non possono ricevere le notifiche come broadcast - Carica e copia link + Carica e copia collegamento Attiva la registrazione, così potrai condividere i registri in un secondo momento per diagnosticare i problemi. Copia negli appunti (censurato) Versione ntfy %1$s (%2$s) Copia/upload file di log Copia negli appunti - Carica e copia link (censurato) - Log in upload … + Carica e copia collegamento (censurato) + Caricando registri … Elimina i log precedentemente salvati, e ricomincia Protocollo di connessione Usa WebSockets per collegarti al server. Questo è il metodo consigliato, ma potrebbe richiedere una configurazione aggiuntiva del proxy. @@ -325,7 +325,7 @@ Attiva ora Predefinita Dona 💸 - Le app non possono più essere installate: devono essere scaricate via browser. Vedi l\'issue #531 per dettagli. + Le app non possono più essere installate: devono essere scaricate tramite browser. Vedi la segnalazione #531 per dettagli. Mantieni l\'alert per le notifiche a priorità massima Attiva UnifiedPush Esclusione Non disturbare (DND), suoni, ecc. From c5b5da3a639ebf93ccc7ef5e4343e89e6e66c2bc Mon Sep 17 00:00:00 2001 From: Liviu Roman Date: Mon, 29 Sep 2025 17:11:06 +0200 Subject: [PATCH 27/70] Translated using Weblate (Romanian) Currently translated at 99.1% (337 of 340 strings) Translation: ntfy/Android app Translate-URL: https://hosted.weblate.org/projects/ntfy/android/ro/ --- app/src/main/res/values-ro/strings.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index a20d2f1e..e0820cb8 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -313,7 +313,7 @@ Logare eșuată. Utilizatorul %1$s nu este autorizat. Utilizator nou Nu ai primit încă notificări pentru acest topic. - Exemplu (folosing curl):

$ curl -d \"Salut\" %1$s
+ Exemplu (folosing curl):
$ curl -d \"Salut\" %1$s
Anulează Test: Poți specifica un titlu dacă dorești. Această este o notificare de test de la aplicația ntfy pentru Android. Are nivelul priorității %1$d. Dacă trimiți altă notificare, s-ar putea să arate altfel. @@ -343,4 +343,9 @@ ntfy va avea rol de distribuitor UnifiedPush Activează UnifiedPush ntfy nu va avea rol de distribuitor UnifiedPush + Întreabă mai târziu + Respinge + Alarme exacte + ntfy poate programa alarme exacte. Alarmele exacte sunt necesare pentru a reconecta WebSocket-urile în fundal. Faceți clic pentru a revoca permisiunea. + ntfy nu poate programa alarme exacte. Alarmele exacte sunt necesare pentru a reconecta WebSockets în fundal. Faceți clic pentru a acorda permisiunea. From d1177bc4923e155795d5261694cdff03effa697c Mon Sep 17 00:00:00 2001 From: Enis Polat Date: Mon, 6 Oct 2025 19:38:00 +0200 Subject: [PATCH 28/70] Translated using Weblate (Turkish) Currently translated at 99.7% (339 of 340 strings) Translation: ntfy/Android app Translate-URL: https://hosted.weblate.org/projects/ntfy/android/tr/ --- app/src/main/res/values-tr/strings.xml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index d25807ce..d4abe752 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -19,9 +19,7 @@ Her şey güncel Bildirimler şu zamana kadar sessize alındı: %1$s %1$d konuya abone olundu - %1$d abonelik yenilenemedi -\n -\n%2$s + %1$d abonelik yenilenemedi \n \n%2$s Abonelik yenilenemedi: %1$s Abone olunan konular Bildirimler açık @@ -209,7 +207,7 @@ dün Kapat Şimdi düzelt - Örnek (curl kullanarak):

$ curl -d \"Merhaba\" %1$s
+ $ curl -d "Merhaba" %1$s ]]> Kalıcı olarak sil Mesaj gönderilemiyor: \"%1$s\" kullanıcısı yetkilendirilmedi. Ayrıntılı talimatlar ntfy.sh adrsimde ve belgelerde bulunabilir. @@ -343,4 +341,11 @@ UnifiedPush\'u etkinleştir ntfy bir UnifiedPush dağıtıcısı olarak davranmayacaktır ntfy bir UnifiedPush dağıtıcısı olarak davranacaktır + WebSocket bağlantılarının arka planda yeniden bağlanmasını sağlamak için ntfy uygulamasına Alarm ve Hatırlatıcılar iznini verin + Daha Sonra Hatırlat + Yoksay + Şimdi izin ver + Kesin alarmlar + ntfy, kesin alarmlar planlayabilir. Kesin alarmlar, WebSocket’lerin arka planda yeniden bağlanması için gereklidir. İzni geri almak için tıklayın. + ntfy, kesin alarmlar planlayamaz. Kesin alarmlar, WebSocket’lerin arka planda yeniden bağlanması için gereklidir. İzni vermek için tıklayın. From d382896792c80e31410ae784a8d3e2b556c4d585 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Thu, 9 Oct 2025 09:00:44 -0400 Subject: [PATCH 29/70] Remove donate link from Google Play version --- app/build.gradle | 6 ++++-- app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 10ac3765..4d8d7dab 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,8 +18,8 @@ android { minSdkVersion 21 targetSdkVersion 35 - versionCode 41 - versionName "1.17.8" + versionCode 42 + versionName "1.17.9" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -53,11 +53,13 @@ android { play { buildConfigField 'boolean', 'FIREBASE_AVAILABLE', 'true' buildConfigField 'boolean', 'RATE_APP_AVAILABLE', 'true' + buildConfigField 'boolean', 'DONATE_LINK_AVAILABLE', 'false' buildConfigField 'boolean', 'INSTALL_PACKAGES_AVAILABLE', 'false' } fdroid { buildConfigField 'boolean', 'FIREBASE_AVAILABLE', 'false' buildConfigField 'boolean', 'RATE_APP_AVAILABLE', 'false' + buildConfigField 'boolean', 'DONATE_LINK_AVAILABLE', 'true' buildConfigField 'boolean', 'INSTALL_PACKAGES_AVAILABLE', 'true' } } diff --git a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt index 1c4b0f52..0df27a7a 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt @@ -395,9 +395,11 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc } val mutedUntilSeconds = repository.getGlobalMutedUntil() runOnUiThread { - // Show/hide in-app rate widget + // Show/hide menu items based on build config val rateAppItem = menu.findItem(R.id.main_menu_rate) + val donateItem = menu.findItem(R.id.main_menu_donate) rateAppItem.isVisible = BuildConfig.RATE_APP_AVAILABLE + donateItem.isVisible = BuildConfig.DONATE_LINK_AVAILABLE // Pause notification icons val notificationsEnabledItem = menu.findItem(R.id.main_menu_notifications_enabled) From 5f99bebebae7f18b87d7da9b7ca1004a328fafd8 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Thu, 9 Oct 2025 10:51:55 -0400 Subject: [PATCH 30/70] Bump --- app/build.gradle | 4 ++-- fastlane/metadata/android/en-US/changelog/43.txt | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelog/43.txt diff --git a/app/build.gradle b/app/build.gradle index 4d8d7dab..464a5853 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,8 +18,8 @@ android { minSdkVersion 21 targetSdkVersion 35 - versionCode 42 - versionName "1.17.9" + versionCode 43 + versionName "1.17.10" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/fastlane/metadata/android/en-US/changelog/43.txt b/fastlane/metadata/android/en-US/changelog/43.txt new file mode 100644 index 00000000..2bb757a5 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelog/43.txt @@ -0,0 +1,4 @@ +This is a small release to remove the "Donate" button from menu, +as this violates the Google Play policies. + +No further changes are in this release. From 075a563024f394a31f97df96b2e76ce75aa720a9 Mon Sep 17 00:00:00 2001 From: "Kristijan \\\"Fremen\\\" Velkovski" Date: Fri, 10 Oct 2025 05:07:30 +0200 Subject: [PATCH 31/70] Added translation using Weblate (Macedonian) --- app/src/main/res/values-mk/strings.xml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 app/src/main/res/values-mk/strings.xml diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml new file mode 100644 index 00000000..55344e51 --- /dev/null +++ b/app/src/main/res/values-mk/strings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file From ab7285540310b0f49c0b85d461f21f85c1205ff5 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Fri, 10 Oct 2025 11:49:36 -0400 Subject: [PATCH 32/70] Remove Donate link entirely . . . --- app/build.gradle | 6 ++---- app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt | 6 ------ app/src/main/res/menu/menu_main_action_bar.xml | 1 - app/src/main/res/values-ar/strings.xml | 1 - app/src/main/res/values-bg/strings.xml | 1 - app/src/main/res/values-ca/strings.xml | 1 - app/src/main/res/values-cs/strings.xml | 1 - app/src/main/res/values-de/strings.xml | 1 - app/src/main/res/values-el/strings.xml | 1 - app/src/main/res/values-es/strings.xml | 1 - app/src/main/res/values-et/strings.xml | 1 - app/src/main/res/values-fa/strings.xml | 1 - app/src/main/res/values-fi/strings.xml | 1 - app/src/main/res/values-fr/strings.xml | 1 - app/src/main/res/values-gl/strings.xml | 1 - app/src/main/res/values-hi/strings.xml | 1 - app/src/main/res/values-hr/strings.xml | 1 - app/src/main/res/values-hu/strings.xml | 1 - app/src/main/res/values-in/strings.xml | 1 - app/src/main/res/values-it/strings.xml | 1 - app/src/main/res/values-iw/strings.xml | 1 - app/src/main/res/values-ja/strings.xml | 1 - app/src/main/res/values-ms/strings.xml | 1 - app/src/main/res/values-nb-rNO/strings.xml | 1 - app/src/main/res/values-nl/strings.xml | 1 - app/src/main/res/values-pl/strings.xml | 1 - app/src/main/res/values-pt-rBR/strings.xml | 1 - app/src/main/res/values-pt/strings.xml | 1 - app/src/main/res/values-ro/strings.xml | 1 - app/src/main/res/values-ru/strings.xml | 1 - app/src/main/res/values-sk/strings.xml | 1 - app/src/main/res/values-sv/strings.xml | 1 - app/src/main/res/values-ta/strings.xml | 1 - app/src/main/res/values-th/strings.xml | 1 - app/src/main/res/values-tr/strings.xml | 1 - app/src/main/res/values-uk/strings.xml | 1 - app/src/main/res/values-uz/strings.xml | 1 - app/src/main/res/values-vi/strings.xml | 1 - app/src/main/res/values-zh-rCN/strings.xml | 1 - app/src/main/res/values-zh-rTW/strings.xml | 1 - app/src/main/res/values/strings.xml | 1 - .../metadata/android/en-US/changelog/{43.txt => 44.txt} | 0 42 files changed, 2 insertions(+), 49 deletions(-) rename fastlane/metadata/android/en-US/changelog/{43.txt => 44.txt} (100%) diff --git a/app/build.gradle b/app/build.gradle index 464a5853..dafaeb80 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,8 +18,8 @@ android { minSdkVersion 21 targetSdkVersion 35 - versionCode 43 - versionName "1.17.10" + versionCode 44 + versionName "1.17.11" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -53,13 +53,11 @@ android { play { buildConfigField 'boolean', 'FIREBASE_AVAILABLE', 'true' buildConfigField 'boolean', 'RATE_APP_AVAILABLE', 'true' - buildConfigField 'boolean', 'DONATE_LINK_AVAILABLE', 'false' buildConfigField 'boolean', 'INSTALL_PACKAGES_AVAILABLE', 'false' } fdroid { buildConfigField 'boolean', 'FIREBASE_AVAILABLE', 'false' buildConfigField 'boolean', 'RATE_APP_AVAILABLE', 'false' - buildConfigField 'boolean', 'DONATE_LINK_AVAILABLE', 'true' buildConfigField 'boolean', 'INSTALL_PACKAGES_AVAILABLE', 'true' } } diff --git a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt index 0df27a7a..5ce60f42 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt @@ -397,9 +397,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc runOnUiThread { // Show/hide menu items based on build config val rateAppItem = menu.findItem(R.id.main_menu_rate) - val donateItem = menu.findItem(R.id.main_menu_donate) rateAppItem.isVisible = BuildConfig.RATE_APP_AVAILABLE - donateItem.isVisible = BuildConfig.DONATE_LINK_AVAILABLE // Pause notification icons val notificationsEnabledItem = menu.findItem(R.id.main_menu_notifications_enabled) @@ -445,10 +443,6 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc } true } - R.id.main_menu_donate -> { - startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.main_menu_donate_url)))) - true - } R.id.main_menu_docs -> { startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.main_menu_docs_url)))) true diff --git a/app/src/main/res/menu/menu_main_action_bar.xml b/app/src/main/res/menu/menu_main_action_bar.xml index 75068746..4f50c912 100644 --- a/app/src/main/res/menu/menu_main_action_bar.xml +++ b/app/src/main/res/menu/menu_main_action_bar.xml @@ -8,6 +8,5 @@ -
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 2a55c732..9cac9d37 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -66,7 +66,6 @@ كل شئ محدث لاخر تحديث تم الاشتراك في 1 موضوع فوري تم الاشتراك في 4 مواضيع فورية - تبرع 💸 اﻹعدادات تعذر تحديث %1$d اشتراكات \n diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 36423ca6..c0ef6c8a 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -327,7 +327,6 @@ Относно Адрес на темата Копирано в междинната памет - Даряване 💸 Ntfy не може да инсталира получени приложения. Вместо това изтеглете чрез браузъра. За подробности вижте дефект №531. Подразбирани Потребителски настройки за известия diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 9ce0a931..edfd4376 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -6,7 +6,6 @@ Prioritat alta Prioritat màxima Servei Subscripció - Donar 💸 reconnectant… Escoltant notificacions entrants Subscrit per entrega instantània de temes diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 0dc1d044..665dac73 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -327,7 +327,6 @@ Povolit nyní WebSockets jsou doporučenou metodou připojení k vašemu serveru, která může zlepšit zvýšit výdrž baterie, ale může vyžadovat další konfiguraci v proxy serveru. Metodu připojení lze přepnout v Nastavení. Zvolit URL služby - Přispět 💸 Aplikace již nelze nainstalovat. Místo toho stahujte přes prohlížeč. Podrobnosti naleznete v issue #531. Výchozí Upozornění s nejvyšší prioritou pouze jednou diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index aceed750..e0cb2768 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -327,7 +327,6 @@ Themen-URL Über In Zwischenablage kopiert - Spenden 💸 Apps können nicht mehr installiert werden. Bitte stattdessen über einen Browser herunterladen. Details siehe Issue #531. Eigene Einstellungen für dieses Abo verwenden Beanchrichtigungseinstellungen konfigurieren diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 6eb1ce1d..0096d259 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -60,7 +60,6 @@ Όνομα θέματος Χρήση άλλου server/εξυπηρετητή Εγγραφή σε ειδοποίηση - Κάντε δωρεά Η μετάβαση σε WebSockets είναι ο συνιστώμενος τρόπος σύνδεσης με τον διακομιστή σας και μπορεί να βελτιώσει τη διάρκεια ζωής της μπαταρίας, αλλά μπορεί να απαιτεί πρόσθετες ρυθμίσεις στο διακομιστή μεσολάβησης. Αυτό μπορεί να ενεργοποιηθεί στις Ρυθμίσεις. Κωδικός πρόσβασης Η σύνδεση απέτυχε. Ο χρήστης %1$s δεν είναι εξουσιοδοτημένος. diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 9a0c5a31..076fcdad 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -327,7 +327,6 @@ Borrar la URL del servicio Cambiar a WebSockets es la forma recomendada para conectarse a su servidor, y podría mejorar la vida de la batería, pero puede requerir configuración adicional en su proxy. Esto se puede cambiar en la Configuración. Habilitar ahora - Donar 💸 Las aplicaciones ya no se pueden instalar desde ntfy. Descárguelas a través del navegador. Consulte el issue #531 para obtener más información. Predeterminado Mantener alertas para la máxima prioridad diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index d2dcab01..58c42674 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -6,7 +6,6 @@ Teata vigadest Loe dokumentatsiooni Hinda rakendust ⭐ - Toeta arendajat 💸 Kustuta jäädavalt %1$d teavitust %1$s (UnifiedPush) diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index a87c2a9c..5449bf84 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -14,7 +14,6 @@ گزارش یک نقص فنی مطالعه مستندات رتبه دهی به اپ ⭐ - حمایت مالی 💸 %1$d اطلاعیه %1$d اطلاعیه در حال اتصال دوباره … diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index dad7df0a..2900047f 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -329,7 +329,6 @@ Pidä hälytykset korkeimmalla tasolla Vain maksimi ja ylittävät About - Lahjoita 💸 8 tuntia Topikki %1$s tilattu Käyttäjätunnus diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 3b802362..673e78e5 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -329,7 +329,6 @@ URL du sujet Défaut Conserver les notifications - Faire un don 💸 Les applications ne peuvent plus être installées. Veuillez les télécharger via un navigateur. Voir le ticket #531 pour plus de détails. Conserver les notifications avec une priorité maximale Paramètres personnalisés de la notification diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 0b46baac..b35e1473 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -31,7 +31,6 @@ Informar dun fallo Ler documentación Valorar a app ⭐ - Doar 💸 Retirar subscrición Retirar a subscrición ao(s) asunto(s) seleccionado(s) e eliminar definitivamente tódalas notificacións\? Eliminar definitivamente diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index e889a626..2f270648 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -79,7 +79,6 @@ विषय की सदस्यता लें पीछे जाएं एक विषय की सदस्यता - दान करें %1$d सूचना रद्द करें रद्द करें diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index e7536971..b6a77b4a 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -80,7 +80,6 @@ ponovno povezivanje… Uključi sada Prebacivanje na WebSockete je preporučen način povezivanja sa serverom, i moglo bi poboljšati životni vijek baterije, ali može zahtjevati dodatnu konfiguraciju u tvojem proxy-u. Ovo možeš promijeniti u postavkama. - Doniraj 💸 Prijavu grešku Opširnije upute dostupne su na ntfy.sh i u dokumentaciji. Klikni + za kreiranje ili pretplaćivanje na temu. Nakon toga primaš obavijesti na uređaj kad pošalješ poruke preko PUT ili POST. diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 4c8df922..752ce0ef 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -50,7 +50,6 @@ %1$d értesítés Mégse Alapértelmezett - Adomány 💸 Bezár Garantálja az azonnali üzenetküldést, akkor is, ha az eszköz inaktív. Az azonnali üzenetküldés mindig bekapcsolva a %1$s címen kívül. diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 4c0d90da..70fe8746 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -327,7 +327,6 @@ Disalin ke papan klip Tentang URL Topik - Donasi 💸 Aplikasi tidak dapat dipasang lagi. Unduh melalui peramban. Lihat masalah #531 untuk detail lebih lanjut. Notifikasi prioritas maks hanya memperingati sekali Atur pengaturan notifikasi diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 7bc980b4..988a77fc 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -328,7 +328,6 @@ Pulisci il servizio URL Attiva ora Default - Dona 💸 Le app non possono più essere installate: devono essere scaricate via browser. Vedi l\'issue #531 per dettagli. Mantieni l\'alert per le notifiche a priorità massima Attiva UnifiedPush diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 663f2b18..e2320755 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -39,7 +39,6 @@ התחברות מחדש… לחיצה על + תאפשר ליצור או להירשם לנושא. לאחר מכן התראות תגענה למכשיר שלך בעת שליחת הודעות עם PUT או POST. הוראות מפורטות זמינות ב־ntfy.sh, ובתיעוד. - תרומה 💸 מנוי לשני נושאים במסירה מיידית מנוי לשלושה נושאים במסירה מיידית מנוי לנושאים במסירה מיידית diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 605201ab..30543449 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -327,7 +327,6 @@ About トピックのURL クリップボードにコピーしました - 寄付する💸 アプリはインストールできなくなりました。代替手段としてブラウザからダウンロードしてください。詳細は issue #531 をご参照ください。 優先度最高は非表示になるまで通知継続 デフォルト diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml index 7de6eda0..3f71002a 100644 --- a/app/src/main/res/values-ms/strings.xml +++ b/app/src/main/res/values-ms/strings.xml @@ -34,7 +34,6 @@ Notifikasi disenyapkan hingga %1$s Tetapan Aduan Kerosakan - Sumbangan 💸 Padamkan secara kekal Batal %1$d notifikasi diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 628222e9..a51cb51e 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -324,7 +324,6 @@ %1$s (standard) Kopier til utklippstavlen Angi et tilpasset visningsnavn for dette abonnementet. La stå tomt for standard (%1$s). - Doner 💸 Å bytte til WebSockets er den anbefalte måten å koble til serveren på, og kan forbedre batterilevetiden, men kan kreve ytterligere konfigurasjon i proxy-serveren. Dette kan endres i innstillingene. Aktiver nå Abonnerte på emnet %1$s diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 28fc303b..6d3b1248 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -328,7 +328,6 @@ Nu inschakelen WebSockets is de aangeraden manier om te verbinden met uw server en kan batterij verbruik verminderen. Het kan extra configuratie in uw proxy vereisen. Dit kan omgeschakeld worden in de instellingen. Standaard - Doneer 💸 Apps kunnen niet meer worden geïnstalleerd. Download deze via de browser. Raadpleeg issue #531 voor meer details. Behoud meldingen voor hoogste prioriteit Max prioriteit berichten geven continue een melding totdat deze worden gesloten diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index c2b2bfa2..27cd59fd 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -327,7 +327,6 @@ Odrzuć Aktywuj teraz Użyj strumienia JSON przez HTTP, aby połączyć się z serwerem. Ta metoda jest sprawdzona, ale może zużywać więcej baterii. - Wspomóż💸 Aplikacja nie może zostać zainstalowana. Pobierz ją poprzez przeglądarkę. Sprawdź problem #531 po więcej informacji. Nadal wysyłaj powiadomienia dla najwyższych priorytetów Własne ustawienia powiadomień diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 84950653..55385e8b 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -324,7 +324,6 @@ Limpar URL do serviço Habilitar agora Padrão - Doar 💸 As notificações de prioridade máxima alertam apenas uma vez Configurar configurações de notificação Ignorar o Não Perturbe, sons, etc. diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index b87ded12..200eced2 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -258,7 +258,6 @@ Modo claro Modo escuro Usar a predefinição do sistema - Doar 💸 Falha ao restaurar %1$s Avançado Messagens de transmissão diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index a20d2f1e..a6fd2248 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -162,7 +162,6 @@ Raportează o problemă Citește documentația Dezabonează-te de la topicele selectate și șterge notificările permanent\? - Donează 💸 %1$s (UnifiedPush) Adaugă abonament %1$d notificări diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 24d6ae32..777d5c6d 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -313,7 +313,6 @@ Установка приложений через уведомления больше не поддерживается. Скачайте приложение через браузер. Подробности смотрите в отчёте ntfy #531. Иконка подписки Использовать иконку для отображения в уведомлениях - Пожертвовать 💸 Уведомления с наивысшим приоритетом будут давать о себе знать только один раз Уведомления будут доставляться с помощью Firebase. Могут быть задержки с доставкой, но потребляется меньше энергии. Очистить URL-адрес сервера diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index a6746b70..251ce74e 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -282,7 +282,6 @@ Ohodnotiť aplikáciu ⭐ Prečítať dokumentáciu Oznámenia stlmené do %1$s - Prispieť 💸 Odhlásiť odber z vybraných tém a natrvalo vymazať všetky oznámenia\? Vymazať natrvalo Odhlásiť odber diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 9005c50c..a3f2b64f 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -113,7 +113,6 @@ Prenumerationsinställningar Dela Dela - Donera 💸 Ångra Öppna fil Ta bort fil diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index 8bd3a285..7d64b6b6 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -40,7 +40,6 @@ ஒரு பிழையைப் புகாரளிக்கவும் ஆவணத்தைப் படியுங்கள் பயன்பாட்டை மதிப்பிடுங்கள் - நன்கொடை குழுவிலகவும் தேர்ந்தெடுக்கப்பட்ட தலைப்பு (கள்) இலிருந்து குழுவிலகவும், அனைத்து அறிவிப்புகளையும் நிரந்தரமாக நீக்கவா? ரத்துசெய் diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 93daccb4..b65f8038 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -35,7 +35,6 @@ รายงานปัญหา(Bug) อ่านเอกสาร ให้คะแนนแอป ⭐ - บริจาค 💸 ยกเลิกการสมัครรับ ต้องการยกเลิกการสมัครจากหัวข้อที่เลือกและลบการแจ้งเตือนทั้งหมดอย่างถาวรใช่ไหม ลบถาวร diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index d25807ce..6aa1cb22 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -327,7 +327,6 @@ Hakkında Konu URL\'si Panoya kopyalandı - Bağış yap 💸 Uygulamalar artık kurulamıyor. Bunun yerine tarayıcı üzerinden indirin. Ayrıntılar için sorun #531\'e bakın. En yüksek öncelikli bildirimler yalnızca bir kez uyarı verir Bu abonelik için özel ayarları kullan diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 5c1cd674..e78b28b0 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -331,7 +331,6 @@ Використання налаштувань за замовчуванням (звуки, \"Не турбувати\" тощо) Перевизначення режиму \"Не турбувати\" (DND), звуки тощо. Продовжувати сповіщати - Пожертвувати 💸 Безперервне сповіщення для найвищого пріоритету Сповіщення з максимальним пріоритетом безперервно сповіщають, доки не будуть закриті Сповіщення з максимальним пріоритетом сповіщають лише один раз diff --git a/app/src/main/res/values-uz/strings.xml b/app/src/main/res/values-uz/strings.xml index d9b6728f..f27ec919 100644 --- a/app/src/main/res/values-uz/strings.xml +++ b/app/src/main/res/values-uz/strings.xml @@ -248,7 +248,6 @@ Uchta darhol yuborish mavzulariga obuna bo‘ldik Bildirishnomalar %1$s gacha o‘chirilgan Beshta mavzuga obuna bo‘ldik - Xayriya qiling 💸 Bekor qilish Boshqa serverlardan mavzularga obuna bo‘lish uchun quyida URL manzillarini kiriting. Ushbu mavzu tizimga kirishni talab qiladi. Iltimos, foydalanuvchi nomi va parolni kiriting. diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index d8d77671..4b9beb3a 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -25,7 +25,6 @@ Chờ thông báo Đã nhận %1$d thông báo Xóa vĩnh viễn - Quyên góp 💸 Hủy Hủy đăng kí các chủ đề đã chọn và xóa tất cả thông báo? Hỏi sau diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index aeb279ac..cff8a815 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -327,7 +327,6 @@ 关于 主题 URL 已复制到剪贴板 - 捐赠 💸 无法再安装应用。 请通过浏览器下载。 有关详细信息,请参阅问题 #531。 默认 持续以最高优先级通知进行提醒,直至取消 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index f41db28f..46510ecc 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -108,7 +108,6 @@ 即時通知 使用全域設定 新增使用者 - 捐獻 💸 復原 已下載 %1$d%% 啓用即時通知 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 49f9082b..aef70eb3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -42,7 +42,6 @@ Report a bug Read the docs Rate the app ⭐ - Donate 💸 Unsubscribe diff --git a/fastlane/metadata/android/en-US/changelog/43.txt b/fastlane/metadata/android/en-US/changelog/44.txt similarity index 100% rename from fastlane/metadata/android/en-US/changelog/43.txt rename to fastlane/metadata/android/en-US/changelog/44.txt From 936c75962d2c6fc106a53a5919b109480e652fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Fri, 10 Oct 2025 10:02:38 +0200 Subject: [PATCH 33/70] Translated using Weblate (Turkish) Currently translated at 100.0% (340 of 340 strings) Translation: ntfy/Android app Translate-URL: https://hosted.weblate.org/projects/ntfy/android/tr/ --- app/src/main/res/values-tr/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index d4abe752..1eb825b2 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -19,7 +19,7 @@ Her şey güncel Bildirimler şu zamana kadar sessize alındı: %1$s %1$d konuya abone olundu - %1$d abonelik yenilenemedi \n \n%2$s + %1$d abonelik yenilenemedi\n\n%2$s Abonelik yenilenemedi: %1$s Abone olunan konular Bildirimler açık From d1ffccc59e967907f2bd8d31ad4f95144e4f367e Mon Sep 17 00:00:00 2001 From: ezn24 Date: Fri, 10 Oct 2025 07:27:43 +0200 Subject: [PATCH 34/70] Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 100.0% (340 of 340 strings) Translation: ntfy/Android app Translate-URL: https://hosted.weblate.org/projects/ntfy/android/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index f41db28f..8f0c5e08 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -213,7 +213,7 @@ 儲存為 \"Downloads\" 資料中的 \"%1$s\" 不能夠發布信息:用戶 %1$s 不被授權。 PUT 或 POST 主題網址以傳送通訊。 - 例如(使用 curl):

$ curl -d \"Hi\" %1$s
+ $ curl -d "Hi" %1$s]]> 不能夠傳送訊息:%1$s 標籤:%1$s 啟動即時傳送 @@ -343,4 +343,11 @@ 無法保存圖標:%1$s 使用全局設置 您可以編輯該用戶的用戶名和密碼,或刪除該用戶。 + 為確保 WebSocket 能在背景重新連線,請授予 ntfy「鬧鐘與提醒」權限 + 關閉 + 稍後再問 + 立即授權 + 精準提醒 + ntfy 可以排程精準提醒。精準提醒是讓 WebSocket 能在背景重新連線的必要條件。點擊以撤銷此權限。 + ntfy 無法排程精準提醒。精準提醒是讓 WebSocket 能在背景重新連線的必要條件。點擊以授予此權限。 From 31a772950126cff5bdc7a4074f450fb636a61b70 Mon Sep 17 00:00:00 2001 From: "Kristijan \\\"Fremen\\\" Velkovski" Date: Fri, 10 Oct 2025 05:10:41 +0200 Subject: [PATCH 35/70] Translated using Weblate (Macedonian) Currently translated at 1.4% (5 of 340 strings) Translation: ntfy/Android app Translate-URL: https://hosted.weblate.org/projects/ntfy/android/mk/ --- app/src/main/res/values-mk/strings.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml index 55344e51..61f3bd04 100644 --- a/app/src/main/res/values-mk/strings.xml +++ b/app/src/main/res/values-mk/strings.xml @@ -1,3 +1,8 @@ - \ No newline at end of file + Низок приоритет + Мин приоритет + Стандарден приоритет + Висок приоритет + Највисок приоритет + From d3c017ebd5cdb6c3597de4148fe05f40bfe9fb87 Mon Sep 17 00:00:00 2001 From: "Kristijan \\\"Fremen\\\" Velkovski" Date: Fri, 10 Oct 2025 05:19:48 +0200 Subject: [PATCH 36/70] Translated using Weblate (Macedonian) Currently translated at 33.3% (1 of 3 strings) Translation: ntfy/Android app (Fastlane metadata) Translate-URL: https://hosted.weblate.org/projects/ntfy/android-fastlane/mk/ --- fastlane/metadata/android/mk-MK/title.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 fastlane/metadata/android/mk-MK/title.txt diff --git a/fastlane/metadata/android/mk-MK/title.txt b/fastlane/metadata/android/mk-MK/title.txt new file mode 100644 index 00000000..70d5de05 --- /dev/null +++ b/fastlane/metadata/android/mk-MK/title.txt @@ -0,0 +1 @@ +ntfy - PUT/POST на ваш телефон From 211e84046159ef2aacb0b575d6f210c159cdfa78 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 12 Oct 2025 17:57:55 -0400 Subject: [PATCH 37/70] Remove all links to ntfy.sh and GitHub, and even copy URL menu items --- app/build.gradle | 6 ++-- .../io/heckel/ntfy/msg/NotificationService.kt | 5 +-- .../java/io/heckel/ntfy/ui/DetailActivity.kt | 23 ++++++++++++-- .../heckel/ntfy/ui/DetailSettingsActivity.kt | 7 +++-- .../java/io/heckel/ntfy/ui/MainActivity.kt | 31 ++++++++++++++++--- .../java/io/heckel/ntfy/ui/MainAdapter.kt | 3 +- app/src/main/java/io/heckel/ntfy/util/Util.kt | 13 +++++--- .../en-US/changelog/{44.txt => 46.txt} | 0 8 files changed, 71 insertions(+), 17 deletions(-) rename fastlane/metadata/android/en-US/changelog/{44.txt => 46.txt} (100%) diff --git a/app/build.gradle b/app/build.gradle index dafaeb80..e86bb4df 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,8 +18,8 @@ android { minSdkVersion 21 targetSdkVersion 35 - versionCode 44 - versionName "1.17.11" + versionCode 46 + versionName "1.17.13" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -53,11 +53,13 @@ android { play { buildConfigField 'boolean', 'FIREBASE_AVAILABLE', 'true' buildConfigField 'boolean', 'RATE_APP_AVAILABLE', 'true' + buildConfigField 'boolean', 'PAYMENT_LINKS_AVAILABLE', 'false' // Google Play Payments Policy, see #1463 buildConfigField 'boolean', 'INSTALL_PACKAGES_AVAILABLE', 'false' } fdroid { buildConfigField 'boolean', 'FIREBASE_AVAILABLE', 'false' buildConfigField 'boolean', 'RATE_APP_AVAILABLE', 'false' + buildConfigField 'boolean', 'PAYMENT_LINKS_AVAILABLE', 'true' buildConfigField 'boolean', 'INSTALL_PACKAGES_AVAILABLE', 'true' } } diff --git a/app/src/main/java/io/heckel/ntfy/msg/NotificationService.kt b/app/src/main/java/io/heckel/ntfy/msg/NotificationService.kt index 48067073..24fc0032 100644 --- a/app/src/main/java/io/heckel/ntfy/msg/NotificationService.kt +++ b/app/src/main/java/io/heckel/ntfy/msg/NotificationService.kt @@ -29,6 +29,7 @@ class NotificationService(val context: Context) { private val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager private val repository = Repository.getInstance(context) private val markwon = MarkwonFactory.createForNotification(context) + private val appBaseUrl = context.getString(R.string.app_base_url) fun display(subscription: Subscription, notification: Notification) { Log.d(TAG, "Displaying notification $notification") @@ -91,7 +92,7 @@ class NotificationService(val context: Context) { } private fun displayInternal(subscription: Subscription, notification: Notification, update: Boolean = false) { - val title = formatTitle(subscription, notification) + val title = formatTitle(appBaseUrl, subscription, notification) val groupId = if (subscription.dedicatedChannels) subscriptionGroupId(subscription) else DEFAULT_GROUP val channelId = toChannelId(groupId, notification.priority) val insistent = notification.priority == PRIORITY_MAX && @@ -365,7 +366,7 @@ class NotificationService(val context: Context) { putExtra(MainActivity.EXTRA_SUBSCRIPTION_ID, subscription.id) putExtra(MainActivity.EXTRA_SUBSCRIPTION_BASE_URL, subscription.baseUrl) putExtra(MainActivity.EXTRA_SUBSCRIPTION_TOPIC, subscription.topic) - putExtra(MainActivity.EXTRA_SUBSCRIPTION_DISPLAY_NAME, displayName(subscription)) + putExtra(MainActivity.EXTRA_SUBSCRIPTION_DISPLAY_NAME, displayName(appBaseUrl, subscription)) putExtra(MainActivity.EXTRA_SUBSCRIPTION_INSTANT, subscription.instant) putExtra(MainActivity.EXTRA_SUBSCRIPTION_MUTED_UNTIL, subscription.mutedUntil) } diff --git a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt index 851f43ac..0dd15499 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt @@ -19,6 +19,7 @@ import android.widget.Toast import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat +import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView @@ -81,6 +82,10 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra // Show 'Back' button supportActionBar?.setDisplayHomeAsUpEnabled(true) + // Hide links that lead to payments, see https://github.com/binwiederhier/ntfy/issues/1463 + val howToLink = findViewById(R.id.detail_how_to_link) + howToLink.isVisible = BuildConfig.PAYMENT_LINKS_AVAILABLE + // Handle direct deep links to topic "ntfy://..." val url = intent?.data if (intent?.action == ACTION_VIEW && url != null) { @@ -152,7 +157,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_ID, subscription.id) intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_BASE_URL, subscription.baseUrl) intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_TOPIC, subscription.topic) - intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_DISPLAY_NAME, displayName(subscription)) + intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_DISPLAY_NAME, displayName(appBaseUrl, subscription)) intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_INSTANT, subscription.instant) intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_MUTED_UNTIL, subscription.mutedUntil) @@ -277,10 +282,11 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra val subscription = repository.getSubscription(subscriptionId) ?: return@launch subscriptionInstant = subscription.instant subscriptionMutedUntil = subscription.mutedUntil - subscriptionDisplayName = displayName(subscription) + subscriptionDisplayName = displayName(appBaseUrl, subscription) showHideInstantMenuItems(subscriptionInstant) showHideMutedUntilMenuItems(subscriptionMutedUntil) + showHideCopyMenuItems(subscription.baseUrl) updateTitle(subscriptionDisplayName) } } @@ -316,6 +322,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra // Show and hide buttons showHideInstantMenuItems(subscriptionInstant) showHideMutedUntilMenuItems(subscriptionMutedUntil) + showHideCopyMenuItems(subscriptionBaseUrl) // Regularly check if "notification muted" time has passed // NOTE: This is done here, because then we know that we've initialized the menu items. @@ -559,6 +566,18 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra } } + + private fun showHideCopyMenuItems(subscriptionBaseUrl: String) { + if (!this::menu.isInitialized) { + return + } + runOnUiThread { + // Hide links that lead to payments, see https://github.com/binwiederhier/ntfy/issues/1463 + val copyUrlItem = menu.findItem(R.id.detail_menu_copy_url) + copyUrlItem?.isVisible = appBaseUrl != subscriptionBaseUrl || BuildConfig.PAYMENT_LINKS_AVAILABLE + } + } + private fun updateTitle(subscriptionDisplayName: String) { runOnUiThread { title = subscriptionDisplayName diff --git a/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt index ccc0191d..5d2af6a7 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt @@ -87,6 +87,7 @@ class DetailSettingsActivity : AppCompatActivity() { private lateinit var openChannelsPref: Preference private lateinit var iconSetLauncher: ActivityResultLauncher private lateinit var iconRemovePref: Preference + private lateinit var appBaseUrl: String override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.detail_preferences, rootKey) @@ -96,6 +97,7 @@ class DetailSettingsActivity : AppCompatActivity() { serviceManager = SubscriberServiceManager(requireActivity()) notificationService = NotificationService(requireActivity()) resolver = requireContext().applicationContext.contentResolver + appBaseUrl = requireContext().getString(R.string.app_base_url) // Create result launcher for custom icon (must be created in onCreatePreferences() directly) iconSetLauncher = createIconPickLauncher() @@ -381,7 +383,7 @@ class DetailSettingsActivity : AppCompatActivity() { save(newSubscription) // Update activity title activity?.runOnUiThread { - activity?.title = displayName(newSubscription) + activity?.title = displayName(appBaseUrl, newSubscription) } // Update dedicated notification channel if (newSubscription.dedicatedChannels) { @@ -394,9 +396,10 @@ class DetailSettingsActivity : AppCompatActivity() { } pref?.summaryProvider = Preference.SummaryProvider { provider -> if (TextUtils.isEmpty(provider.text)) { + val appBaseUrl = context?.getString(R.string.app_base_url) getString( R.string.detail_settings_appearance_display_name_default_summary, - displayName(subscription) + displayName(appBaseUrl, subscription) ) } else { provider.text diff --git a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt index 5ce60f42..5655826a 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt @@ -14,6 +14,7 @@ import android.os.Bundle import android.provider.Settings import android.provider.Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM import android.text.method.LinkMovementMethod +import android.text.util.Linkify import android.view.ActionMode import android.view.Menu import android.view.MenuItem @@ -26,6 +27,8 @@ import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat +import androidx.core.text.HtmlCompat +import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout @@ -227,6 +230,10 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc } } + // Hide links that lead to payments, see https://github.com/binwiederhier/ntfy/issues/1463 + val howToLink = findViewById(R.id.main_how_to_link) + howToLink.isVisible = BuildConfig.PAYMENT_LINKS_AVAILABLE + // Create notification channels right away, so we can configure them immediately after installing the app dispatcher?.init() @@ -276,7 +283,19 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc val wsRemindTimeReached = repository.getWebSocketRemindTime() < System.currentTimeMillis() val showBanner = hasSelfHostedSubscriptions && wsRemindTimeReached && !usingWebSockets val wsBanner = findViewById(R.id.main_banner_websocket) - wsBanner.visibility = if (showBanner) View.VISIBLE else View.GONE + if (showBanner) { + wsBanner.visibility = View.VISIBLE + if (!BuildConfig.PAYMENT_LINKS_AVAILABLE) { + // Hide links that lead to payments, see https://github.com/binwiederhier/ntfy/issues/1463 + // This is a big fat hack, but I have to release this quickly ... + val wsBannerMainText = findViewById(R.id.main_banner_websocket_text) + val raw = getString(R.string.main_banner_websocket_text) + val unlinked = raw.replace(Regex("]*>"), "") + wsBannerMainText.text = HtmlCompat.fromHtml(unlinked, HtmlCompat.FROM_HTML_MODE_LEGACY) + } + } else { + wsBanner.visibility = View.GONE + } } private fun showHideWebSocketReconnectBanner(subscriptions: List) { @@ -397,7 +416,11 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc runOnUiThread { // Show/hide menu items based on build config val rateAppItem = menu.findItem(R.id.main_menu_rate) + val docsItem = menu.findItem(R.id.main_menu_docs) + val reportBugItem = menu.findItem(R.id.main_menu_report_bug) rateAppItem.isVisible = BuildConfig.RATE_APP_AVAILABLE + docsItem.isVisible = BuildConfig.PAYMENT_LINKS_AVAILABLE // Google Payments Policy, see https://github.com/binwiederhier/ntfy/issues/1463 + reportBugItem.isVisible = BuildConfig.PAYMENT_LINKS_AVAILABLE // Google Payments Policy, see https://github.com/binwiederhier/ntfy/issues/1463 // Pause notification icons val notificationsEnabledItem = menu.findItem(R.id.main_menu_notifications_enabled) @@ -570,7 +593,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc } } } catch (e: Exception) { - val topic = displayName(subscription) + val topic = displayName(appBaseUrl, subscription) if (errorMessage == "") errorMessage = "$topic: ${e.message}" errors++ } @@ -597,7 +620,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc intent.putExtra(EXTRA_SUBSCRIPTION_ID, subscription.id) intent.putExtra(EXTRA_SUBSCRIPTION_BASE_URL, subscription.baseUrl) intent.putExtra(EXTRA_SUBSCRIPTION_TOPIC, subscription.topic) - intent.putExtra(EXTRA_SUBSCRIPTION_DISPLAY_NAME, displayName(subscription)) + intent.putExtra(EXTRA_SUBSCRIPTION_DISPLAY_NAME, displayName(appBaseUrl, subscription)) intent.putExtra(EXTRA_SUBSCRIPTION_INSTANT, subscription.instant) intent.putExtra(EXTRA_SUBSCRIPTION_MUTED_UNTIL, subscription.mutedUntil) startActivity(intent) @@ -610,7 +633,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc intent.putExtra(DetailActivity.EXTRA_SUBSCRIPTION_ID, subscription.id) intent.putExtra(DetailActivity.EXTRA_SUBSCRIPTION_BASE_URL, subscription.baseUrl) intent.putExtra(DetailActivity.EXTRA_SUBSCRIPTION_TOPIC, subscription.topic) - intent.putExtra(DetailActivity.EXTRA_SUBSCRIPTION_DISPLAY_NAME, displayName(subscription)) + intent.putExtra(DetailActivity.EXTRA_SUBSCRIPTION_DISPLAY_NAME, displayName(appBaseUrl, subscription)) startActivity(intent) } diff --git a/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt b/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt index ed0d2bd0..905db7c8 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt @@ -64,6 +64,7 @@ class MainAdapter(private val repository: Repository, private val onClick: (Subs private val notificationDisabledForeverImageView: View = itemView.findViewById(R.id.main_item_notification_disabled_forever_image) private val instantImageView: View = itemView.findViewById(R.id.main_item_instant_image) private val newItemsView: TextView = itemView.findViewById(R.id.main_item_new) + private val appBaseUrl = context.getString(R.string.app_base_url) fun bind(subscription: Subscription) { this.subscription = subscription @@ -99,7 +100,7 @@ class MainAdapter(private val repository: Repository, private val onClick: (Subs } else { imageView.setImageResource(R.drawable.ic_sms_gray_24dp) } - nameView.text = displayName(subscription) + nameView.text = displayName(appBaseUrl, subscription) statusView.text = statusMessage dateView.text = dateText dateView.visibility = if (isUnifiedPush) View.GONE else View.VISIBLE diff --git a/app/src/main/java/io/heckel/ntfy/util/Util.kt b/app/src/main/java/io/heckel/ntfy/util/Util.kt index a658a7fe..605a87d3 100644 --- a/app/src/main/java/io/heckel/ntfy/util/Util.kt +++ b/app/src/main/java/io/heckel/ntfy/util/Util.kt @@ -64,8 +64,13 @@ fun subscriptionTopicShortUrl(subscription: Subscription) : String { return topicShortUrl(subscription.baseUrl, subscription.topic) } -fun displayName(subscription: Subscription) : String { - return subscription.displayName ?: subscriptionTopicShortUrl(subscription) +fun displayName(appBaseUrl: String?, subscription: Subscription) : String { + if (subscription.displayName != null) { + return subscription.displayName + } else if (appBaseUrl == subscription.baseUrl) { + return subscription.topic + } + return subscriptionTopicShortUrl(subscription) } fun shortUrl(url: String) = url @@ -186,11 +191,11 @@ fun decodeBytesMessage(notification: Notification): ByteArray { * See above; prepend emojis to title if the title is non-empty. * Otherwise, they are prepended to the message. */ -fun formatTitle(subscription: Subscription, notification: Notification): String { +fun formatTitle(appBaseUrl: String?, subscription: Subscription, notification: Notification): String { return if (notification.title != "") { formatTitle(notification) } else { - displayName(subscription) + displayName(appBaseUrl, subscription) } } diff --git a/fastlane/metadata/android/en-US/changelog/44.txt b/fastlane/metadata/android/en-US/changelog/46.txt similarity index 100% rename from fastlane/metadata/android/en-US/changelog/44.txt rename to fastlane/metadata/android/en-US/changelog/46.txt From 18c54aeaa7c95ad8b1a1ec1cf5baf56ae9e4c4ce Mon Sep 17 00:00:00 2001 From: Johan Andersson Date: Sun, 12 Oct 2025 11:31:19 +0200 Subject: [PATCH 38/70] Translated using Weblate (Swedish) Currently translated at 100.0% (340 of 340 strings) Translation: ntfy/Android app Translate-URL: https://hosted.weblate.org/projects/ntfy/android/sv/ --- app/src/main/res/values-sv/strings.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 9005c50c..f04e4c3e 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -70,7 +70,7 @@ Rensa tjänstens URL Du har inte fått några meddelanden för detta ämne ännu. För att skicka meddelanden till det här ämnet, PUT eller POST till ämnesadressen. - Exempel (med curl):

$ curl -d \"Hej\" %1$s
+ $ curl -d \"Hej\" %1$s ]]> Detaljerade instruktioner finns på ntfy.sh och i dokumentationen. Ta bort alla meddelanden i det här ämnet\? Ta bort permanent @@ -343,4 +343,11 @@ Meddela endast en gång Använd de globala inställningarna Ikon som visas i meddelanden för detta ämne + För att säkerställa att WebSockets återansluter i bakgrunden, bevilja behörigheten Alarm & Påminnelser till ntfy + Fråga senare + Avfärda + Bevilja nu + Exakta larm + ntfy kan schemalägga exakta larm. Exakta larm krävs för att återansluta WebSockets i bakgrunden. Klicka för att återkalla behörigheten. + ntfy kan inte schemalägga exakta larm. Exakta larm krävs för att återansluta WebSockets i bakgrunden. Klicka för att bevilja behörigheten. From cb6dec17b0442895f8de11d3cce2d8af7de4b8db Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Tue, 14 Oct 2025 10:02:28 -0400 Subject: [PATCH 39/70] Update release notes --- fastlane/metadata/android/en-US/changelog/46.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fastlane/metadata/android/en-US/changelog/46.txt b/fastlane/metadata/android/en-US/changelog/46.txt index 2bb757a5..f94b7f8e 100644 --- a/fastlane/metadata/android/en-US/changelog/46.txt +++ b/fastlane/metadata/android/en-US/changelog/46.txt @@ -1,4 +1,9 @@ -This is a small release to remove the "Donate" button from menu, -as this violates the Google Play policies. +This release makes changes to comply with the Google Play policies. +See https://github.com/binwiederhier/ntfy/issues/1463 for details. -No further changes are in this release. +Changes: +- Remove the "Donate" button from menu (all variants) +- Change default display name from "ntfy.sh/mytopic" to "mytopic" (all variants) +- Remove links to ntfy docs and issue tracker (Play variant only) +- Remove how-to links to ntfy.sh in a few places (Play variant only) +- Remove "Copy topic address" from subscription menu (Play variant only) From f46474c7d81d29852947225f1fb7112027bfcff6 Mon Sep 17 00:00:00 2001 From: Ryu Siwoo Date: Fri, 17 Oct 2025 15:49:25 +0200 Subject: [PATCH 40/70] Translated using Weblate (Korean) Currently translated at 93.2% (317 of 340 strings) Translation: ntfy/Android app Translate-URL: https://hosted.weblate.org/projects/ntfy/android/ko/ --- app/src/main/res/values-ko/strings.xml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 5e9b81dd..076bcf77 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -1,13 +1,13 @@ 자세한 설명은 ntfy.sh와 docs 페이지에서 찾으실 수 있습니다. - 알림 (우선순위 높음) + 우선순위 높음 알림 음소거됨 즉시 전달 주제 3개 구독중 다른 서버 사용 알림 켜짐 - 알림 (우선순위 기본) - 알림 (우선순위 최상) + 우선순위 기본 + 우선순위 최상 구독 서비스 알림 수신중 즉시 전달 주제를 구독함 @@ -165,9 +165,9 @@ 연결 프로토콜 JSON stream over HTTP 표시 설정 - 알림 (우선순위 낮음) + 우선순위 낮음 저장 - 알림 (우선순위 최하) + 우선순위 최하 즉시 전달 주제 2개 구독중 즉시 전달 주제 5개 구독중 즉시 전달 주제 4개 구독중 @@ -214,7 +214,7 @@ 파일 열기 URL이 클립보드에 복사됨 서비스 URL 선택 - 예제 (curl 사용):

$ curl -d \\\"Hi\\\" %1$s
+ 예제 (curl 사용):
$ curl -d \\\"Hi\\\" %1$s
파일 정보를 읽을 수 없습니다: %1$s 테스트: 원한다면 제목을 설정할 수 있습니다. 즉시 전달 꺼짐 @@ -328,4 +328,5 @@ 사용자 추가 사용자 삭제 이 구독에 사용자 설정 사용 + 기본 그룹
From 5053721a48ba896fb8ddb5905b60e02375c303d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Mon, 20 Oct 2025 23:19:25 +0200 Subject: [PATCH 41/70] Translated using Weblate (Estonian) Currently translated at 100.0% (340 of 340 strings) Translation: ntfy/Android app Translate-URL: https://hosted.weblate.org/projects/ntfy/android/et/ --- app/src/main/res/values-et/strings.xml | 66 ++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index d2dcab01..a12ec93f 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -274,4 +274,70 @@ Taastamine õnnestus Taastamine ei õnnestunud: %1$s Täiendavad seadistused + Leviedasta sõnumeid + Rakendused saavad teavitusi leviedastusena (kõik saavad sama sõnumi) + Rakendused ei saa teavitusi leviedastusena + Kasuta UnifiedPushi + ntfy toimib UnifiedPushi levitajana + ntfy ei toimi UnifiedPushi levitajana + Salvesta logisid + Login (kuni 1,000 kirjet) seadmesse… + Lülita logimine sisse ja sa saad neid vigade otsimisel jagada. + Kopeeri logid või laadi nad üles + Kopeeri logid lõikelaule või laadi nad nopaste.net teenusesse (mille omanik on ntfy autor). Seadmete nimed ja aadressid on võimalik välja jätta, kui teavituste sisusid mitte. + Kopeeri lõikelauale + Kopeeri lõikelauale (tsenseerituna) + Laadi üles ja kopeeri link + Laadi üles ja kopeeri link (tsenseerituna) + Logid on kopeeritud lõikelauale + Logid on üleslaadimisel… + Logid on laaditud üles ja võrguaadress on kopeeritud + Logide üleslaadimine ei õnnestunud: %1$s + Need teemad ja seadmete nimed on asendatud puuviljade nimedega ja seega saad ohutumalt logi jagada:\n\n%1$s\n\nKa salasõnad on korjatud välja, kuid neid pole siin näidatud. + Ühtegi teemat ega seadme nime polnud asendatud. Kas sul üldse on teemade tellimusi? + Sobib + Kustuta logid + Kustuta varasemad logid ja alusta nullist + Logid on kustutatud + Ühendusprotokoll + Ühenduseks serveriga kasuta JSON-i voogedastust üle HTTP. See meetod on korralikult testitud, aga võib suurendada akukasutust. + Ühenduseks serveriga kasuta WebSocketsi protokolli. Selle meetodi kasutamine on esimene soovitus, aga see võib eeldada sinu proksiserveri täiendavat seadistamist. + JSON-i voogedastus üle HTTP + WebSockets + Kasuta üldist seadistust + kasutan üldist seadistust + Rakenduse teave + Lisa kasutaja + Muuda kasutajat + Sa võid muuta valitud kasutaja kasutajanime või salasõna, aga ta ka sootuks kustutada. + ntfy %1$s (%2$s) + Kopeeritud lõikelauale + Teenuse võrguaadress + Kasutajanimi + Salasõna + Salasõna (kui jääb tühjaks, siis ei muutu) + Lisa kasutaja + Katkesta + Kustuta kasutaja + Salvesta + Täpsed äratused + ntfy võib ajastada täpseid äratusi. Need on vajalikud WebSocketsi toimimiseks taustal. Klõpsa selle õiguse keelamiseks. + ntfy ei või ajastada täpseid äratusi. Need on vajalikud WebSocketsi toimimiseks taustal. Klõpsa selle õiguse lubamiseks. + Rakenduse teave + Versioon + Ikooni salvestamine ei õnnestu: %1$s + Kuvatav nimi + Määra selle tellimuse jaoks eraldi kuvatav nimi. Vaikimisi nime jaoks jäta tühjaks (%1$s). + %1$s (vaikimisi) + Välimus + Tellimuse ikoon + Vali teavitustes kuvatav ikoon + Tellimuste ikoon (eemaldamiseks klõpsa) + Teavituste kohanadatud seadistused + Kasutan selle tellimuse jaoks kohandatud teavitusi + Kasutan vaikimisi teavitusi (helimärguanded, „Ära sega“ olekuga mittearvestamine, jne) + Kohenda teavituste seadistusi + Helimärguanded, „Ära sega“ olekuga mittearvestamine, jne. + Jätka pidevate märguannetega + Anna märku vaid üks kord From 038aa6ea1ece9895038f20662fa42e11e2b0dcce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asger=20Geel=20Weirs=C3=B8e?= Date: Sun, 26 Oct 2025 15:59:58 +0100 Subject: [PATCH 42/70] Translated using Weblate (Danish) Currently translated at 27.6% (94 of 340 strings) Translation: ntfy/Android app Translate-URL: https://hosted.weblate.org/projects/ntfy/android/da/ --- app/src/main/res/values-da/strings.xml | 80 +++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 1a8bbb75..8135558b 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -17,4 +17,82 @@ Abonnerer på et emne med øjeblikkelig levering Abonnerer på fire emner med øjeblikkelig levering Høj prioritet - \ No newline at end of file + Abonnerer på et emne + Abonnerer på to emner + Abonnerer på tre emner + Abonnerer på fire emner + Abonnerer på fem emner + Abonnerer på seks emner + Abonnerer på %1$d emner + %1$d notifikation(er) modtaget + Alt er opdateret + Kunne ikke opdaterer %1$d abonnementer\n\n%2$s + Kunne ikke genopfriske abonnement %1$s + Notifikationer aktiveret + Notifikationer slået fra + Notifikationer slået fra indtil %1$s + Indstillinger + Anmeld fejl + Læs manualen + Anmeld appen ⭐ + Doner 💸 + Afmeld + Afmeld valgte emne(r) og slet alle notifikationer permanent? + Slet permanent + Annuller + %1$d notifikationer + %1$d notifikationer + Tilslutter … + %1$s (UnifiedPush) + i går + Tilføj abonomment + Det ser ud til at du ikke abonnere på noget endnu. + Klik + for at oprette eller abonnere på et emne. Derefter kan du modtage notifikationer på din enhed vha. PUT og POST. + Detaljeret instruktioner tilgængelige på ntfy.sh, og i manualen. + Dette abonnement er styret af %1$s vha. UnifiedPush + Batterioptimering bør være slået fra for appen for at undgå problemer med at modtage notifikationer. + Spørg senere + Afvis + Løs nu + Anvendelse af WebSockets er den anbefalede måde tilslutte dig din server, og kan forbedre batterilevetiden, men det kan kræve yderligere konfigurationer i din proxy. Dette kan ændres i indstillingerne. + Spørg senere + Afvis + Aktiver nu + For at kunne garantere at WebSockets genopretter forbindelsen i baggrunden, skal du give Alarm & Påmindelses tilladelser til ntfy + Spørg senere + Afvis + Tildel nu + Abonner på emne + Emner er ikke password-beskyttet, så vælg et navn der er svært at gætte. Når først du er abonnere, kan du PUT/POST notifikationer. + Emne navn, f.eks. jørns_alarmer + Brug anden server + Skriv URLs herunder for at abonnere på emner fra andre servere. + Øjeblikkelig levering i dvale + Garanter at meldingerne bliver leveret med det samme, selv hvis enheden er inaktiv. + Øjeblikkelig levering er altid aktiveret for andre værter end %1$s. + Annuller + Abonner + Tilbage + Log ind + Tilslutning fejlede: %1$s + Login krævet + Dette emne kræver at du logger ind. Skriv venligst dit brugernavn og password. + Brugernavn + Password + Login fejlede. Bruger %1$s er ikke autoriseret. + Ny bruger + Vælg service URL + Fjern service URL + Du har ikke modtaget nogen notifikationer for dette emne endnu. + For at sende notifikationer for dette emne, PUT eller POST til emne URLen. + $ curl -d \"Hej\"%1$s]]> + Detaljeret instruktioner tilgængelig på ntfy.sh, and in the docs. + Slet alle notifikationer for emnet? + Slet permanent + Annuller + Afmeld abonnementet for dette emne og slet alle modtagende notifikationer? + Slet permanent + Annuller + Test: Ændre titlen til det du vil. + Dette er en test notifikation fra ntfy Android app. Den har prioritets niveau %1$d. Hvis du sender en anden, kan den se anderledes ud. + From e4d4c5282a77cac9120905300a65d355b6d1c679 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 16 Nov 2025 20:21:47 -0500 Subject: [PATCH 43/70] Cursor colors --- app/src/main/java/io/heckel/ntfy/ui/Colors.kt | 6 ++-- app/src/main/res/layout/activity_main.xml | 8 +++-- app/src/main/res/values-night/colors.xml | 29 ++++++++++--------- app/src/main/res/values/colors.xml | 22 +++++++------- app/src/main/res/values/themes.xml | 14 +++++++-- 5 files changed, 47 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt index 46d0d19e..5e96ac8e 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt @@ -30,7 +30,7 @@ class Colors { } fun cardBackgroundColor(context: Context): Int { - return onPrimary(context) // SurfaceColors.getColorForElevation(context, 5f) + return MaterialColors.getColor(context, R.attr.colorSurface, Color.WHITE) } fun cardSelectedBackgroundColor(context: Context): Int { @@ -39,7 +39,7 @@ class Colors { fun statusBarNormal(context: Context, dynamicColors: Boolean, darkMode: Boolean): Int { val default = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - context.resources.getColor(R.color.action_bar) + context.resources.getColor(R.color.action_bar, null) } else { @Suppress("DEPRECATION") context.resources.getColor(R.color.action_bar) @@ -48,7 +48,7 @@ class Colors { if (darkMode) { MaterialColors.getColor(context, R.attr.colorSurface, default) } else { - MaterialColors.getColor(context, R.attr.colorOnPrimaryContainer, default) + MaterialColors.getColor(context, R.attr.colorPrimary, default) } } else { default diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index a391d370..1bf20371 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -22,7 +22,7 @@ @@ -166,7 +167,8 @@ diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 32343f1d..0103cc5e 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -16,16 +16,16 @@ #690005 #93000A #FFDAD6 - #0E1513 - #DEE4E0 - #0E1513 - #DEE4E0 + #121212 + #E0E0E0 + #121212 + #E0E0E0 #3F4946 - #BFC9C4 + #C0C0C0 #89938F #3F4946 #000000 - #DEE4E0 + #E0E0E0 #2B3230 #076B5B #A0F2DD @@ -40,13 +40,16 @@ #001E2E #AACBE4 #2A4A5F - #0E1513 - #343B38 - #090F0E - #171D1B - #1B211F - #252B29 - #303634 + #121212 + #383838 + #0D0D0D + #1B1B1B + #1B2023 + #282F33 + #333333 + + #121212 + #9AECD7 #002C24 #4D9F8C diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index facde9f1..94b87ae8 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -16,17 +16,17 @@ #FFFFFF #FFDAD6 #93000A - #F5FBF7 + #FFFFFF #171D1B - #F5FBF7 + #FFFFFF #171D1B - #DBE5E0 + #E0E0E0 #3F4946 #6F7976 - #BFC9C4 + #C0C0C0 #000000 #2B3230 - #ECF2EF + #F0F0F0 #84D6C2 #A0F2DD #00201A @@ -40,13 +40,13 @@ #001E2E #AACBE4 #2A4A5F - #D5DBD8 - #F5FBF7 + #E0E0E0 + #FFFFFF #FFFFFF - #EFF5F1 - #E9EFEC - #E3EAE6 - #DEE4E0 + #F5F5F5 + #F0F0F0 + #EEEEEE + #E0E0E0 #003E34 #FFFFFF #237A69 diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index c2df478e..304c77f1 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -82,11 +82,21 @@ + + + + + From 96b16d36ac56051c95796cfe10cbe63b5301290a Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 16 Nov 2025 21:00:41 -0500 Subject: [PATCH 44/70] Cursor is amazing --- app/src/main/java/io/heckel/ntfy/ui/Colors.kt | 6 +++--- app/src/main/res/layout/activity_detail.xml | 1 + app/src/main/res/values/themes.xml | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt index 5e96ac8e..cb1eef5b 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt @@ -3,8 +3,8 @@ package io.heckel.ntfy.ui import android.content.Context import android.graphics.Color import android.os.Build +import androidx.core.content.ContextCompat import com.google.android.material.color.MaterialColors -import com.google.android.material.elevation.SurfaceColors import io.heckel.ntfy.R class Colors { @@ -26,7 +26,7 @@ class Colors { } fun itemSelectedBackground(context: Context): Int { - return SurfaceColors.getColorForElevation(context, 10f) + return ContextCompat.getColor(context, R.color.md_theme_surfaceContainerHigh) } fun cardBackgroundColor(context: Context): Int { @@ -34,7 +34,7 @@ class Colors { } fun cardSelectedBackgroundColor(context: Context): Int { - return SurfaceColors.getColorForElevation(context, 20f) + return ContextCompat.getColor(context, R.color.md_theme_surfaceContainerHighest) } fun statusBarNormal(context: Context, dynamicColors: Boolean, darkMode: Boolean): Int { diff --git a/app/src/main/res/layout/activity_detail.xml b/app/src/main/res/layout/activity_detail.xml index b4dbd523..1a0a2434 100644 --- a/app/src/main/res/layout/activity_detail.xml +++ b/app/src/main/res/layout/activity_detail.xml @@ -18,6 +18,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="16dp" + android:background="?attr/colorSurfaceContainerHigh" app:layout_behavior="@string/appbar_scrolling_view_behavior"> - ?attr/colorSurfaceContainer + ?attr/colorPrimary @style/MyActionModeTitle From ba147abe2d52cc55e311f040fdd9cc68def9f1a6 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 16 Nov 2025 21:11:50 -0500 Subject: [PATCH 45/70] Back button white --- app/src/main/res/values/themes.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 8742a157..22a6d020 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -51,6 +51,7 @@ false true @style/OverflowButtonStyle + @style/ActionModeCloseButtonStyle @style/MyActionMode @@ -59,6 +60,10 @@ @android:color/white + + From ec5b6e13bd7bee96588ed6355719e2095602dca5 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 16 Nov 2025 21:27:30 -0500 Subject: [PATCH 46/70] FAB color --- app/src/main/res/values/themes.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 22a6d020..30610e6c 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -68,7 +68,10 @@ ?attr/colorError - + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 94b87ae8..c29fdabb 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -143,6 +143,7 @@ #C1C8C5 #076B5B + #EEEEEE @android:color/transparent From e810e28ae7072239775936bbb1c17c0a65a88961 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 16 Nov 2025 22:01:38 -0500 Subject: [PATCH 48/70] More dark mode tweaks --- app/src/main/java/io/heckel/ntfy/ui/Colors.kt | 2 +- app/src/main/res/values-night/colors.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt index cb1eef5b..0778543c 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt @@ -30,7 +30,7 @@ class Colors { } fun cardBackgroundColor(context: Context): Int { - return MaterialColors.getColor(context, R.attr.colorSurface, Color.WHITE) + return MaterialColors.getColor(context, R.attr.colorSurfaceContainer, Color.WHITE) } fun cardSelectedBackgroundColor(context: Context): Int { diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 34f3d55e..7612d2ad 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -48,7 +48,7 @@ #282F33 #333333 - #121212 + #1B2023 #121212 #9AECD7 From b2a716e086bc0f11521d99504b417232f67650e1 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 16 Nov 2025 22:07:12 -0500 Subject: [PATCH 49/70] More dark mode things --- app/src/main/java/io/heckel/ntfy/ui/Colors.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt index 0778543c..6688d113 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt @@ -34,7 +34,7 @@ class Colors { } fun cardSelectedBackgroundColor(context: Context): Int { - return ContextCompat.getColor(context, R.color.md_theme_surfaceContainerHighest) + return MaterialColors.getColor(context, R.attr.colorSurfaceContainer, Color.GRAY) } fun statusBarNormal(context: Context, dynamicColors: Boolean, darkMode: Boolean): Int { From fa079dd198d6d674453cc64d68236353c1e08572 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 16 Nov 2025 22:11:36 -0500 Subject: [PATCH 50/70] More refinements --- app/src/main/java/io/heckel/ntfy/ui/Colors.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt index 6688d113..40a8c1f7 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt @@ -34,7 +34,7 @@ class Colors { } fun cardSelectedBackgroundColor(context: Context): Int { - return MaterialColors.getColor(context, R.attr.colorSurfaceContainer, Color.GRAY) + return MaterialColors.getColor(context, R.attr.colorSurfaceContainerHigh, Color.GRAY) } fun statusBarNormal(context: Context, dynamicColors: Boolean, darkMode: Boolean): Int { From 6ca6db85c4d869016f35b0d563eee29ce84894f2 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Mon, 17 Nov 2025 16:57:35 -0500 Subject: [PATCH 51/70] Darker background for detail activity in light mode --- app/src/main/res/values-night/themes.xml | 2 +- app/src/main/res/values/colors.xml | 2 +- app/src/main/res/values/themes.xml | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index 166f34b7..4eb0eb0e 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -1,4 +1,4 @@ - + - + + + + + + From f0b7c18db87662e85c4146d5e58c45fbdc7c30b6 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Thu, 4 Dec 2025 15:34:23 -0500 Subject: [PATCH 64/70] Full size dialog --- app/src/main/java/io/heckel/ntfy/ui/Colors.kt | 28 +++++++++++++--- .../java/io/heckel/ntfy/ui/DetailActivity.kt | 31 ++++++++++++++---- .../heckel/ntfy/ui/DetailSettingsActivity.kt | 24 ++++++++++---- .../java/io/heckel/ntfy/ui/MainActivity.kt | 32 +++++++++++++++---- .../io/heckel/ntfy/ui/SettingsActivity.kt | 27 ++++++++++++---- .../java/io/heckel/ntfy/ui/ShareActivity.kt | 32 +++++++++++++++---- app/src/main/res/layout/app_bar_drawer.xml | 4 +-- .../main/res/menu/menu_detail_action_bar.xml | 5 --- .../main/res/menu/menu_main_action_bar.xml | 3 -- .../main/res/menu/menu_share_action_bar.xml | 1 - app/src/main/res/values/themes.xml | 2 -- 11 files changed, 140 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt index 34b4c04a..8363360e 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt @@ -54,16 +54,33 @@ class Colors { context.resources.getColor(R.color.action_bar) } return if (dynamicColors) { - if (darkMode) { - MaterialColors.getColor(context, R.attr.colorSurface, default) - } else { - MaterialColors.getColor(context, R.attr.colorPrimary, default) - } + // Use colorSurface for both light and dark mode when dynamic colors are enabled + MaterialColors.getColor(context, R.attr.colorSurface, default) } else { default } } + fun shouldUseLightStatusBar(dynamicColors: Boolean, darkMode: Boolean): Boolean { + // Use light status bar (dark icons) when dynamic colors are enabled in light mode + return dynamicColors && !darkMode + } + + fun toolbarTextColor(context: Context, dynamicColors: Boolean, darkMode: Boolean): Int { + return if (dynamicColors) { + // Use colorOnSurface (dark on light, light on dark) when dynamic colors are enabled + MaterialColors.getColor(context, R.attr.colorOnSurface, Color.BLACK) + } else { + if (darkMode) { + // In dark mode, toolbar is gray (surfaceContainer), so use light text + MaterialColors.getColor(context, R.attr.colorOnSurface, Color.WHITE) + } else { + // In light mode, toolbar is teal (primary), so use white text + MaterialColors.getColor(context, R.attr.colorOnPrimary, Color.WHITE) + } + } + } + fun dangerText(context: Context): Int { return MaterialColors.getColor(context, R.attr.colorError, Color.RED) } @@ -73,3 +90,4 @@ class Colors { } } } + diff --git a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt index e981ffa9..908cf7ed 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt @@ -19,6 +19,7 @@ import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.view.ActionMode import androidx.core.content.ContextCompat +import androidx.core.view.WindowInsetsControllerCompat import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.ItemTouchHelper @@ -53,6 +54,8 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import java.util.Date import kotlin.random.Random +import androidx.core.view.size +import androidx.core.view.get class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSettingsListener { private val viewModel by viewModels { @@ -122,12 +125,22 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet appBaseUrl = getString(R.string.app_base_url) val toolbarLayout = findViewById(R.id.app_bar_drawer) - toolbarLayout.setBackgroundColor(Colors.statusBarNormal( - this, - repository.getDynamicColorsEnabled(), - isDarkThemeOn(this) - )) - setSupportActionBar(toolbarLayout.findViewById(R.id.toolbar)) + val dynamicColors = repository.getDynamicColorsEnabled() + val darkMode = isDarkThemeOn(this) + val statusBarColor = Colors.statusBarNormal(this, dynamicColors, darkMode) + val toolbarTextColor = Colors.toolbarTextColor(this, dynamicColors, darkMode) + toolbarLayout.setBackgroundColor(statusBarColor) + + val toolbar = toolbarLayout.findViewById(R.id.toolbar) + toolbar.setTitleTextColor(toolbarTextColor) + toolbar.setNavigationIconTint(toolbarTextColor) + toolbar.overflowIcon?.setTint(toolbarTextColor) + setSupportActionBar(toolbar) + + // Set system status bar color and appearance + window.statusBarColor = statusBarColor + WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightStatusBars = + Colors.shouldUseLightStatusBar(dynamicColors, darkMode) // Set detail activity background: use theme background for dynamic colors, static gray for non-dynamic val detailContentLayout = findViewById(R.id.detail_content_layout) @@ -384,6 +397,12 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_detail_action_bar, menu) this.menu = menu + + // Tint menu icons based on theme + val toolbarTextColor = Colors.toolbarTextColor(this, repository.getDynamicColorsEnabled(), isDarkThemeOn(this)) + for (i in 0 until menu.size) { + menu[i].icon?.setTint(toolbarTextColor) + } // Show and hide buttons showHideInstantMenuItems(subscriptionInstant) diff --git a/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt index 66f13813..e012ba04 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt @@ -15,6 +15,7 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity import androidx.core.content.FileProvider import androidx.core.graphics.drawable.toDrawable +import androidx.core.view.WindowInsetsControllerCompat import androidx.lifecycle.lifecycleScope import androidx.preference.* import androidx.preference.Preference.OnPreferenceClickListener @@ -65,12 +66,23 @@ class DetailSettingsActivity : AppCompatActivity() { } val toolbarLayout = findViewById(R.id.app_bar_drawer) - toolbarLayout.setBackgroundColor(Colors.statusBarNormal( - this, - repository.getDynamicColorsEnabled(), - isDarkThemeOn(this) - )) - setSupportActionBar(toolbarLayout.findViewById(R.id.toolbar)) + val dynamicColors = repository.getDynamicColorsEnabled() + val darkMode = isDarkThemeOn(this) + val statusBarColor = Colors.statusBarNormal(this, dynamicColors, darkMode) + val toolbarTextColor = Colors.toolbarTextColor(this, dynamicColors, darkMode) + toolbarLayout.setBackgroundColor(statusBarColor) + + val toolbar = toolbarLayout.findViewById(R.id.toolbar) + toolbar.setTitleTextColor(toolbarTextColor) + toolbar.setNavigationIconTint(toolbarTextColor) + toolbar.overflowIcon?.setTint(toolbarTextColor) + setSupportActionBar(toolbar) + + // Set system status bar color and appearance + window.statusBarColor = statusBarColor + WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightStatusBars = + Colors.shouldUseLightStatusBar(dynamicColors, darkMode) + // Title val displayName = intent.getStringExtra(DetailActivity.EXTRA_SUBSCRIPTION_DISPLAY_NAME) ?: return title = displayName diff --git a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt index 64bf5457..6d64974e 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt @@ -30,6 +30,7 @@ import androidx.core.content.res.ResourcesCompat import androidx.core.text.HtmlCompat import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat +import androidx.core.view.WindowInsetsControllerCompat import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView @@ -72,6 +73,8 @@ import kotlinx.coroutines.launch import java.util.Date import java.util.concurrent.TimeUnit import kotlin.random.Random +import androidx.core.view.size +import androidx.core.view.get class MainActivity : AppCompatActivity(), AddFragment.SubscribeListener, NotificationFragment.NotificationSettingsListener { private val viewModel by viewModels { @@ -136,13 +139,23 @@ class MainActivity : AppCompatActivity(), AddFragment.SubscribeListener, Notific // Action bar val toolbarLayout = findViewById(R.id.app_bar_drawer) - toolbarLayout.setBackgroundColor(Colors.statusBarNormal( - this, - repository.getDynamicColorsEnabled(), - isDarkThemeOn(this) - )) - setSupportActionBar(toolbarLayout.findViewById(R.id.toolbar)) + val dynamicColors = repository.getDynamicColorsEnabled() + val darkMode = isDarkThemeOn(this) + val statusBarColor = Colors.statusBarNormal(this, dynamicColors, darkMode) + val toolbarTextColor = Colors.toolbarTextColor(this, dynamicColors, darkMode) + toolbarLayout.setBackgroundColor(statusBarColor) + + val toolbar = toolbarLayout.findViewById(R.id.toolbar) + toolbar.setTitleTextColor(toolbarTextColor) + toolbar.setNavigationIconTint(toolbarTextColor) + toolbar.overflowIcon?.setTint(toolbarTextColor) + setSupportActionBar(toolbar) title = getString(R.string.main_action_bar_title) + + // Set system status bar color and appearance + window.statusBarColor = statusBarColor + WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightStatusBars = + Colors.shouldUseLightStatusBar(dynamicColors, darkMode) // Floating action button ("+") fab = findViewById(R.id.fab) @@ -460,6 +473,13 @@ class MainActivity : AppCompatActivity(), AddFragment.SubscribeListener, Notific override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_main_action_bar, menu) this.menu = menu + + // Tint menu icons based on theme + val toolbarTextColor = Colors.toolbarTextColor(this, repository.getDynamicColorsEnabled(), isDarkThemeOn(this)) + for (i in 0 until menu.size) { + menu[i].icon?.setTint(toolbarTextColor) + } + showHideNotificationMenuItems() checkSubscriptionsMuted() // This is done here, because then we know that we've initialized the menu return true diff --git a/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt index bfc67834..170fede3 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt @@ -21,6 +21,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat +import androidx.core.view.WindowInsetsControllerCompat import androidx.fragment.app.DialogFragment import androidx.lifecycle.lifecycleScope import androidx.preference.* @@ -67,12 +68,26 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere serviceManager = SubscriberServiceManager(this) val toolbarLayout = findViewById(R.id.app_bar_drawer) - toolbarLayout.setBackgroundColor(Colors.statusBarNormal( + val dynamicColors = repository.getDynamicColorsEnabled() + val darkMode = isDarkThemeOn(this) + val statusBarColor = Colors.statusBarNormal( this, - repository.getDynamicColorsEnabled(), - isDarkThemeOn(this) - )) - setSupportActionBar(toolbarLayout.findViewById(R.id.toolbar)) + dynamicColors, + darkMode + ) + val toolbarTextColor = Colors.toolbarTextColor(this, dynamicColors, darkMode) + toolbarLayout.setBackgroundColor(statusBarColor) + + val toolbar = toolbarLayout.findViewById(R.id.toolbar) + toolbar.setTitleTextColor(toolbarTextColor) + toolbar.setNavigationIconTint(toolbarTextColor) + toolbar.overflowIcon?.setTint(toolbarTextColor) + setSupportActionBar(toolbar) + + // Set system status bar color and appearance + window.statusBarColor = statusBarColor + WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightStatusBars = + Colors.shouldUseLightStatusBar(dynamicColors, darkMode) if (savedInstanceState == null) { settingsFragment = SettingsFragment() // Empty constructor! @@ -342,7 +357,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere override fun putBoolean(key: String?, value: Boolean) { repository.setDynamicColorsEnabled(value) - // restart app + // Restart app val packageManager = requireContext().packageManager val packageName = requireContext().packageName val intent = packageManager.getLaunchIntentForPackage(packageName) diff --git a/app/src/main/java/io/heckel/ntfy/ui/ShareActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/ShareActivity.kt index c254283f..076e0cca 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/ShareActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/ShareActivity.kt @@ -9,6 +9,7 @@ import android.text.TextWatcher import android.view.* import android.widget.* import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.WindowInsetsControllerCompat import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import com.google.android.material.textfield.TextInputLayout @@ -18,6 +19,8 @@ import io.heckel.ntfy.msg.ApiService import io.heckel.ntfy.util.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import androidx.core.view.size +import androidx.core.view.get class ShareActivity : AppCompatActivity() { private val repository by lazy { (application as Application).repository } @@ -56,13 +59,23 @@ class ShareActivity : AppCompatActivity() { // Action bar val toolbarLayout = findViewById(R.id.app_bar_drawer) - toolbarLayout.setBackgroundColor(Colors.statusBarNormal( - this, - repository.getDynamicColorsEnabled(), - isDarkThemeOn(this) - )) - setSupportActionBar(toolbarLayout.findViewById(R.id.toolbar)) + val dynamicColors = repository.getDynamicColorsEnabled() + val darkMode = isDarkThemeOn(this) + val statusBarColor = Colors.statusBarNormal(this, dynamicColors, darkMode) + val toolbarTextColor = Colors.toolbarTextColor(this, dynamicColors, darkMode) + toolbarLayout.setBackgroundColor(statusBarColor) + + val toolbar = toolbarLayout.findViewById(R.id.toolbar) + toolbar.setTitleTextColor(toolbarTextColor) + toolbar.setNavigationIconTint(toolbarTextColor) + toolbar.overflowIcon?.setTint(toolbarTextColor) + setSupportActionBar(toolbar) title = getString(R.string.share_title) + + // Set system status bar color and appearance + window.statusBarColor = statusBarColor + WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightStatusBars = + Colors.shouldUseLightStatusBar(dynamicColors, darkMode) // Show 'Back' button supportActionBar?.setDisplayHomeAsUpEnabled(true) @@ -242,6 +255,13 @@ class ShareActivity : AppCompatActivity() { menuInflater.inflate(R.menu.menu_share_action_bar, menu) this.menu = menu sendItem = menu.findItem(R.id.share_menu_send) + + // Tint menu icons based on theme + val toolbarTextColor = Colors.toolbarTextColor(this, repository.getDynamicColorsEnabled(), isDarkThemeOn(this)) + for (i in 0 until menu.size) { + menu[i].icon?.setTint(toolbarTextColor) + } + validateInput() // Disable icon return true } diff --git a/app/src/main/res/layout/app_bar_drawer.xml b/app/src/main/res/layout/app_bar_drawer.xml index 821f6d27..f61c73b6 100644 --- a/app/src/main/res/layout/app_bar_drawer.xml +++ b/app/src/main/res/layout/app_bar_drawer.xml @@ -12,8 +12,6 @@ + android:layout_height="?attr/actionBarSize" /> diff --git a/app/src/main/res/menu/menu_detail_action_bar.xml b/app/src/main/res/menu/menu_detail_action_bar.xml index 94c4a75d..b90c71fb 100644 --- a/app/src/main/res/menu/menu_detail_action_bar.xml +++ b/app/src/main/res/menu/menu_detail_action_bar.xml @@ -5,31 +5,26 @@ android:id="@+id/detail_menu_notifications_enabled" android:icon="@drawable/ic_notifications_white_24dp" android:title="@string/detail_menu_notifications_enabled" - app:iconTint="@android:color/white" app:showAsAction="ifRoom" /> diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 33c6c7b8..6305636b 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -48,7 +48,6 @@ @color/md_theme_surfaceContainerHighest @style/MaterialSwitch - false true @style/OverflowButtonStyle @style/ActionModeCloseButtonStyle @@ -57,7 +56,6 @@ - diff --git a/app/src/main/res/values/theme_overlays.xml b/app/src/main/res/values/theme_overlays.xml deleted file mode 100644 index 607a9a6d..00000000 --- a/app/src/main/res/values/theme_overlays.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - - diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 6305636b..470ea305 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -49,18 +49,13 @@ @style/MaterialSwitch true - @style/OverflowButtonStyle + + @style/ActionMode @style/ActionModeCloseButtonStyle - - @style/MyActionMode + @style/OverflowButtonStyle - - - + - - + +