WIP:Image preview in detail view

This commit is contained in:
Philipp Heckel 2022-01-08 22:17:41 -05:00
parent dced0a2e06
commit 95e101eb65
4 changed files with 37 additions and 10 deletions

View file

@ -14,10 +14,7 @@ import io.heckel.ntfy.data.Notification
import io.heckel.ntfy.data.Subscription import io.heckel.ntfy.data.Subscription
import io.heckel.ntfy.ui.DetailActivity import io.heckel.ntfy.ui.DetailActivity
import io.heckel.ntfy.ui.MainActivity import io.heckel.ntfy.ui.MainActivity
import io.heckel.ntfy.util.formatBytes import io.heckel.ntfy.util.*
import io.heckel.ntfy.util.formatDateShort
import io.heckel.ntfy.util.formatMessage
import io.heckel.ntfy.util.formatTitle
class NotificationService(val context: Context) { class NotificationService(val context: Context) {
private val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager private val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
@ -73,7 +70,7 @@ class NotificationService(val context: Context) {
if (att.name != null) infos.add(att.name) if (att.name != null) infos.add(att.name)
if (att.size != null) infos.add(formatBytes(att.size)) if (att.size != null) infos.add(formatBytes(att.size))
//if (att.expires != null && att.expires != 0L) infos.add(formatDateShort(att.expires)) //if (att.expires != null && att.expires != 0L) infos.add(formatDateShort(att.expires))
if (progress >= 0) infos.add("${progress}%") if (progress in 0..99) infos.add("${progress}%")
if (infos.size == 0) return message if (infos.size == 0) return message
if (progress < 100) return "Downloading ${infos.joinToString(", ")}\n${message}" if (progress < 100) return "Downloading ${infos.joinToString(", ")}\n${message}"
return "${message}\nFile: ${infos.joinToString(", ")}" return "${message}\nFile: ${infos.joinToString(", ")}"
@ -90,8 +87,8 @@ class NotificationService(val context: Context) {
private fun setStyle(builder: NotificationCompat.Builder, notification: Notification, message: String) { private fun setStyle(builder: NotificationCompat.Builder, notification: Notification, message: String) {
val contentUri = notification.attachment?.contentUri val contentUri = notification.attachment?.contentUri
val isImage = listOf("image/jpeg", "image/png").contains(notification.attachment?.type) val isSupportedImage = supportedImage(notification.attachment?.type)
if (contentUri != null && isImage) { if (contentUri != null && isSupportedImage) {
try { try {
val resolver = context.applicationContext.contentResolver val resolver = context.applicationContext.contentResolver
val bitmapStream = resolver.openInputStream(Uri.parse(contentUri)) val bitmapStream = resolver.openInputStream(Uri.parse(contentUri))

View file

@ -1,11 +1,14 @@
package io.heckel.ntfy.ui package io.heckel.ntfy.ui
import android.graphics.BitmapFactory
import android.net.Uri
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
@ -49,6 +52,7 @@ class DetailAdapter(private val onClick: (Notification) -> Unit, private val onL
private val messageView: TextView = itemView.findViewById(R.id.detail_item_message_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 newImageView: View = itemView.findViewById(R.id.detail_item_new_dot)
private val tagsView: TextView = itemView.findViewById(R.id.detail_item_tags) private val tagsView: TextView = itemView.findViewById(R.id.detail_item_tags)
private val imageView: ImageView = itemView.findViewById(R.id.detail_item_image)
fun bind(notification: Notification) { fun bind(notification: Notification) {
this.notification = notification this.notification = notification
@ -97,6 +101,21 @@ class DetailAdapter(private val onClick: (Notification) -> Unit, private val onL
priorityImageView.setImageDrawable(ContextCompat.getDrawable(ctx, R.drawable.ic_priority_5_24dp)) priorityImageView.setImageDrawable(ContextCompat.getDrawable(ctx, R.drawable.ic_priority_5_24dp))
} }
} }
// 📄
val contentUri = notification.attachment?.contentUri
if (contentUri != null && supportedImage(notification.attachment.type)) {
try {
val resolver = itemView.context.applicationContext.contentResolver
val bitmapStream = resolver.openInputStream(Uri.parse(contentUri))
val bitmap = BitmapFactory.decodeStream(bitmapStream)
imageView.setImageBitmap(bitmap)
imageView.visibility = View.VISIBLE
} catch (_: Exception) {
imageView.visibility = View.GONE
}
} else {
imageView.visibility = View.GONE
}
} }
} }

View file

@ -144,3 +144,7 @@ fun formatBytes(bytes: Long): String {
value *= java.lang.Long.signum(bytes).toLong() value *= java.lang.Long.signum(bytes).toLong()
return java.lang.String.format("%.1f %ciB", value / 1024.0, ci.current()) return java.lang.String.format("%.1f %ciB", value / 1024.0, ci.current())
} }
fun supportedImage(mimeType: String?): Boolean {
return listOf("image/jpeg", "image/png").contains(mimeType)
}

View file

@ -47,11 +47,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/detail_item_tags" android:id="@+id/detail_item_tags"
android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="10dp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="10dp" app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="10dp"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="10dp" app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="10dp"
app:layout_constraintTop_toBottomOf="@id/detail_item_message_text"/> app:layout_constraintTop_toBottomOf="@id/detail_item_message_text"
app:layout_constraintBottom_toTopOf="@id/detail_item_image"/>
<TextView <TextView
android:text="This is an optional title. It can also be a little longer but not too long." android:text="This is an optional title. It can also be a little longer but not too long."
android:layout_width="0dp" android:layout_width="0dp"
@ -71,5 +70,13 @@
app:layout_constraintStart_toEndOf="@+id/detail_item_date_text" app:layout_constraintStart_toEndOf="@+id/detail_item_date_text"
app:layout_constraintTop_toTopOf="@+id/detail_item_date_text" app:layout_constraintTop_toTopOf="@+id/detail_item_date_text"
app:layout_constraintBottom_toBottomOf="@+id/detail_item_date_text" android:layout_marginStart="5dp"/> app:layout_constraintBottom_toBottomOf="@+id/detail_item_date_text" android:layout_marginStart="5dp"/>
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content" app:srcCompat="@drawable/ic_cancel_gray_24dp"
android:id="@+id/detail_item_image" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/detail_item_tags"
android:layout_marginStart="10dp" android:layout_marginEnd="10dp"
app:layout_constraintBottom_toBottomOf="parent" android:scaleType="centerCrop"
android:adjustViewBounds="true" android:maxHeight="150dp" android:layout_marginTop="5dp"/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>