custom display names
fixes binwiederhier/ntfy#313 fixes binwiederhier/ntfy#291 (at least the android portion)
This commit is contained in:
parent
6333a063a1
commit
bbc7549d7a
14 changed files with 95 additions and 22 deletions
|
@ -2,11 +2,11 @@
|
||||||
"formatVersion": 1,
|
"formatVersion": 1,
|
||||||
"database": {
|
"database": {
|
||||||
"version": 12,
|
"version": 12,
|
||||||
"identityHash": "b439720b55cf5e6bfdec2b56dd46103d",
|
"identityHash": "9363ad5196e88862acceb1bb9ee91124",
|
||||||
"entities": [
|
"entities": [
|
||||||
{
|
{
|
||||||
"tableName": "Subscription",
|
"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": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"fieldPath": "id",
|
"fieldPath": "id",
|
||||||
|
@ -73,6 +73,12 @@
|
||||||
"columnName": "upConnectorToken",
|
"columnName": "upConnectorToken",
|
||||||
"affinity": "TEXT",
|
"affinity": "TEXT",
|
||||||
"notNull": false
|
"notNull": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "displayName",
|
||||||
|
"columnName": "displayName",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"primaryKey": {
|
"primaryKey": {
|
||||||
|
@ -320,7 +326,7 @@
|
||||||
"views": [],
|
"views": [],
|
||||||
"setupQueries": [
|
"setupQueries": [
|
||||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
"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')"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -100,7 +100,8 @@ class Backuper(val context: Context) {
|
||||||
lastNotificationId = s.lastNotificationId,
|
lastNotificationId = s.lastNotificationId,
|
||||||
icon = s.icon,
|
icon = s.icon,
|
||||||
upAppId = s.upAppId,
|
upAppId = s.upAppId,
|
||||||
upConnectorToken = s.upConnectorToken
|
upConnectorToken = s.upConnectorToken,
|
||||||
|
displayName = s.displayName,
|
||||||
))
|
))
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.w(TAG, "Unable to restore subscription ${s.id} (${topicUrl(s.baseUrl, s.topic)}): ${e.message}. Ignoring.", e)
|
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,
|
lastNotificationId = s.lastNotificationId,
|
||||||
icon = s.icon,
|
icon = s.icon,
|
||||||
upAppId = s.upAppId,
|
upAppId = s.upAppId,
|
||||||
upConnectorToken = s.upConnectorToken
|
upConnectorToken = s.upConnectorToken,
|
||||||
|
displayName = s.displayName
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,7 +333,8 @@ data class Subscription(
|
||||||
val lastNotificationId: String?,
|
val lastNotificationId: String?,
|
||||||
val icon: String?,
|
val icon: String?,
|
||||||
val upAppId: String?,
|
val upAppId: String?,
|
||||||
val upConnectorToken: String?
|
val upConnectorToken: String?,
|
||||||
|
val displayName: String?
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Notification(
|
data class Notification(
|
||||||
|
|
|
@ -22,13 +22,14 @@ data class Subscription(
|
||||||
@ColumnInfo(name = "icon") val icon: String?, // content://-URI (or later other identifier)
|
@ColumnInfo(name = "icon") val icon: String?, // content://-URI (or later other identifier)
|
||||||
@ColumnInfo(name = "upAppId") val upAppId: String?, // UnifiedPush application package name
|
@ColumnInfo(name = "upAppId") val upAppId: String?, // UnifiedPush application package name
|
||||||
@ColumnInfo(name = "upConnectorToken") val upConnectorToken: String?, // UnifiedPush connector token
|
@ColumnInfo(name = "upConnectorToken") val upConnectorToken: String?, // UnifiedPush connector token
|
||||||
|
@ColumnInfo(name = "displayName") val displayName: String?,
|
||||||
@Ignore val totalCount: Int = 0, // Total notifications
|
@Ignore val totalCount: Int = 0, // Total notifications
|
||||||
@Ignore val newCount: Int = 0, // New notifications
|
@Ignore val newCount: Int = 0, // New notifications
|
||||||
@Ignore val lastActive: Long = 0, // Unix timestamp
|
@Ignore val lastActive: Long = 0, // Unix timestamp
|
||||||
@Ignore val state: ConnectionState = ConnectionState.NOT_APPLICABLE
|
@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) :
|
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, 0, 0, 0, ConnectionState.NOT_APPLICABLE)
|
this(id, baseUrl, topic, instant, mutedUntil, minPriority, autoDelete, lastNotificationId, icon, upAppId, upConnectorToken, displayName, 0, 0, 0, ConnectionState.NOT_APPLICABLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class ConnectionState {
|
enum class ConnectionState {
|
||||||
|
@ -47,6 +48,7 @@ data class SubscriptionWithMetadata(
|
||||||
val icon: String?,
|
val icon: String?,
|
||||||
val upAppId: String?,
|
val upAppId: String?,
|
||||||
val upConnectorToken: String?,
|
val upConnectorToken: String?,
|
||||||
|
val displayName: String?,
|
||||||
val totalCount: Int,
|
val totalCount: Int,
|
||||||
val newCount: Int,
|
val newCount: Int,
|
||||||
val lastActive: Long
|
val lastActive: Long
|
||||||
|
@ -266,6 +268,7 @@ abstract class Database : RoomDatabase() {
|
||||||
private val MIGRATION_11_12 = object : Migration(11, 12) {
|
private val MIGRATION_11_12 = object : Migration(11, 12) {
|
||||||
override fun migrate(db: SupportSQLiteDatabase) {
|
override fun migrate(db: SupportSQLiteDatabase) {
|
||||||
db.execSQL("ALTER TABLE Subscription ADD COLUMN lastNotificationId TEXT")
|
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 {
|
interface SubscriptionDao {
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT
|
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(n.id) totalCount,
|
||||||
COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount,
|
COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount,
|
||||||
IFNULL(MAX(n.timestamp),0) AS lastActive
|
IFNULL(MAX(n.timestamp),0) AS lastActive
|
||||||
|
@ -288,7 +291,7 @@ interface SubscriptionDao {
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT
|
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(n.id) totalCount,
|
||||||
COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount,
|
COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount,
|
||||||
IFNULL(MAX(n.timestamp),0) AS lastActive
|
IFNULL(MAX(n.timestamp),0) AS lastActive
|
||||||
|
@ -301,7 +304,7 @@ interface SubscriptionDao {
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT
|
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(n.id) totalCount,
|
||||||
COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount,
|
COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount,
|
||||||
IFNULL(MAX(n.timestamp),0) AS lastActive
|
IFNULL(MAX(n.timestamp),0) AS lastActive
|
||||||
|
@ -314,7 +317,7 @@ interface SubscriptionDao {
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT
|
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(n.id) totalCount,
|
||||||
COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount,
|
COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount,
|
||||||
IFNULL(MAX(n.timestamp),0) AS lastActive
|
IFNULL(MAX(n.timestamp),0) AS lastActive
|
||||||
|
@ -327,7 +330,7 @@ interface SubscriptionDao {
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT
|
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(n.id) totalCount,
|
||||||
COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount,
|
COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount,
|
||||||
IFNULL(MAX(n.timestamp),0) AS lastActive
|
IFNULL(MAX(n.timestamp),0) AS lastActive
|
||||||
|
|
|
@ -384,6 +384,7 @@ class Repository(private val sharedPrefs: SharedPreferences, private val databas
|
||||||
icon = s.icon,
|
icon = s.icon,
|
||||||
upAppId = s.upAppId,
|
upAppId = s.upAppId,
|
||||||
upConnectorToken = s.upConnectorToken,
|
upConnectorToken = s.upConnectorToken,
|
||||||
|
displayName = s.displayName,
|
||||||
totalCount = s.totalCount,
|
totalCount = s.totalCount,
|
||||||
newCount = s.newCount,
|
newCount = s.newCount,
|
||||||
lastActive = s.lastActive,
|
lastActive = s.lastActive,
|
||||||
|
@ -408,6 +409,7 @@ class Repository(private val sharedPrefs: SharedPreferences, private val databas
|
||||||
icon = s.icon,
|
icon = s.icon,
|
||||||
upAppId = s.upAppId,
|
upAppId = s.upAppId,
|
||||||
upConnectorToken = s.upConnectorToken,
|
upConnectorToken = s.upConnectorToken,
|
||||||
|
displayName = s.displayName,
|
||||||
totalCount = s.totalCount,
|
totalCount = s.totalCount,
|
||||||
newCount = s.newCount,
|
newCount = s.newCount,
|
||||||
lastActive = s.lastActive,
|
lastActive = s.lastActive,
|
||||||
|
|
|
@ -300,6 +300,7 @@ class NotificationService(val context: Context) {
|
||||||
putExtra(MainActivity.EXTRA_SUBSCRIPTION_ID, subscription.id)
|
putExtra(MainActivity.EXTRA_SUBSCRIPTION_ID, subscription.id)
|
||||||
putExtra(MainActivity.EXTRA_SUBSCRIPTION_BASE_URL, subscription.baseUrl)
|
putExtra(MainActivity.EXTRA_SUBSCRIPTION_BASE_URL, subscription.baseUrl)
|
||||||
putExtra(MainActivity.EXTRA_SUBSCRIPTION_TOPIC, subscription.topic)
|
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_INSTANT, subscription.instant)
|
||||||
putExtra(MainActivity.EXTRA_SUBSCRIPTION_MUTED_UNTIL, subscription.mutedUntil)
|
putExtra(MainActivity.EXTRA_SUBSCRIPTION_MUTED_UNTIL, subscription.mutedUntil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra
|
||||||
private var subscriptionId: Long = 0L // Set in onCreate()
|
private var subscriptionId: Long = 0L // Set in onCreate()
|
||||||
private var subscriptionBaseUrl: String = "" // Set in onCreate()
|
private var subscriptionBaseUrl: String = "" // Set in onCreate()
|
||||||
private var subscriptionTopic: 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 subscriptionInstant: Boolean = false // Set in onCreate() & updated by options menu!
|
||||||
private var subscriptionMutedUntil: Long = 0L // 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 secure = url.getBooleanQueryParameter("secure", true)
|
||||||
val baseUrl = if (secure) "https://${url.host}" else "http://${url.host}"
|
val baseUrl = if (secure) "https://${url.host}" else "http://${url.host}"
|
||||||
val topic = url.pathSegments.first()
|
val topic = url.pathSegments.first()
|
||||||
title = topicShortUrl(baseUrl, topic)
|
|
||||||
|
|
||||||
// Subscribe to topic if it doesn't already exist
|
// Subscribe to topic if it doesn't already exist
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
@ -116,6 +116,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra
|
||||||
icon = null,
|
icon = null,
|
||||||
upAppId = null,
|
upAppId = null,
|
||||||
upConnectorToken = null,
|
upConnectorToken = null,
|
||||||
|
displayName = null,
|
||||||
totalCount = 0,
|
totalCount = 0,
|
||||||
newCount = 0,
|
newCount = 0,
|
||||||
lastActive = Date().time/1000
|
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
|
// Add extras needed in loadView(); normally these are added in MainActivity
|
||||||
intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_ID, subscription.id)
|
intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_ID, subscription.id)
|
||||||
intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_BASE_URL, subscription.baseUrl)
|
intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_BASE_URL, subscription.baseUrl)
|
||||||
intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_TOPIC, subscription.topic)
|
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_INSTANT, subscription.instant)
|
||||||
intent.putExtra(MainActivity.EXTRA_SUBSCRIPTION_MUTED_UNTIL, subscription.mutedUntil)
|
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)
|
subscriptionId = intent.getLongExtra(MainActivity.EXTRA_SUBSCRIPTION_ID, 0)
|
||||||
subscriptionBaseUrl = intent.getStringExtra(MainActivity.EXTRA_SUBSCRIPTION_BASE_URL) ?: return
|
subscriptionBaseUrl = intent.getStringExtra(MainActivity.EXTRA_SUBSCRIPTION_BASE_URL) ?: return
|
||||||
subscriptionTopic = intent.getStringExtra(MainActivity.EXTRA_SUBSCRIPTION_TOPIC) ?: 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)
|
subscriptionInstant = intent.getBooleanExtra(MainActivity.EXTRA_SUBSCRIPTION_INSTANT, false)
|
||||||
subscriptionMutedUntil = intent.getLongExtra(MainActivity.EXTRA_SUBSCRIPTION_MUTED_UNTIL, 0L)
|
subscriptionMutedUntil = intent.getLongExtra(MainActivity.EXTRA_SUBSCRIPTION_MUTED_UNTIL, 0L)
|
||||||
|
|
||||||
// Set title
|
// Set title
|
||||||
val subscriptionBaseUrl = intent.getStringExtra(MainActivity.EXTRA_SUBSCRIPTION_BASE_URL) ?: return
|
val subscriptionBaseUrl = intent.getStringExtra(MainActivity.EXTRA_SUBSCRIPTION_BASE_URL) ?: return
|
||||||
val topicUrl = topicShortUrl(subscriptionBaseUrl, subscriptionTopic)
|
val topicUrl = topicShortUrl(subscriptionBaseUrl, subscriptionTopic)
|
||||||
title = topicUrl
|
title = subscriptionDisplayName
|
||||||
|
|
||||||
// Set "how to instructions"
|
// Set "how to instructions"
|
||||||
val howToExample: TextView = findViewById(R.id.detail_how_to_example)
|
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
|
val subscription = repository.getSubscription(subscriptionId) ?: return@launch
|
||||||
subscriptionInstant = subscription.instant
|
subscriptionInstant = subscription.instant
|
||||||
subscriptionMutedUntil = subscription.mutedUntil
|
subscriptionMutedUntil = subscription.mutedUntil
|
||||||
|
subscriptionDisplayName = displayName(subscription)
|
||||||
|
|
||||||
showHideInstantMenuItems(subscriptionInstant)
|
showHideInstantMenuItems(subscriptionInstant)
|
||||||
showHideMutedUntilMenuItems(subscriptionMutedUntil)
|
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() {
|
private fun onClearClick() {
|
||||||
Log.d(TAG, "Clearing all notifications for ${topicShortUrl(subscriptionBaseUrl, subscriptionTopic)}")
|
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_ID, subscriptionId)
|
||||||
intent.putExtra(EXTRA_SUBSCRIPTION_BASE_URL, subscriptionBaseUrl)
|
intent.putExtra(EXTRA_SUBSCRIPTION_BASE_URL, subscriptionBaseUrl)
|
||||||
intent.putExtra(EXTRA_SUBSCRIPTION_TOPIC, subscriptionTopic)
|
intent.putExtra(EXTRA_SUBSCRIPTION_TOPIC, subscriptionTopic)
|
||||||
|
intent.putExtra(EXTRA_SUBSCRIPTION_DISPLAY_NAME, subscriptionDisplayName)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,5 +761,6 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra
|
||||||
const val EXTRA_SUBSCRIPTION_ID = "subscriptionId"
|
const val EXTRA_SUBSCRIPTION_ID = "subscriptionId"
|
||||||
const val EXTRA_SUBSCRIPTION_BASE_URL = "baseUrl"
|
const val EXTRA_SUBSCRIPTION_BASE_URL = "baseUrl"
|
||||||
const val EXTRA_SUBSCRIPTION_TOPIC = "topic"
|
const val EXTRA_SUBSCRIPTION_TOPIC = "topic"
|
||||||
|
const val EXTRA_SUBSCRIPTION_DISPLAY_NAME = "displayName"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,9 +55,8 @@ class DetailSettingsActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Title
|
// Title
|
||||||
val baseUrl = intent.getStringExtra(DetailActivity.EXTRA_SUBSCRIPTION_BASE_URL) ?: return
|
val displayName = intent.getStringExtra(DetailActivity.EXTRA_SUBSCRIPTION_DISPLAY_NAME) ?: return
|
||||||
val topic = intent.getStringExtra(DetailActivity.EXTRA_SUBSCRIPTION_TOPIC) ?: return
|
title = displayName
|
||||||
title = topicShortUrl(baseUrl, topic)
|
|
||||||
|
|
||||||
// Show 'Back' button
|
// Show 'Back' button
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
@ -108,6 +107,7 @@ class DetailSettingsActivity : AppCompatActivity() {
|
||||||
loadAutoDeletePref()
|
loadAutoDeletePref()
|
||||||
loadIconSetPref()
|
loadIconSetPref()
|
||||||
loadIconRemovePref()
|
loadIconRemovePref()
|
||||||
|
loadDisplayNamePref()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadInstantPref() {
|
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<EditTextPreference> { _ ->
|
||||||
|
getString(R.string.detail_settings_appearance_display_name_summary, displayName(subscription), topicShortUrl(subscription.baseUrl, subscription.topic))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun createIconPickLauncher(): ActivityResultLauncher<String> {
|
private fun createIconPickLauncher(): ActivityResultLauncher<String> {
|
||||||
return registerForActivityResult(ActivityResultContracts.GetContent()) { inputUri ->
|
return registerForActivityResult(ActivityResultContracts.GetContent()) { inputUri ->
|
||||||
if (inputUri == null) {
|
if (inputUri == null) {
|
||||||
|
|
|
@ -438,6 +438,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
|
||||||
icon = null,
|
icon = null,
|
||||||
upAppId = null,
|
upAppId = null,
|
||||||
upConnectorToken = null,
|
upConnectorToken = null,
|
||||||
|
displayName = null,
|
||||||
totalCount = 0,
|
totalCount = 0,
|
||||||
newCount = 0,
|
newCount = 0,
|
||||||
lastActive = Date().time/1000
|
lastActive = Date().time/1000
|
||||||
|
@ -509,7 +510,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
val topic = topicShortUrl(subscription.baseUrl, subscription.topic)
|
val topic = displayName(subscription)
|
||||||
if (errorMessage == "") errorMessage = "$topic: ${e.message}"
|
if (errorMessage == "") errorMessage = "$topic: ${e.message}"
|
||||||
errors++
|
errors++
|
||||||
}
|
}
|
||||||
|
@ -536,6 +537,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
|
||||||
intent.putExtra(EXTRA_SUBSCRIPTION_ID, subscription.id)
|
intent.putExtra(EXTRA_SUBSCRIPTION_ID, subscription.id)
|
||||||
intent.putExtra(EXTRA_SUBSCRIPTION_BASE_URL, subscription.baseUrl)
|
intent.putExtra(EXTRA_SUBSCRIPTION_BASE_URL, subscription.baseUrl)
|
||||||
intent.putExtra(EXTRA_SUBSCRIPTION_TOPIC, subscription.topic)
|
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_INSTANT, subscription.instant)
|
||||||
intent.putExtra(EXTRA_SUBSCRIPTION_MUTED_UNTIL, subscription.mutedUntil)
|
intent.putExtra(EXTRA_SUBSCRIPTION_MUTED_UNTIL, subscription.mutedUntil)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
|
@ -662,6 +664,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
|
||||||
const val EXTRA_SUBSCRIPTION_ID = "subscriptionId"
|
const val EXTRA_SUBSCRIPTION_ID = "subscriptionId"
|
||||||
const val EXTRA_SUBSCRIPTION_BASE_URL = "subscriptionBaseUrl"
|
const val EXTRA_SUBSCRIPTION_BASE_URL = "subscriptionBaseUrl"
|
||||||
const val EXTRA_SUBSCRIPTION_TOPIC = "subscriptionTopic"
|
const val EXTRA_SUBSCRIPTION_TOPIC = "subscriptionTopic"
|
||||||
|
const val EXTRA_SUBSCRIPTION_DISPLAY_NAME = "subscriptionDisplayName"
|
||||||
const val EXTRA_SUBSCRIPTION_INSTANT = "subscriptionInstant"
|
const val EXTRA_SUBSCRIPTION_INSTANT = "subscriptionInstant"
|
||||||
const val EXTRA_SUBSCRIPTION_MUTED_UNTIL = "subscriptionMutedUntil"
|
const val EXTRA_SUBSCRIPTION_MUTED_UNTIL = "subscriptionMutedUntil"
|
||||||
const val ANIMATION_DURATION = 80L
|
const val ANIMATION_DURATION = 80L
|
||||||
|
|
|
@ -20,7 +20,7 @@ import io.heckel.ntfy.db.Subscription
|
||||||
import io.heckel.ntfy.msg.NotificationService
|
import io.heckel.ntfy.msg.NotificationService
|
||||||
import io.heckel.ntfy.util.Log
|
import io.heckel.ntfy.util.Log
|
||||||
import io.heckel.ntfy.util.readBitmapFromUriOrNull
|
import io.heckel.ntfy.util.readBitmapFromUriOrNull
|
||||||
import io.heckel.ntfy.util.topicShortUrl
|
import io.heckel.ntfy.util.displayName
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ class MainAdapter(private val repository: Repository, private val onClick: (Subs
|
||||||
if (subscription.icon != null) {
|
if (subscription.icon != null) {
|
||||||
imageView.setImageBitmap(subscription.icon.readBitmapFromUriOrNull(context))
|
imageView.setImageBitmap(subscription.icon.readBitmapFromUriOrNull(context))
|
||||||
}
|
}
|
||||||
nameView.text = topicShortUrl(subscription.baseUrl, subscription.topic)
|
nameView.text = displayName(subscription)
|
||||||
statusView.text = statusMessage
|
statusView.text = statusMessage
|
||||||
dateView.text = dateText
|
dateView.text = dateText
|
||||||
dateView.visibility = if (isUnifiedPush) View.GONE else View.VISIBLE
|
dateView.visibility = if (isUnifiedPush) View.GONE else View.VISIBLE
|
||||||
|
|
|
@ -79,6 +79,7 @@ class BroadcastReceiver : android.content.BroadcastReceiver() {
|
||||||
icon = null,
|
icon = null,
|
||||||
upAppId = appId,
|
upAppId = appId,
|
||||||
upConnectorToken = connectorToken,
|
upConnectorToken = connectorToken,
|
||||||
|
displayName = null,
|
||||||
totalCount = 0,
|
totalCount = 0,
|
||||||
newCount = 0,
|
newCount = 0,
|
||||||
lastActive = Date().time/1000
|
lastActive = Date().time/1000
|
||||||
|
|
|
@ -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 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 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
|
fun shortUrl(url: String) = url
|
||||||
.replace("http://", "")
|
.replace("http://", "")
|
||||||
.replace("https://", "")
|
.replace("https://", "")
|
||||||
|
@ -176,7 +180,7 @@ fun formatTitle(subscription: Subscription, notification: Notification): String
|
||||||
return if (notification.title != "") {
|
return if (notification.title != "") {
|
||||||
formatTitle(notification)
|
formatTitle(notification)
|
||||||
} else {
|
} else {
|
||||||
topicShortUrl(subscription.baseUrl, subscription.topic)
|
displayName(subscription)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -353,6 +353,8 @@
|
||||||
<string name="detail_settings_appearance_icon_remove_title">Subscription icon (tap to remove)</string>
|
<string name="detail_settings_appearance_icon_remove_title">Subscription icon (tap to remove)</string>
|
||||||
<string name="detail_settings_appearance_icon_remove_summary">Icon displayed in notifications for this topic</string>
|
<string name="detail_settings_appearance_icon_remove_summary">Icon displayed in notifications for this topic</string>
|
||||||
<string name="detail_settings_appearance_icon_error_saving">Unable to save icon: %1$s</string>
|
<string name="detail_settings_appearance_icon_error_saving">Unable to save icon: %1$s</string>
|
||||||
|
<string name="detail_settings_appearance_display_name_title">Display name</string>
|
||||||
|
<string name="detail_settings_appearance_display_name_summary">Set a custom display name for this subscription. Leave empty for default\nCurrent: %1$s\nDefault: %2$s</string>
|
||||||
<string name="detail_settings_global_setting_title">Use global setting</string>
|
<string name="detail_settings_global_setting_title">Use global setting</string>
|
||||||
<string name="detail_settings_global_setting_suffix">using global setting</string>
|
<string name="detail_settings_global_setting_suffix">using global setting</string>
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
<string name="detail_settings_notifications_auto_delete_key" translatable="false">SubscriptionAutoDelete</string>
|
<string name="detail_settings_notifications_auto_delete_key" translatable="false">SubscriptionAutoDelete</string>
|
||||||
<string name="detail_settings_appearance_icon_set_key" translatable="false">SubscriptionIconSet</string>
|
<string name="detail_settings_appearance_icon_set_key" translatable="false">SubscriptionIconSet</string>
|
||||||
<string name="detail_settings_appearance_icon_remove_key" translatable="false">SubscriptionIconRemove</string>
|
<string name="detail_settings_appearance_icon_remove_key" translatable="false">SubscriptionIconRemove</string>
|
||||||
|
<string name="detail_settings_appearance_display_name_key" translatable="false">SubscriptionDisplayName</string>
|
||||||
|
|
||||||
<!-- Main settings -->
|
<!-- Main settings -->
|
||||||
<string-array name="settings_notifications_muted_until_entries">
|
<string-array name="settings_notifications_muted_until_entries">
|
||||||
|
|
|
@ -38,5 +38,10 @@
|
||||||
app:title="@string/detail_settings_appearance_icon_remove_title"
|
app:title="@string/detail_settings_appearance_icon_remove_title"
|
||||||
app:summary="@string/detail_settings_appearance_icon_remove_summary"
|
app:summary="@string/detail_settings_appearance_icon_remove_summary"
|
||||||
app:isPreferenceVisible="false"/>
|
app:isPreferenceVisible="false"/>
|
||||||
|
<EditTextPreference
|
||||||
|
app:key="@string/detail_settings_appearance_display_name_key"
|
||||||
|
app:title="@string/detail_settings_appearance_display_name_title"
|
||||||
|
app:summary="@string/detail_settings_appearance_display_name_summary"
|
||||||
|
app:isPreferenceVisible="false"/>
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|
Loading…
Reference in a new issue