From bbc7549d7a198113421a9d70c129dc573c2673f1 Mon Sep 17 00:00:00 2001 From: Hunter Kehoe Date: Fri, 24 Jun 2022 09:15:22 -0600 Subject: [PATCH 1/4] custom display names fixes binwiederhier/ntfy#313 fixes binwiederhier/ntfy#291 (at least the android portion) --- .../io.heckel.ntfy.db.Database/12.json | 12 +++++-- .../java/io/heckel/ntfy/backup/Backuper.kt | 9 +++-- .../main/java/io/heckel/ntfy/db/Database.kt | 17 ++++++---- .../main/java/io/heckel/ntfy/db/Repository.kt | 2 ++ .../io/heckel/ntfy/msg/NotificationService.kt | 1 + .../java/io/heckel/ntfy/ui/DetailActivity.kt | 19 +++++++++-- .../heckel/ntfy/ui/DetailSettingsActivity.kt | 33 +++++++++++++++++-- .../java/io/heckel/ntfy/ui/MainActivity.kt | 5 ++- .../java/io/heckel/ntfy/ui/MainAdapter.kt | 4 +-- .../io/heckel/ntfy/up/BroadcastReceiver.kt | 1 + app/src/main/java/io/heckel/ntfy/util/Util.kt | 6 +++- app/src/main/res/values/strings.xml | 2 ++ app/src/main/res/values/values.xml | 1 + app/src/main/res/xml/detail_preferences.xml | 5 +++ 14 files changed, 95 insertions(+), 22 deletions(-) diff --git a/app/schemas/io.heckel.ntfy.db.Database/12.json b/app/schemas/io.heckel.ntfy.db.Database/12.json index 9743a78..8b1a443 100644 --- a/app/schemas/io.heckel.ntfy.db.Database/12.json +++ b/app/schemas/io.heckel.ntfy.db.Database/12.json @@ -2,11 +2,11 @@ "formatVersion": 1, "database": { "version": 12, - "identityHash": "b439720b55cf5e6bfdec2b56dd46103d", + "identityHash": "9363ad5196e88862acceb1bb9ee91124", "entities": [ { "tableName": "Subscription", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `minPriority` INTEGER NOT NULL, `autoDelete` INTEGER NOT NULL, `lastNotificationId` TEXT, `icon` TEXT, `upAppId` TEXT, `upConnectorToken` TEXT, PRIMARY KEY(`id`))", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `minPriority` INTEGER NOT NULL, `autoDelete` INTEGER NOT NULL, `lastNotificationId` TEXT, `icon` TEXT, `upAppId` TEXT, `upConnectorToken` TEXT, `displayName` TEXT, PRIMARY KEY(`id`))", "fields": [ { "fieldPath": "id", @@ -73,6 +73,12 @@ "columnName": "upConnectorToken", "affinity": "TEXT", "notNull": false + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": false } ], "primaryKey": { @@ -320,7 +326,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'b439720b55cf5e6bfdec2b56dd46103d')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '9363ad5196e88862acceb1bb9ee91124')" ] } } \ No newline at end of file diff --git a/app/src/main/java/io/heckel/ntfy/backup/Backuper.kt b/app/src/main/java/io/heckel/ntfy/backup/Backuper.kt index 120f41e..9ce3069 100644 --- a/app/src/main/java/io/heckel/ntfy/backup/Backuper.kt +++ b/app/src/main/java/io/heckel/ntfy/backup/Backuper.kt @@ -100,7 +100,8 @@ class Backuper(val context: Context) { lastNotificationId = s.lastNotificationId, icon = s.icon, upAppId = s.upAppId, - upConnectorToken = s.upConnectorToken + upConnectorToken = s.upConnectorToken, + displayName = s.displayName, )) } catch (e: Exception) { Log.w(TAG, "Unable to restore subscription ${s.id} (${topicUrl(s.baseUrl, s.topic)}): ${e.message}. Ignoring.", e) @@ -224,7 +225,8 @@ class Backuper(val context: Context) { lastNotificationId = s.lastNotificationId, icon = s.icon, upAppId = s.upAppId, - upConnectorToken = s.upConnectorToken + upConnectorToken = s.upConnectorToken, + displayName = s.displayName ) } } @@ -331,7 +333,8 @@ data class Subscription( val lastNotificationId: String?, val icon: String?, val upAppId: String?, - val upConnectorToken: String? + val upConnectorToken: String?, + val displayName: String? ) data class Notification( diff --git a/app/src/main/java/io/heckel/ntfy/db/Database.kt b/app/src/main/java/io/heckel/ntfy/db/Database.kt index eba9cb9..f5ddb44 100644 --- a/app/src/main/java/io/heckel/ntfy/db/Database.kt +++ b/app/src/main/java/io/heckel/ntfy/db/Database.kt @@ -22,13 +22,14 @@ data class Subscription( @ColumnInfo(name = "icon") val icon: String?, // content://-URI (or later other identifier) @ColumnInfo(name = "upAppId") val upAppId: String?, // UnifiedPush application package name @ColumnInfo(name = "upConnectorToken") val upConnectorToken: String?, // UnifiedPush connector token + @ColumnInfo(name = "displayName") val displayName: String?, @Ignore val totalCount: Int = 0, // Total notifications @Ignore val newCount: Int = 0, // New notifications @Ignore val lastActive: Long = 0, // Unix timestamp @Ignore val state: ConnectionState = ConnectionState.NOT_APPLICABLE ) { - constructor(id: Long, baseUrl: String, topic: String, instant: Boolean, mutedUntil: Long, minPriority: Int, autoDelete: Long, lastNotificationId: String, icon: String, upAppId: String, upConnectorToken: String) : - this(id, baseUrl, topic, instant, mutedUntil, minPriority, autoDelete, lastNotificationId, icon, upAppId, upConnectorToken, 0, 0, 0, ConnectionState.NOT_APPLICABLE) + constructor(id: Long, baseUrl: String, topic: String, instant: Boolean, mutedUntil: Long, minPriority: Int, autoDelete: Long, lastNotificationId: String, icon: String, upAppId: String, upConnectorToken: String, displayName: String?) : + this(id, baseUrl, topic, instant, mutedUntil, minPriority, autoDelete, lastNotificationId, icon, upAppId, upConnectorToken, displayName, 0, 0, 0, ConnectionState.NOT_APPLICABLE) } enum class ConnectionState { @@ -47,6 +48,7 @@ data class SubscriptionWithMetadata( val icon: String?, val upAppId: String?, val upConnectorToken: String?, + val displayName: String?, val totalCount: Int, val newCount: Int, val lastActive: Long @@ -266,6 +268,7 @@ abstract class Database : RoomDatabase() { private val MIGRATION_11_12 = object : Migration(11, 12) { override fun migrate(db: SupportSQLiteDatabase) { db.execSQL("ALTER TABLE Subscription ADD COLUMN lastNotificationId TEXT") + db.execSQL("ALTER TABLE Subscription ADD COLUMN displayName TEXT") } } } @@ -275,7 +278,7 @@ abstract class Database : RoomDatabase() { interface SubscriptionDao { @Query(""" SELECT - s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil, s.minPriority, s.autoDelete, s.lastNotificationId, s.icon, s.upAppId, s.upConnectorToken, + s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil, s.minPriority, s.autoDelete, s.lastNotificationId, s.icon, s.upAppId, s.upConnectorToken, s.displayName, COUNT(n.id) totalCount, COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount, IFNULL(MAX(n.timestamp),0) AS lastActive @@ -288,7 +291,7 @@ interface SubscriptionDao { @Query(""" SELECT - s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil, s.minPriority, s.autoDelete, s.lastNotificationId, s.icon, s.upAppId, s.upConnectorToken, + s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil, s.minPriority, s.autoDelete, s.lastNotificationId, s.icon, s.upAppId, s.upConnectorToken, s.displayName, COUNT(n.id) totalCount, COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount, IFNULL(MAX(n.timestamp),0) AS lastActive @@ -301,7 +304,7 @@ interface SubscriptionDao { @Query(""" SELECT - s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil, s.minPriority, s.autoDelete, s.lastNotificationId, s.icon, s.upAppId, s.upConnectorToken, + s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil, s.minPriority, s.autoDelete, s.lastNotificationId, s.icon, s.upAppId, s.upConnectorToken, s.displayName, COUNT(n.id) totalCount, COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount, IFNULL(MAX(n.timestamp),0) AS lastActive @@ -314,7 +317,7 @@ interface SubscriptionDao { @Query(""" SELECT - s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil, s.minPriority, s.autoDelete, s.lastNotificationId, s.icon, s.upAppId, s.upConnectorToken, + s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil, s.minPriority, s.autoDelete, s.lastNotificationId, s.icon, s.upAppId, s.upConnectorToken, s.displayName, COUNT(n.id) totalCount, COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount, IFNULL(MAX(n.timestamp),0) AS lastActive @@ -327,7 +330,7 @@ interface SubscriptionDao { @Query(""" SELECT - s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil, s.minPriority, s.autoDelete, s.lastNotificationId, s.icon, s.upAppId, s.upConnectorToken, + s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil, s.minPriority, s.autoDelete, s.lastNotificationId, s.icon, s.upAppId, s.upConnectorToken, s.displayName, COUNT(n.id) totalCount, COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount, IFNULL(MAX(n.timestamp),0) AS lastActive diff --git a/app/src/main/java/io/heckel/ntfy/db/Repository.kt b/app/src/main/java/io/heckel/ntfy/db/Repository.kt index d35a25d..9f13656 100644 --- a/app/src/main/java/io/heckel/ntfy/db/Repository.kt +++ b/app/src/main/java/io/heckel/ntfy/db/Repository.kt @@ -384,6 +384,7 @@ class Repository(private val sharedPrefs: SharedPreferences, private val databas icon = s.icon, upAppId = s.upAppId, upConnectorToken = s.upConnectorToken, + displayName = s.displayName, totalCount = s.totalCount, newCount = s.newCount, lastActive = s.lastActive, @@ -408,6 +409,7 @@ class Repository(private val sharedPrefs: SharedPreferences, private val databas icon = s.icon, upAppId = s.upAppId, upConnectorToken = s.upConnectorToken, + displayName = s.displayName, totalCount = s.totalCount, newCount = s.newCount, lastActive = s.lastActive, 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 06b8ad1..846e10b 100644 --- a/app/src/main/java/io/heckel/ntfy/msg/NotificationService.kt +++ b/app/src/main/java/io/heckel/ntfy/msg/NotificationService.kt @@ -300,6 +300,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_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 cfa4553..aff1ba6 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt @@ -54,6 +54,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra private var subscriptionId: Long = 0L // Set in onCreate() private var subscriptionBaseUrl: String = "" // Set in onCreate() private var subscriptionTopic: String = "" // Set in onCreate() + private var subscriptionDisplayName: String = "" // Set in onCreate() & updated by options menu! private var subscriptionInstant: Boolean = false // Set in onCreate() & updated by options menu! private var subscriptionMutedUntil: Long = 0L // Set in onCreate() & updated by options menu! @@ -97,7 +98,6 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra val secure = url.getBooleanQueryParameter("secure", true) val baseUrl = if (secure) "https://${url.host}" else "http://${url.host}" val topic = url.pathSegments.first() - title = topicShortUrl(baseUrl, topic) // Subscribe to topic if it doesn't already exist lifecycleScope.launch(Dispatchers.IO) { @@ -116,6 +116,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra icon = null, upAppId = null, upConnectorToken = null, + displayName = null, totalCount = 0, newCount = 0, lastActive = Date().time/1000 @@ -143,10 +144,13 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra } } + title = displayName(subscription) + // Add extras needed in loadView(); normally these are added in MainActivity 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_INSTANT, subscription.instant) intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_MUTED_UNTIL, subscription.mutedUntil) @@ -161,13 +165,14 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra subscriptionId = intent.getLongExtra(MainActivity.EXTRA_SUBSCRIPTION_ID, 0) subscriptionBaseUrl = intent.getStringExtra(MainActivity.EXTRA_SUBSCRIPTION_BASE_URL) ?: return subscriptionTopic = intent.getStringExtra(MainActivity.EXTRA_SUBSCRIPTION_TOPIC) ?: return + subscriptionDisplayName = intent.getStringExtra(MainActivity.EXTRA_SUBSCRIPTION_DISPLAY_NAME) ?: return subscriptionInstant = intent.getBooleanExtra(MainActivity.EXTRA_SUBSCRIPTION_INSTANT, false) subscriptionMutedUntil = intent.getLongExtra(MainActivity.EXTRA_SUBSCRIPTION_MUTED_UNTIL, 0L) // Set title val subscriptionBaseUrl = intent.getStringExtra(MainActivity.EXTRA_SUBSCRIPTION_BASE_URL) ?: return val topicUrl = topicShortUrl(subscriptionBaseUrl, subscriptionTopic) - title = topicUrl + title = subscriptionDisplayName // Set "how to instructions" val howToExample: TextView = findViewById(R.id.detail_how_to_example) @@ -263,9 +268,11 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra val subscription = repository.getSubscription(subscriptionId) ?: return@launch subscriptionInstant = subscription.instant subscriptionMutedUntil = subscription.mutedUntil + subscriptionDisplayName = displayName(subscription) showHideInstantMenuItems(subscriptionInstant) showHideMutedUntilMenuItems(subscriptionMutedUntil) + updateTitle(subscriptionDisplayName) } } @@ -543,6 +550,12 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra } } + private fun updateTitle(subscriptionDisplayName: String) { + runOnUiThread { + title = subscriptionDisplayName + } + } + private fun onClearClick() { Log.d(TAG, "Clearing all notifications for ${topicShortUrl(subscriptionBaseUrl, subscriptionTopic)}") @@ -571,6 +584,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra intent.putExtra(EXTRA_SUBSCRIPTION_ID, subscriptionId) intent.putExtra(EXTRA_SUBSCRIPTION_BASE_URL, subscriptionBaseUrl) intent.putExtra(EXTRA_SUBSCRIPTION_TOPIC, subscriptionTopic) + intent.putExtra(EXTRA_SUBSCRIPTION_DISPLAY_NAME, subscriptionDisplayName) startActivity(intent) } @@ -747,5 +761,6 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra const val EXTRA_SUBSCRIPTION_ID = "subscriptionId" const val EXTRA_SUBSCRIPTION_BASE_URL = "baseUrl" const val EXTRA_SUBSCRIPTION_TOPIC = "topic" + const val EXTRA_SUBSCRIPTION_DISPLAY_NAME = "displayName" } } 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 f4c39e8..757745a 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt @@ -55,9 +55,8 @@ class DetailSettingsActivity : AppCompatActivity() { } // Title - val baseUrl = intent.getStringExtra(DetailActivity.EXTRA_SUBSCRIPTION_BASE_URL) ?: return - val topic = intent.getStringExtra(DetailActivity.EXTRA_SUBSCRIPTION_TOPIC) ?: return - title = topicShortUrl(baseUrl, topic) + val displayName = intent.getStringExtra(DetailActivity.EXTRA_SUBSCRIPTION_DISPLAY_NAME) ?: return + title = displayName // Show 'Back' button supportActionBar?.setDisplayHomeAsUpEnabled(true) @@ -108,6 +107,7 @@ class DetailSettingsActivity : AppCompatActivity() { loadAutoDeletePref() loadIconSetPref() loadIconRemovePref() + loadDisplayNamePref() } private fun loadInstantPref() { @@ -276,6 +276,33 @@ class DetailSettingsActivity : AppCompatActivity() { } } + private fun loadDisplayNamePref() { + val prefId = context?.getString(R.string.detail_settings_appearance_display_name_key) ?: return + val pref: EditTextPreference? = findPreference(prefId) + pref?.isVisible = true // Hack: Show all settings at once, because subscription is loaded asynchronously + pref?.text = subscription.displayName + pref?.preferenceDataStore = object : PreferenceDataStore() { + override fun putString(key: String?, value: String?) { + val displayName: String? = if (value == "") { + null + } else { + value + } + val newSubscription = subscription.copy(displayName = displayName) + save(newSubscription) // TODO: does this need refresh=true? + activity?.runOnUiThread { + activity?.title = displayName(newSubscription) + } + } + override fun getString(key: String?, defValue: String?): String { + return subscription.displayName ?: "" + } + } + pref?.summaryProvider = Preference.SummaryProvider { _ -> + getString(R.string.detail_settings_appearance_display_name_summary, displayName(subscription), topicShortUrl(subscription.baseUrl, subscription.topic)) + } + } + private fun createIconPickLauncher(): ActivityResultLauncher { return registerForActivityResult(ActivityResultContracts.GetContent()) { inputUri -> if (inputUri == null) { 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 5321a85..10b7228 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt @@ -438,6 +438,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc icon = null, upAppId = null, upConnectorToken = null, + displayName = null, totalCount = 0, newCount = 0, lastActive = Date().time/1000 @@ -509,7 +510,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc } } } catch (e: Exception) { - val topic = topicShortUrl(subscription.baseUrl, subscription.topic) + val topic = displayName(subscription) if (errorMessage == "") errorMessage = "$topic: ${e.message}" errors++ } @@ -536,6 +537,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_INSTANT, subscription.instant) intent.putExtra(EXTRA_SUBSCRIPTION_MUTED_UNTIL, subscription.mutedUntil) startActivity(intent) @@ -662,6 +664,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc const val EXTRA_SUBSCRIPTION_ID = "subscriptionId" const val EXTRA_SUBSCRIPTION_BASE_URL = "subscriptionBaseUrl" const val EXTRA_SUBSCRIPTION_TOPIC = "subscriptionTopic" + const val EXTRA_SUBSCRIPTION_DISPLAY_NAME = "subscriptionDisplayName" const val EXTRA_SUBSCRIPTION_INSTANT = "subscriptionInstant" const val EXTRA_SUBSCRIPTION_MUTED_UNTIL = "subscriptionMutedUntil" const val ANIMATION_DURATION = 80L 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 0ffa4fa..bb78468 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt @@ -20,7 +20,7 @@ import io.heckel.ntfy.db.Subscription import io.heckel.ntfy.msg.NotificationService import io.heckel.ntfy.util.Log import io.heckel.ntfy.util.readBitmapFromUriOrNull -import io.heckel.ntfy.util.topicShortUrl +import io.heckel.ntfy.util.displayName import java.text.DateFormat import java.util.* @@ -101,7 +101,7 @@ class MainAdapter(private val repository: Repository, private val onClick: (Subs if (subscription.icon != null) { imageView.setImageBitmap(subscription.icon.readBitmapFromUriOrNull(context)) } - nameView.text = topicShortUrl(subscription.baseUrl, subscription.topic) + nameView.text = displayName(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/up/BroadcastReceiver.kt b/app/src/main/java/io/heckel/ntfy/up/BroadcastReceiver.kt index 6906399..9119e15 100644 --- a/app/src/main/java/io/heckel/ntfy/up/BroadcastReceiver.kt +++ b/app/src/main/java/io/heckel/ntfy/up/BroadcastReceiver.kt @@ -79,6 +79,7 @@ class BroadcastReceiver : android.content.BroadcastReceiver() { icon = null, upAppId = appId, upConnectorToken = connectorToken, + displayName = null, totalCount = 0, newCount = 0, lastActive = Date().time/1000 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 aa23f55..a6a3197 100644 --- a/app/src/main/java/io/heckel/ntfy/util/Util.kt +++ b/app/src/main/java/io/heckel/ntfy/util/Util.kt @@ -53,6 +53,10 @@ fun topicUrlAuth(baseUrl: String, topic: String) = "${topicUrl(baseUrl, topic)}/ fun topicUrlJsonPoll(baseUrl: String, topic: String, since: String) = "${topicUrl(baseUrl, topic)}/json?poll=1&since=$since" fun topicShortUrl(baseUrl: String, topic: String) = shortUrl(topicUrl(baseUrl, topic)) +fun displayName(subscription: Subscription) : String { + return subscription.displayName ?: topicShortUrl(subscription.baseUrl, subscription.topic) +} + fun shortUrl(url: String) = url .replace("http://", "") .replace("https://", "") @@ -176,7 +180,7 @@ fun formatTitle(subscription: Subscription, notification: Notification): String return if (notification.title != "") { formatTitle(notification) } else { - topicShortUrl(subscription.baseUrl, subscription.topic) + displayName(subscription) } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 10cb1a3..ea80adb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -353,6 +353,8 @@ Subscription icon (tap to remove) Icon displayed in notifications for this topic Unable to save icon: %1$s + Display name + Set a custom display name for this subscription. Leave empty for default\nCurrent: %1$s\nDefault: %2$s Use global setting using global setting diff --git a/app/src/main/res/values/values.xml b/app/src/main/res/values/values.xml index e199f8d..d5b4859 100644 --- a/app/src/main/res/values/values.xml +++ b/app/src/main/res/values/values.xml @@ -36,6 +36,7 @@ SubscriptionAutoDelete SubscriptionIconSet SubscriptionIconRemove + SubscriptionDisplayName diff --git a/app/src/main/res/xml/detail_preferences.xml b/app/src/main/res/xml/detail_preferences.xml index 660635d..b398170 100644 --- a/app/src/main/res/xml/detail_preferences.xml +++ b/app/src/main/res/xml/detail_preferences.xml @@ -38,5 +38,10 @@ app:title="@string/detail_settings_appearance_icon_remove_title" app:summary="@string/detail_settings_appearance_icon_remove_summary" app:isPreferenceVisible="false"/> + From f18285a17086f8c49db2a2cc83212b0eba3287b4 Mon Sep 17 00:00:00 2001 From: Hunter Kehoe Date: Fri, 24 Jun 2022 10:08:33 -0600 Subject: [PATCH 2/4] use custom dialog with display name preference --- .../java/io/heckel/ntfy/ui/DetailSettingsActivity.kt | 12 ++++++++++-- app/src/main/res/values/strings.xml | 3 ++- app/src/main/res/xml/detail_preferences.xml | 3 ++- 3 files changed, 14 insertions(+), 4 deletions(-) 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 757745a..e6df89b 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt @@ -4,6 +4,7 @@ import android.content.ContentResolver import android.graphics.BitmapFactory import android.net.Uri import android.os.Bundle +import android.text.TextUtils import android.widget.Toast import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts @@ -298,8 +299,15 @@ class DetailSettingsActivity : AppCompatActivity() { return subscription.displayName ?: "" } } - pref?.summaryProvider = Preference.SummaryProvider { _ -> - getString(R.string.detail_settings_appearance_display_name_summary, displayName(subscription), topicShortUrl(subscription.baseUrl, subscription.topic)) + pref?.summaryProvider = Preference.SummaryProvider { provider -> + if (TextUtils.isEmpty(provider.text)) { + getString( + R.string.detail_settings_appearance_display_name_default_summary, + displayName(subscription) + ) + } else { + provider.text + } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ea80adb..1691d49 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -354,7 +354,8 @@ Icon displayed in notifications for this topic Unable to save icon: %1$s Display name - Set a custom display name for this subscription. Leave empty for default\nCurrent: %1$s\nDefault: %2$s + Set a custom display name for this subscription. Leave empty for default + %1$s (default) Use global setting using global setting diff --git a/app/src/main/res/xml/detail_preferences.xml b/app/src/main/res/xml/detail_preferences.xml index b398170..184bdb4 100644 --- a/app/src/main/res/xml/detail_preferences.xml +++ b/app/src/main/res/xml/detail_preferences.xml @@ -41,7 +41,8 @@ From e69692fe9e6cedf01dd55ab067f94cae4c2b550d Mon Sep 17 00:00:00 2001 From: Hunter Kehoe Date: Fri, 24 Jun 2022 10:19:53 -0600 Subject: [PATCH 3/4] remove TODO --- app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e6df89b..8ccfad8 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt @@ -290,7 +290,7 @@ class DetailSettingsActivity : AppCompatActivity() { value } val newSubscription = subscription.copy(displayName = displayName) - save(newSubscription) // TODO: does this need refresh=true? + save(newSubscription) activity?.runOnUiThread { activity?.title = displayName(newSubscription) } From c5496c3f8c54940cd29baf133649bff1e0161c54 Mon Sep 17 00:00:00 2001 From: Hunter Kehoe Date: Fri, 24 Jun 2022 10:32:48 -0600 Subject: [PATCH 4/4] fix problem with deep links --- app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 aff1ba6..4fc9ec7 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt @@ -98,6 +98,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra val secure = url.getBooleanQueryParameter("secure", true) val baseUrl = if (secure) "https://${url.host}" else "http://${url.host}" val topic = url.pathSegments.first() + title = topicShortUrl(baseUrl, topic) // Subscribe to topic if it doesn't already exist lifecycleScope.launch(Dispatchers.IO) { @@ -144,8 +145,6 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra } } - title = displayName(subscription) - // Add extras needed in loadView(); normally these are added in MainActivity intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_ID, subscription.id) intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_BASE_URL, subscription.baseUrl)