Test notification

This commit is contained in:
Philipp Heckel 2021-11-01 09:57:05 -04:00
parent 7d561a5068
commit fd1cfafdbf
8 changed files with 72 additions and 17 deletions

View file

@ -41,11 +41,14 @@ dependencies {
implementation "androidx.activity:activity-ktx:$rootProject.activityVersion"
implementation 'com.google.code.gson:gson:2.8.8'
// Room
// Room (SQLite)
def roomVersion = "2.3.0"
implementation "androidx.room:room-ktx:$roomVersion"
kapt "androidx.room:room-compiler:$roomVersion"
// Volley (HTTP library)
implementation 'com.android.volley:volley:1.2.1'
// Firebase, sigh ...
implementation 'com.google.firebase:firebase-messaging:22.0.0'

View file

@ -1,6 +1,7 @@
package io.heckel.ntfy.data
fun topicUrl(baseUrl: String, topic: String) = "${baseUrl}/${topic}"
fun topicShortUrl(baseUrl: String, topic: String) =
"${baseUrl}/${topic}"
topicUrl(baseUrl, topic)
.replace("http://", "")
.replace("https://", "")

View file

@ -3,22 +3,36 @@ package io.heckel.ntfy.ui
import android.app.AlertDialog
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.Request
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application
import io.heckel.ntfy.data.Notification
import io.heckel.ntfy.data.topicShortUrl
import io.heckel.ntfy.data.topicUrl
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.util.*
class DetailActivity : AppCompatActivity() {
private val viewModel by viewModels<DetailViewModel> {
DetailViewModelFactory((application as Application).repository)
}
private var subscriptionId: Long = 0L // Set in onCreate()
private var subscriptionBaseUrl: String = "" // Set in onCreate()
private var subscriptionTopic: String = "" // Set in onCreate()
override fun onCreate(savedInstanceState: Bundle?) {
@ -28,6 +42,7 @@ class DetailActivity : AppCompatActivity() {
// Get extras required for the return to the main activity
subscriptionId = intent.getLongExtra(MainActivity.EXTRA_SUBSCRIPTION_ID, 0)
subscriptionBaseUrl = intent.getStringExtra(MainActivity.EXTRA_SUBSCRIPTION_BASE_URL) ?: return
subscriptionTopic = intent.getStringExtra(MainActivity.EXTRA_SUBSCRIPTION_TOPIC) ?: return
// Set title
@ -61,6 +76,10 @@ class DetailActivity : AppCompatActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.detail_menu_test -> {
onTestClick()
true
}
R.id.detail_menu_delete -> {
onDeleteClick()
true
@ -69,7 +88,31 @@ class DetailActivity : AppCompatActivity() {
}
}
private fun onTestClick() {
val url = topicUrl(subscriptionBaseUrl, subscriptionTopic)
Log.d(TAG, "Sending test notification to $url")
val queue = Volley.newRequestQueue(this) // This should be a Singleton :-O
val stringRequest = object : StringRequest(
Method.PUT,
url,
{ _ -> /* Do nothing */ },
{ error ->
Toast
.makeText(this, getString(R.string.detail_test_message_error, error.message), Toast.LENGTH_LONG)
.show()
}
) {
override fun getBody(): ByteArray {
return getString(R.string.detail_test_message, Date().toString()).toByteArray()
}
}
queue.add(stringRequest)
}
private fun onDeleteClick() {
Log.d(TAG, "Deleting subscription ${topicShortUrl(subscriptionBaseUrl, subscriptionTopic)}")
val builder = AlertDialog.Builder(this)
builder
.setMessage(R.string.detail_delete_dialog_message)
@ -90,6 +133,10 @@ class DetailActivity : AppCompatActivity() {
}
private fun onNotificationClick(notification: Notification) {
println("clicked " + notification.id)
// TODO Do something
}
companion object {
const val TAG = "NtfyDetailActivity"
}
}

View file

@ -3,20 +3,18 @@ package io.heckel.ntfy.ui
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import com.google.firebase.messaging.FirebaseMessaging
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application
import io.heckel.ntfy.data.Subscription
import io.heckel.ntfy.data.topicShortUrl
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.*
import kotlin.random.Random
@ -29,6 +27,8 @@ class MainActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
// TODO implement multi-select delete - https://enoent.fr/posts/recyclerview-basics/
// Action bar
title = getString(R.string.main_action_bar_title)
@ -65,11 +65,11 @@ class MainActivity : AppCompatActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.menu_action_source -> {
R.id.main_menu_source -> {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.main_menu_source_url))))
true
}
R.id.detail_menu_delete -> {
R.id.main_menu_website -> {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.app_base_url))))
true
}
@ -83,12 +83,16 @@ class MainActivity : AppCompatActivity() {
}
private fun onSubscribe(topic: String, baseUrl: String) {
Log.d(TAG, "Adding subscription ${topicShortUrl(baseUrl, topic)}")
val subscription = Subscription(id = Random.nextLong(), baseUrl = baseUrl, topic = topic, notifications = 0, lastActive = Date().time/1000)
viewModel.add(subscription)
FirebaseMessaging.getInstance().subscribeToTopic(topic) // FIXME ignores baseUrl
}
private fun onSubscriptionItemClick(subscription: Subscription) {
Log.d(TAG, "Entering detail view for subscription $subscription")
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra(EXTRA_SUBSCRIPTION_ID, subscription.id)
intent.putExtra(EXTRA_SUBSCRIPTION_BASE_URL, subscription.baseUrl)
@ -100,6 +104,8 @@ class MainActivity : AppCompatActivity() {
if (requestCode == REQUEST_CODE_DELETE_SUBSCRIPTION && resultCode == RESULT_OK) {
val subscriptionId = data?.getLongExtra(EXTRA_SUBSCRIPTION_ID, 0)
val subscriptionTopic = data?.getStringExtra(EXTRA_SUBSCRIPTION_TOPIC)
Log.d(TAG, "Deleting subscription with subscription ID $subscriptionId (topic: $subscriptionTopic)")
subscriptionId?.let { id -> viewModel.remove(id) }
subscriptionTopic?.let { topic -> FirebaseMessaging.getInstance().unsubscribeFromTopic(topic) } // FIXME This only works for ntfy.sh
} else {

View file

@ -1,3 +1,4 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:title="@string/detail_menu_delete" android:id="@+id/detail_menu_delete"/>
<item android:id="@+id/detail_menu_test" android:title="@string/detail_menu_test"/>
<item android:id="@+id/detail_menu_delete" android:title="@string/detail_menu_delete"/>
</menu>

View file

@ -1,5 +1,4 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/menu_action_source"
android:title="@string/main_menu_source_title"/>
<item android:title="@string/main_menu_website_title" android:id="@+id/detail_menu_delete"/>
<item android:id="@+id/main_menu_source" android:title="@string/main_menu_source_title"/>
<item android:id="@+id/main_menu_website" android:title="@string/main_menu_website_title"/>
</menu>

View file

@ -1,4 +0,0 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/main_item_popup_unsubscribe"
android:title="@string/main_item_popup_unsubscribe"/>
</menu>

View file

@ -18,7 +18,6 @@
<string name="main_item_status_reconnecting">reconnecting …</string>
<string name="main_item_status_text_one">%1$d notification received</string>
<string name="main_item_status_text_not_one">%1$d notifications received</string>
<string name="main_item_popup_unsubscribe">Unsubscribe</string>
<string name="main_add_button_description">Add subscription</string>
<string name="main_no_subscriptions_text">It looks like you don\'t have any subscriptions yet.</string>
@ -34,7 +33,10 @@
<string name="detail_delete_dialog_message">Do you really want to permanently delete this subscription and all its messages?</string>
<string name="detail_delete_dialog_permanently_delete">Permanently delete</string>
<string name="detail_delete_dialog_cancel">Cancel</string>
<string name="detail_test_message">This is a test notification from the Ntfy Android app. It was sent at %1$s.</string>
<string name="detail_test_message_error">Could not send test message: %1$s</string>
<!-- Detail activity: Action bar -->
<string name="detail_menu_test">Send test notification</string>
<string name="detail_menu_delete">Delete topic</string>
</resources>