From 1148e08b961217a3003aefc7b4bfdd4b95d4d1cb Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 28 Nov 2021 19:28:58 -0500 Subject: [PATCH] List unmatched tags as strings --- app/build.gradle | 4 +- .../main/java/io/heckel/ntfy/data/Database.kt | 2 +- .../java/io/heckel/ntfy/ui/DetailActivity.kt | 7 ++- .../java/io/heckel/ntfy/ui/DetailAdapter.kt | 15 ++++-- app/src/main/java/io/heckel/ntfy/util/Util.kt | 34 +++++++++----- .../main/res/layout/fragment_detail_item.xml | 12 ++++- app/src/main/res/values/strings.xml | 1 + .../heckel/ntfy/firebase/FirebaseService.kt | 4 +- assets/priority_5_24dp.svg | 20 +++++--- assets/priority_5_alt2_24dp.svg | 47 ------------------- assets/priority_5_alt3_24dp.svg | 39 +++++++++++++++ 11 files changed, 108 insertions(+), 77 deletions(-) delete mode 100644 assets/priority_5_alt2_24dp.svg create mode 100644 assets/priority_5_alt3_24dp.svg diff --git a/app/build.gradle b/app/build.gradle index bde4f874..5d037a2f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,8 +12,8 @@ android { minSdkVersion 21 targetSdkVersion 30 - versionCode 8 - versionName "1.2.1" + versionCode 9 + versionName "1.2.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/io/heckel/ntfy/data/Database.kt b/app/src/main/java/io/heckel/ntfy/data/Database.kt index 185f6ae8..7457cfe4 100644 --- a/app/src/main/java/io/heckel/ntfy/data/Database.kt +++ b/app/src/main/java/io/heckel/ntfy/data/Database.kt @@ -96,7 +96,7 @@ abstract class Database : RoomDatabase() { private val MIGRATION_3_4 = object : Migration(3, 4) { override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("CREATE TABLE Notification_New (id TEXT NOT NULL, subscriptionId INTEGER NOT NULL, timestamp INTEGER NOT NULL, title TEXT NOT NULL, message TEXT NOT NULL, notificationId INTEGER NOT NULL, priority INTEGER NOT NULL, tags TEXT NOT NULL, deleted INTEGER NOT NULL, PRIMARY KEY(id, subscriptionId))") + db.execSQL("CREATE TABLE Notification_New (id TEXT NOT NULL, subscriptionId INTEGER NOT NULL, timestamp INTEGER NOT NULL, title TEXT NOT NULL, message TEXT NOT NULL, notificationId INTEGER NOT NULL, priority INTEGER NOT NULL DEFAULT(3), tags TEXT NOT NULL, deleted INTEGER NOT NULL, PRIMARY KEY(id, subscriptionId))") db.execSQL("INSERT INTO Notification_New SELECT id, subscriptionId, timestamp, '', message, notificationId, 3, '', deleted FROM Notification") db.execSQL("DROP TABLE Notification") db.execSQL("ALTER TABLE Notification_New RENAME TO Notification") 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 53dffddc..2ae156de 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt @@ -326,9 +326,12 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra lifecycleScope.launch(Dispatchers.IO) { try { - val possibleTags = listOf("warning", "skull", "success", "triangular_flag_on_post", "de", "dog", "rotating_light", "cat", "bike") + val possibleTags = listOf( + "warning", "skull", "success", "triangular_flag_on_post", "de", "dog", "rotating_light", "cat", "bike", // Emojis + "backup", "rsync", "de-server1", "this-is-a-tag" + ) val priority = Random.nextInt(1, 6) - val tags = possibleTags.shuffled().take(Random.nextInt(0, 3)) + val tags = possibleTags.shuffled().take(Random.nextInt(0, 4)) val title = if (Random.nextBoolean()) getString(R.string.detail_test_title) else "" val message = getString(R.string.detail_test_message, priority) api.publish(subscriptionBaseUrl, subscriptionTopic, message, title, priority, tags) diff --git a/app/src/main/java/io/heckel/ntfy/ui/DetailAdapter.kt b/app/src/main/java/io/heckel/ntfy/ui/DetailAdapter.kt index b39dd344..662e0227 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailAdapter.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailAdapter.kt @@ -1,5 +1,6 @@ package io.heckel.ntfy.ui +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -11,8 +12,7 @@ import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import io.heckel.ntfy.R import io.heckel.ntfy.data.Notification -import io.heckel.ntfy.util.formatMessage -import io.heckel.ntfy.util.formatTitle +import io.heckel.ntfy.util.* import java.util.* class DetailAdapter(private val onClick: (Notification) -> Unit, private val onLongClick: (Notification) -> Unit) : @@ -48,10 +48,14 @@ class DetailAdapter(private val onClick: (Notification) -> Unit, private val onL private val titleView: TextView = itemView.findViewById(R.id.detail_item_title_text) private val messageView: TextView = itemView.findViewById(R.id.detail_item_message_text) private val newImageView: View = itemView.findViewById(R.id.detail_item_new_dot) + private val tagsView: TextView = itemView.findViewById(R.id.detail_item_tags) fun bind(notification: Notification) { this.notification = notification + val ctx = itemView.context + val unmatchedTags = unmatchedTags(splitTags(notification.tags)) + dateView.text = Date(notification.timestamp * 1000).toString() messageView.text = formatMessage(notification) newImageView.visibility = if (notification.notificationId == 0) View.GONE else View.VISIBLE @@ -63,10 +67,15 @@ class DetailAdapter(private val onClick: (Notification) -> Unit, private val onL } else { titleView.visibility = View.GONE } + if (unmatchedTags.isNotEmpty()) { + tagsView.visibility = View.VISIBLE + tagsView.text = ctx.getString(R.string.detail_item_tags, unmatchedTags.joinToString(", ")) + } else { + tagsView.visibility = View.GONE + } if (selected.contains(notification.id)) { itemView.setBackgroundResource(R.color.primarySelectedRowColor); } - val ctx = itemView.context when (notification.priority) { 1 -> { priorityImageView.visibility = 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 3b72167e..072f5dae 100644 --- a/app/src/main/java/io/heckel/ntfy/util/Util.kt +++ b/app/src/main/java/io/heckel/ntfy/util/Util.kt @@ -31,21 +31,31 @@ fun joinTags(tags: List?): String { return tags?.joinToString(",") ?: "" } -fun toTags(tags: String?): String { - return tags ?: "" +fun splitTags(tags: String?): List { + return if (tags == null || tags == "") { + emptyList() + } else { + tags.split(",") + } } -fun emojify(tags: List): List { - return tags.mapNotNull { - when (it.toLowerCase()) { - "warn", "warning" -> "\u26A0\uFE0F" - "success" -> "\u2714\uFE0F" - "failure" -> "\u274C" - else -> EmojiManager.getForAlias(it)?.unicode - } +fun toEmojis(tags: List): List { + return tags.mapNotNull { tag -> toEmoji(tag) } +} + +fun toEmoji(tag: String): String? { + return when (tag.toLowerCase()) { + "warn", "warning" -> "\u26A0\uFE0F" + "success" -> "\u2714\uFE0F" + "failure" -> "\u274C" + else -> EmojiManager.getForAlias(tag)?.unicode } } +fun unmatchedTags(tags: List): List { + return tags.filter { tag -> toEmoji(tag) == null } +} + /** * Prepend tags/emojis to message, but only if there is a non-empty title. * Otherwise the tags will be prepended to the title. @@ -54,7 +64,7 @@ fun formatMessage(notification: Notification): String { return if (notification.title != "") { notification.message } else { - val emojis = emojify(notification.tags.split(",")) + val emojis = toEmojis(splitTags(notification.tags)) if (emojis.isEmpty()) { notification.message } else { @@ -76,7 +86,7 @@ fun formatTitle(subscription: Subscription, notification: Notification): String } fun formatTitle(notification: Notification): String { - val emojis = emojify(notification.tags.split(",")) + val emojis = toEmojis(splitTags(notification.tags)) return if (emojis.isEmpty()) { notification.title } else { diff --git a/app/src/main/res/layout/fragment_detail_item.xml b/app/src/main/res/layout/fragment_detail_item.xml index 591540c7..1b44351e 100644 --- a/app/src/main/res/layout/fragment_detail_item.xml +++ b/app/src/main/res/layout/fragment_detail_item.xml @@ -37,10 +37,20 @@ android:textColor="@color/primaryTextColor" android:textAppearance="@style/TextAppearance.AppCompat.Medium" app:layout_constraintTop_toBottomOf="@id/detail_item_title_text" + app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="10dp" + app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="10dp" + app:layout_constraintBottom_toTopOf="@+id/detail_item_tags"/> + + app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="10dp" + app:layout_constraintTop_toBottomOf="@id/detail_item_message_text"/> Instant delivery enabled Instant delivery disabled Instant delivery is enabled + Tags: %1$s Notifications enabled diff --git a/app/src/play/java/io/heckel/ntfy/firebase/FirebaseService.kt b/app/src/play/java/io/heckel/ntfy/firebase/FirebaseService.kt index 66876aa1..815741d7 100644 --- a/app/src/play/java/io/heckel/ntfy/firebase/FirebaseService.kt +++ b/app/src/play/java/io/heckel/ntfy/firebase/FirebaseService.kt @@ -7,9 +7,7 @@ import io.heckel.ntfy.R import io.heckel.ntfy.app.Application import io.heckel.ntfy.data.Notification import io.heckel.ntfy.msg.NotificationService -import io.heckel.ntfy.util.joinTags import io.heckel.ntfy.util.toPriority -import io.heckel.ntfy.util.toTags import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch @@ -55,7 +53,7 @@ class FirebaseService : FirebaseMessagingService() { message = message, notificationId = Random.nextInt(), priority = toPriority(priority), - tags = toTags(tags), + tags = tags ?: "", deleted = false ) val shouldNotify = repository.addNotification(notification) diff --git a/assets/priority_5_24dp.svg b/assets/priority_5_24dp.svg index 71bc0e22..2e2c4447 100644 --- a/assets/priority_5_24dp.svg +++ b/assets/priority_5_24dp.svg @@ -23,9 +23,9 @@ inkscape:pageopacity="0" inkscape:pagecheckerboard="0" showgrid="false" - inkscape:zoom="26.806921" - inkscape:cx="18.894374" - inkscape:cy="14.026229" + inkscape:zoom="20.517358" + inkscape:cx="22.834323" + inkscape:cy="15.742767" inkscape:window-width="1863" inkscape:window-height="1025" inkscape:window-x="57" @@ -33,7 +33,15 @@ inkscape:window-maximized="1" inkscape:current-layer="svg1428" /> + style="color:#000000;fill:#aa0000;fill-opacity:1;stroke-width:0.0919748;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none" + d="M 12.116784,3.40514 A 1.2747098,1.2747098 0 0 0 11.455179,3.5903463 L 4.8085864,7.6275238 A 1.2745823,1.2745823 0 0 0 4.3810494,9.3786313 1.2745823,1.2745823 0 0 0 6.1319775,9.8063489 L 12.116784,6.1710217 18.101593,9.8063489 A 1.2745823,1.2745823 0 0 0 19.85252,9.3786313 1.2745823,1.2745823 0 0 0 19.424984,7.6275238 L 12.778569,3.5903463 A 1.2747098,1.2747098 0 0 0 12.116784,3.40514 Z" + id="rect3554" /> + + diff --git a/assets/priority_5_alt2_24dp.svg b/assets/priority_5_alt2_24dp.svg deleted file mode 100644 index 2e2c4447..00000000 --- a/assets/priority_5_alt2_24dp.svg +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - diff --git a/assets/priority_5_alt3_24dp.svg b/assets/priority_5_alt3_24dp.svg new file mode 100644 index 00000000..71bc0e22 --- /dev/null +++ b/assets/priority_5_alt3_24dp.svg @@ -0,0 +1,39 @@ + + + + + +