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 bde4f87..5d037a2 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 185f6ae..7457cfe 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 53dffdd..2ae156d 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 b39dd34..662e022 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 3b72167..072f5da 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 591540c..1b44351 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 66876aa..815741d 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 71bc0e2..2e2c444 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 2e2c444..0000000 --- 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 0000000..71bc0e2 --- /dev/null +++ b/assets/priority_5_alt3_24dp.svg @@ -0,0 +1,39 @@ + + + + + +