Loading app/src/main/java/io/heckel/ntfy/db/Database.kt +19 −12 Original line number Diff line number Diff line Loading @@ -73,20 +73,33 @@ data class Attachment( @ColumnInfo(name = "progress") val progress: Int, // Progress during download, -1 if not downloaded ) { constructor(name: String, type: String?, size: Long?, expires: Long?, url: String) : this(name, type, size, expires, url, null, PROGRESS_NONE) this(name, type, size, expires, url, null, ATTACHMENT_PROGRESS_NONE) } const val ATTACHMENT_PROGRESS_NONE = -1 const val ATTACHMENT_PROGRESS_INDETERMINATE = -2 const val ATTACHMENT_PROGRESS_FAILED = -3 const val ATTACHMENT_PROGRESS_DELETED = -4 const val ATTACHMENT_PROGRESS_DONE = 100 @Entity data class Action( @ColumnInfo(name = "id") val id: String, // Synthetic ID to identify result, and easily pass via Broadcast and WorkManager @ColumnInfo(name = "action") val action: String, @ColumnInfo(name = "action") val action: String, // "view", "http" or "broadcast" @ColumnInfo(name = "label") val label: String, @ColumnInfo(name = "url") val url: String?, // used in "view" and "http" @ColumnInfo(name = "method") val method: String?, // used in "http" @ColumnInfo(name = "headers") val headers: Map<String,String>?, // used in "http" @ColumnInfo(name = "body") val body: String?, // used in "http" @ColumnInfo(name = "url") val url: String?, // used in "view" and "http" actions @ColumnInfo(name = "method") val method: String?, // used in "http" action @ColumnInfo(name = "headers") val headers: Map<String,String>?, // used in "http" action @ColumnInfo(name = "body") val body: String?, // used in "http" action @ColumnInfo(name = "extras") val extras: Map<String,String>?, // used in "broadcast" action @ColumnInfo(name = "progress") val progress: Int?, // used to indicate progress in popup @ColumnInfo(name = "error") val error: String?, // used to indicate errors in popup ) const val ACTION_PROGRESS_ONGOING = 1 const val ACTION_PROGRESS_SUCCESS = 2 const val ACTION_PROGRESS_FAILED = 3 class Converters { private val gson = Gson() Loading @@ -102,12 +115,6 @@ class Converters { } } const val PROGRESS_NONE = -1 const val PROGRESS_INDETERMINATE = -2 const val PROGRESS_FAILED = -3 const val PROGRESS_DELETED = -4 const val PROGRESS_DONE = 100 @Entity data class User( @PrimaryKey @ColumnInfo(name = "baseUrl") val baseUrl: String, Loading app/src/main/java/io/heckel/ntfy/msg/BroadcastService.kt +14 −3 Original line number Diff line number Diff line Loading @@ -2,8 +2,8 @@ package io.heckel.ntfy.msg import android.content.Context import android.content.Intent import android.util.Base64 import io.heckel.ntfy.R import io.heckel.ntfy.db.Action import io.heckel.ntfy.db.Notification import io.heckel.ntfy.db.Repository import io.heckel.ntfy.db.Subscription Loading @@ -17,7 +17,7 @@ import kotlinx.coroutines.launch * in order to facilitate tasks app integrations. */ class BroadcastService(private val ctx: Context) { fun send(subscription: Subscription, notification: Notification, muted: Boolean) { fun sendMessage(subscription: Subscription, notification: Notification, muted: Boolean) { val intent = Intent() intent.action = MESSAGE_RECEIVED_ACTION intent.putExtra("id", notification.id) Loading @@ -34,7 +34,17 @@ class BroadcastService(private val ctx: Context) { intent.putExtra("muted", muted) intent.putExtra("muted_str", muted.toString()) Log.d(TAG, "Sending intent broadcast: $intent") Log.d(TAG, "Sending message intent broadcast: $intent") ctx.sendBroadcast(intent) } fun sendUserAction(action: Action) { val intent = Intent() intent.action = USER_ACTION_ACTION action.extras?.forEach { (key, value) -> intent.putExtra(key, value) } Log.d(TAG, "Sending user action intent broadcast: $intent") ctx.sendBroadcast(intent) } Loading Loading @@ -109,5 +119,6 @@ class BroadcastService(private val ctx: Context) { // These constants cannot be changed without breaking the contract; also see manifest private const val MESSAGE_RECEIVED_ACTION = "io.heckel.ntfy.MESSAGE_RECEIVED" private const val MESSAGE_SEND_ACTION = "io.heckel.ntfy.SEND_MESSAGE" private const val USER_ACTION_ACTION = "io.heckel.ntfy.USER_ACTION" } } app/src/main/java/io/heckel/ntfy/msg/DownloadWorker.kt +4 −4 Original line number Diff line number Diff line Loading @@ -91,13 +91,13 @@ class DownloadWorker(private val context: Context, params: WorkerParameters) : W while (bytes >= 0) { if (System.currentTimeMillis() - lastProgress > NOTIFICATION_UPDATE_INTERVAL_MILLIS) { if (isStopped) { // Canceled by user save(attachment.copy(progress = PROGRESS_NONE)) save(attachment.copy(progress = ATTACHMENT_PROGRESS_NONE)) return // File will be deleted in onStopped() } val progress = if (attachment.size != null && attachment.size!! > 0) { (bytesCopied.toFloat()/attachment.size!!.toFloat()*100).toInt() } else { PROGRESS_INDETERMINATE ATTACHMENT_PROGRESS_INDETERMINATE } save(attachment.copy(progress = progress)) lastProgress = System.currentTimeMillis() Loading @@ -114,7 +114,7 @@ class DownloadWorker(private val context: Context, params: WorkerParameters) : W save(attachment.copy( size = bytesCopied, contentUri = uri.toString(), progress = PROGRESS_DONE progress = ATTACHMENT_PROGRESS_DONE )) } } catch (e: Exception) { Loading Loading @@ -155,7 +155,7 @@ class DownloadWorker(private val context: Context, params: WorkerParameters) : W private fun failed(e: Exception) { Log.w(TAG, "Attachment download failed", e) save(attachment.copy(progress = PROGRESS_FAILED)) save(attachment.copy(progress = ATTACHMENT_PROGRESS_FAILED)) maybeDeleteFile() } Loading app/src/main/java/io/heckel/ntfy/msg/Message.kt +3 −2 Original line number Diff line number Diff line Loading @@ -34,11 +34,12 @@ data class MessageAttachment( data class MessageAction( val id: String, val action: String, val label: String, val label: String, // "view", "broadcast" or "http" val url: String?, // used in "view" and "http" val method: String?, // used in "http" val method: String?, // used in "http", default is POST (!) val headers: Map<String,String>?, // used in "http" val body: String?, // used in "http" val extras: Map<String,String>?, // used in "broadcast" ) const val MESSAGE_ENCODING_BASE64 = "base64" app/src/main/java/io/heckel/ntfy/msg/NotificationDispatcher.kt +1 −2 Original line number Diff line number Diff line package io.heckel.ntfy.msg import android.content.Context import android.util.Base64 import io.heckel.ntfy.db.Notification import io.heckel.ntfy.db.Repository import io.heckel.ntfy.db.Subscription Loading Loading @@ -35,7 +34,7 @@ class NotificationDispatcher(val context: Context, val repository: Repository) { notifier.display(subscription, notification) } if (broadcast) { broadcaster.send(subscription, notification, muted) broadcaster.sendMessage(subscription, notification, muted) } if (distribute) { safeLet(subscription.upAppId, subscription.upConnectorToken) { appId, connectorToken -> Loading Loading
app/src/main/java/io/heckel/ntfy/db/Database.kt +19 −12 Original line number Diff line number Diff line Loading @@ -73,20 +73,33 @@ data class Attachment( @ColumnInfo(name = "progress") val progress: Int, // Progress during download, -1 if not downloaded ) { constructor(name: String, type: String?, size: Long?, expires: Long?, url: String) : this(name, type, size, expires, url, null, PROGRESS_NONE) this(name, type, size, expires, url, null, ATTACHMENT_PROGRESS_NONE) } const val ATTACHMENT_PROGRESS_NONE = -1 const val ATTACHMENT_PROGRESS_INDETERMINATE = -2 const val ATTACHMENT_PROGRESS_FAILED = -3 const val ATTACHMENT_PROGRESS_DELETED = -4 const val ATTACHMENT_PROGRESS_DONE = 100 @Entity data class Action( @ColumnInfo(name = "id") val id: String, // Synthetic ID to identify result, and easily pass via Broadcast and WorkManager @ColumnInfo(name = "action") val action: String, @ColumnInfo(name = "action") val action: String, // "view", "http" or "broadcast" @ColumnInfo(name = "label") val label: String, @ColumnInfo(name = "url") val url: String?, // used in "view" and "http" @ColumnInfo(name = "method") val method: String?, // used in "http" @ColumnInfo(name = "headers") val headers: Map<String,String>?, // used in "http" @ColumnInfo(name = "body") val body: String?, // used in "http" @ColumnInfo(name = "url") val url: String?, // used in "view" and "http" actions @ColumnInfo(name = "method") val method: String?, // used in "http" action @ColumnInfo(name = "headers") val headers: Map<String,String>?, // used in "http" action @ColumnInfo(name = "body") val body: String?, // used in "http" action @ColumnInfo(name = "extras") val extras: Map<String,String>?, // used in "broadcast" action @ColumnInfo(name = "progress") val progress: Int?, // used to indicate progress in popup @ColumnInfo(name = "error") val error: String?, // used to indicate errors in popup ) const val ACTION_PROGRESS_ONGOING = 1 const val ACTION_PROGRESS_SUCCESS = 2 const val ACTION_PROGRESS_FAILED = 3 class Converters { private val gson = Gson() Loading @@ -102,12 +115,6 @@ class Converters { } } const val PROGRESS_NONE = -1 const val PROGRESS_INDETERMINATE = -2 const val PROGRESS_FAILED = -3 const val PROGRESS_DELETED = -4 const val PROGRESS_DONE = 100 @Entity data class User( @PrimaryKey @ColumnInfo(name = "baseUrl") val baseUrl: String, Loading
app/src/main/java/io/heckel/ntfy/msg/BroadcastService.kt +14 −3 Original line number Diff line number Diff line Loading @@ -2,8 +2,8 @@ package io.heckel.ntfy.msg import android.content.Context import android.content.Intent import android.util.Base64 import io.heckel.ntfy.R import io.heckel.ntfy.db.Action import io.heckel.ntfy.db.Notification import io.heckel.ntfy.db.Repository import io.heckel.ntfy.db.Subscription Loading @@ -17,7 +17,7 @@ import kotlinx.coroutines.launch * in order to facilitate tasks app integrations. */ class BroadcastService(private val ctx: Context) { fun send(subscription: Subscription, notification: Notification, muted: Boolean) { fun sendMessage(subscription: Subscription, notification: Notification, muted: Boolean) { val intent = Intent() intent.action = MESSAGE_RECEIVED_ACTION intent.putExtra("id", notification.id) Loading @@ -34,7 +34,17 @@ class BroadcastService(private val ctx: Context) { intent.putExtra("muted", muted) intent.putExtra("muted_str", muted.toString()) Log.d(TAG, "Sending intent broadcast: $intent") Log.d(TAG, "Sending message intent broadcast: $intent") ctx.sendBroadcast(intent) } fun sendUserAction(action: Action) { val intent = Intent() intent.action = USER_ACTION_ACTION action.extras?.forEach { (key, value) -> intent.putExtra(key, value) } Log.d(TAG, "Sending user action intent broadcast: $intent") ctx.sendBroadcast(intent) } Loading Loading @@ -109,5 +119,6 @@ class BroadcastService(private val ctx: Context) { // These constants cannot be changed without breaking the contract; also see manifest private const val MESSAGE_RECEIVED_ACTION = "io.heckel.ntfy.MESSAGE_RECEIVED" private const val MESSAGE_SEND_ACTION = "io.heckel.ntfy.SEND_MESSAGE" private const val USER_ACTION_ACTION = "io.heckel.ntfy.USER_ACTION" } }
app/src/main/java/io/heckel/ntfy/msg/DownloadWorker.kt +4 −4 Original line number Diff line number Diff line Loading @@ -91,13 +91,13 @@ class DownloadWorker(private val context: Context, params: WorkerParameters) : W while (bytes >= 0) { if (System.currentTimeMillis() - lastProgress > NOTIFICATION_UPDATE_INTERVAL_MILLIS) { if (isStopped) { // Canceled by user save(attachment.copy(progress = PROGRESS_NONE)) save(attachment.copy(progress = ATTACHMENT_PROGRESS_NONE)) return // File will be deleted in onStopped() } val progress = if (attachment.size != null && attachment.size!! > 0) { (bytesCopied.toFloat()/attachment.size!!.toFloat()*100).toInt() } else { PROGRESS_INDETERMINATE ATTACHMENT_PROGRESS_INDETERMINATE } save(attachment.copy(progress = progress)) lastProgress = System.currentTimeMillis() Loading @@ -114,7 +114,7 @@ class DownloadWorker(private val context: Context, params: WorkerParameters) : W save(attachment.copy( size = bytesCopied, contentUri = uri.toString(), progress = PROGRESS_DONE progress = ATTACHMENT_PROGRESS_DONE )) } } catch (e: Exception) { Loading Loading @@ -155,7 +155,7 @@ class DownloadWorker(private val context: Context, params: WorkerParameters) : W private fun failed(e: Exception) { Log.w(TAG, "Attachment download failed", e) save(attachment.copy(progress = PROGRESS_FAILED)) save(attachment.copy(progress = ATTACHMENT_PROGRESS_FAILED)) maybeDeleteFile() } Loading
app/src/main/java/io/heckel/ntfy/msg/Message.kt +3 −2 Original line number Diff line number Diff line Loading @@ -34,11 +34,12 @@ data class MessageAttachment( data class MessageAction( val id: String, val action: String, val label: String, val label: String, // "view", "broadcast" or "http" val url: String?, // used in "view" and "http" val method: String?, // used in "http" val method: String?, // used in "http", default is POST (!) val headers: Map<String,String>?, // used in "http" val body: String?, // used in "http" val extras: Map<String,String>?, // used in "broadcast" ) const val MESSAGE_ENCODING_BASE64 = "base64"
app/src/main/java/io/heckel/ntfy/msg/NotificationDispatcher.kt +1 −2 Original line number Diff line number Diff line package io.heckel.ntfy.msg import android.content.Context import android.util.Base64 import io.heckel.ntfy.db.Notification import io.heckel.ntfy.db.Repository import io.heckel.ntfy.db.Subscription Loading Loading @@ -35,7 +34,7 @@ class NotificationDispatcher(val context: Context, val repository: Repository) { notifier.display(subscription, notification) } if (broadcast) { broadcaster.send(subscription, notification, muted) broadcaster.sendMessage(subscription, notification, muted) } if (distribute) { safeLet(subscription.upAppId, subscription.upConnectorToken) { appId, connectorToken -> Loading