Adjut foreground notification to reflect subscription state, add instant icon to non-ntfy.sh subscriptions
This commit is contained in:
parent
cea43b3529
commit
ce6a2152db
6 changed files with 60 additions and 19 deletions
|
@ -131,6 +131,18 @@ class SubscriberService : Service() {
|
||||||
cancelJob(subscriptionId)
|
cancelJob(subscriptionId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (jobs.size > 0) {
|
||||||
|
synchronized(this) {
|
||||||
|
val title = getString(R.string.channel_subscriber_notification_title)
|
||||||
|
val text = if (jobs.size == 1) {
|
||||||
|
getString(R.string.channel_subscriber_notification_text_one)
|
||||||
|
} else {
|
||||||
|
getString(R.string.channel_subscriber_notification_text_more, jobs.size)
|
||||||
|
}
|
||||||
|
notification = createNotification(title, text)
|
||||||
|
notificationManager?.notify(NOTIFICATION_SERVICE_ID, notification)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun cancelJob(subscriptionId: Long?) {
|
private fun cancelJob(subscriptionId: Long?) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package io.heckel.ntfy.ui
|
package io.heckel.ntfy.ui
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
@ -9,14 +8,10 @@ import android.text.TextWatcher
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.CheckBox
|
import android.widget.CheckBox
|
||||||
import androidx.activity.viewModels
|
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.viewModelScope
|
|
||||||
import com.google.android.material.textfield.TextInputEditText
|
import com.google.android.material.textfield.TextInputEditText
|
||||||
import io.heckel.ntfy.R
|
import io.heckel.ntfy.R
|
||||||
import io.heckel.ntfy.app.Application
|
|
||||||
import io.heckel.ntfy.data.Repository
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
@ -25,6 +20,7 @@ class AddFragment(private val viewModel: SubscriptionsViewModel, private val onS
|
||||||
private lateinit var baseUrlText: TextInputEditText
|
private lateinit var baseUrlText: TextInputEditText
|
||||||
private lateinit var useAnotherServerCheckbox: CheckBox
|
private lateinit var useAnotherServerCheckbox: CheckBox
|
||||||
private lateinit var useAnotherServerDescription: View
|
private lateinit var useAnotherServerDescription: View
|
||||||
|
private lateinit var instantDeliveryBox: View
|
||||||
private lateinit var instantDeliveryCheckbox: CheckBox
|
private lateinit var instantDeliveryCheckbox: CheckBox
|
||||||
private lateinit var instantDeliveryDescription: View
|
private lateinit var instantDeliveryDescription: View
|
||||||
private lateinit var subscribeButton: Button
|
private lateinit var subscribeButton: Button
|
||||||
|
@ -35,6 +31,7 @@ class AddFragment(private val viewModel: SubscriptionsViewModel, private val onS
|
||||||
val view = requireActivity().layoutInflater.inflate(R.layout.add_dialog_fragment, null)
|
val view = requireActivity().layoutInflater.inflate(R.layout.add_dialog_fragment, null)
|
||||||
topicNameText = view.findViewById(R.id.add_dialog_topic_text) as TextInputEditText
|
topicNameText = view.findViewById(R.id.add_dialog_topic_text) as TextInputEditText
|
||||||
baseUrlText = view.findViewById(R.id.add_dialog_base_url_text) as TextInputEditText
|
baseUrlText = view.findViewById(R.id.add_dialog_base_url_text) as TextInputEditText
|
||||||
|
instantDeliveryBox = view.findViewById(R.id.add_dialog_instant_delivery_box)
|
||||||
instantDeliveryCheckbox = view.findViewById(R.id.add_dialog_instant_delivery_checkbox) as CheckBox
|
instantDeliveryCheckbox = view.findViewById(R.id.add_dialog_instant_delivery_checkbox) as CheckBox
|
||||||
instantDeliveryDescription = view.findViewById(R.id.add_dialog_instant_delivery_description)
|
instantDeliveryDescription = view.findViewById(R.id.add_dialog_instant_delivery_description)
|
||||||
useAnotherServerCheckbox = view.findViewById(R.id.add_dialog_use_another_server_checkbox) as CheckBox
|
useAnotherServerCheckbox = view.findViewById(R.id.add_dialog_use_another_server_checkbox) as CheckBox
|
||||||
|
@ -82,12 +79,12 @@ class AddFragment(private val viewModel: SubscriptionsViewModel, private val onS
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
useAnotherServerDescription.visibility = View.VISIBLE
|
useAnotherServerDescription.visibility = View.VISIBLE
|
||||||
baseUrlText.visibility = View.VISIBLE
|
baseUrlText.visibility = View.VISIBLE
|
||||||
instantDeliveryCheckbox.visibility = View.GONE
|
instantDeliveryBox.visibility = View.GONE
|
||||||
instantDeliveryDescription.visibility = View.GONE
|
instantDeliveryDescription.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
useAnotherServerDescription.visibility = View.GONE
|
useAnotherServerDescription.visibility = View.GONE
|
||||||
baseUrlText.visibility = View.GONE
|
baseUrlText.visibility = View.GONE
|
||||||
instantDeliveryCheckbox.visibility = View.VISIBLE
|
instantDeliveryBox.visibility = View.VISIBLE
|
||||||
if (instantDeliveryCheckbox.isChecked) instantDeliveryDescription.visibility = View.VISIBLE
|
if (instantDeliveryCheckbox.isChecked) instantDeliveryDescription.visibility = View.VISIBLE
|
||||||
else instantDeliveryDescription.visibility = View.GONE
|
else instantDeliveryDescription.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,6 +143,10 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback {
|
||||||
onInstantEnableClick(enable = false)
|
onInstantEnableClick(enable = false)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
R.id.detail_menu_instant_info -> {
|
||||||
|
onInstantInfoClick()
|
||||||
|
true
|
||||||
|
}
|
||||||
R.id.detail_menu_copy_url -> {
|
R.id.detail_menu_copy_url -> {
|
||||||
onCopyUrlClick()
|
onCopyUrlClick()
|
||||||
true
|
true
|
||||||
|
@ -232,18 +236,27 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onInstantInfoClick() {
|
||||||
|
Log.d(TAG, "Showing instant info toast")
|
||||||
|
Toast.makeText(this@DetailActivity, getString(R.string.detail_instant_info), Toast.LENGTH_LONG)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
private fun showHideInstantMenuItems(enable: Boolean) {
|
private fun showHideInstantMenuItems(enable: Boolean) {
|
||||||
subscriptionInstant = enable
|
subscriptionInstant = enable
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
val appBaseUrl = getString(R.string.app_base_url)
|
val appBaseUrl = getString(R.string.app_base_url)
|
||||||
val enableInstantItem = menu.findItem(R.id.detail_menu_enable_instant)
|
val enableInstantItem = menu.findItem(R.id.detail_menu_enable_instant)
|
||||||
val disableInstantItem = menu.findItem(R.id.detail_menu_disable_instant)
|
val disableInstantItem = menu.findItem(R.id.detail_menu_disable_instant)
|
||||||
|
val instantInfoItem = menu.findItem(R.id.detail_menu_instant_info)
|
||||||
if (subscriptionBaseUrl == appBaseUrl) {
|
if (subscriptionBaseUrl == appBaseUrl) {
|
||||||
enableInstantItem?.isVisible = !subscriptionInstant
|
enableInstantItem?.isVisible = !subscriptionInstant
|
||||||
disableInstantItem?.isVisible = subscriptionInstant
|
disableInstantItem?.isVisible = subscriptionInstant
|
||||||
|
instantInfoItem?.isVisible = false
|
||||||
} else {
|
} else {
|
||||||
enableInstantItem?.isVisible = false
|
enableInstantItem?.isVisible = false
|
||||||
disableInstantItem?.isVisible = false
|
disableInstantItem?.isVisible = false
|
||||||
|
instantInfoItem?.isVisible = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,6 +362,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback {
|
||||||
Toast
|
Toast
|
||||||
.makeText(this@DetailActivity, getString(R.string.detail_copied_to_clipboard_message), Toast.LENGTH_LONG)
|
.makeText(this@DetailActivity, getString(R.string.detail_copied_to_clipboard_message), Toast.LENGTH_LONG)
|
||||||
.show()
|
.show()
|
||||||
|
finishActionMode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingLeft="16dp"
|
android:paddingLeft="16dp"
|
||||||
|
@ -43,11 +43,23 @@
|
||||||
android:layout_height="wrap_content" android:visibility="gone"
|
android:layout_height="wrap_content" android:visibility="gone"
|
||||||
android:hint="@string/app_base_url" android:inputType="textUri" android:maxLines="1"
|
android:hint="@string/app_base_url" android:inputType="textUri" android:maxLines="1"
|
||||||
android:layout_marginTop="-2dp" android:layout_marginBottom="5dp"/>
|
android:layout_marginTop="-2dp" android:layout_marginBottom="5dp"/>
|
||||||
<CheckBox
|
<LinearLayout
|
||||||
android:text="@string/add_dialog_instant_delivery"
|
android:orientation="horizontal"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" android:id="@+id/add_dialog_instant_delivery_checkbox"
|
android:layout_height="wrap_content" android:id="@+id/add_dialog_instant_delivery_box">
|
||||||
android:layout_marginTop="-8dp" android:layout_marginBottom="-5dp" android:layout_marginStart="-3dp"/>
|
<CheckBox
|
||||||
|
android:text="@string/add_dialog_instant_delivery"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" android:id="@+id/add_dialog_instant_delivery_checkbox"
|
||||||
|
android:layout_marginTop="-8dp" android:layout_marginBottom="-5dp" android:layout_marginStart="-3dp"/>
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp" app:srcCompat="@drawable/ic_bolt_black_24dp"
|
||||||
|
android:id="@+id/add_dialog_instant_image"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/main_item_text"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/main_item_date" android:paddingTop="3dp"
|
||||||
|
android:layout_marginTop="3dp"/>
|
||||||
|
</LinearLayout>
|
||||||
<TextView
|
<TextView
|
||||||
android:text="@string/add_dialog_instant_delivery_description"
|
android:text="@string/add_dialog_instant_delivery_description"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
app:showAsAction="ifRoom|withText" android:icon="@drawable/ic_bolt_outline_white_24dp"/>
|
app:showAsAction="ifRoom|withText" android:icon="@drawable/ic_bolt_outline_white_24dp"/>
|
||||||
<item android:id="@+id/detail_menu_disable_instant" android:title="@string/detail_menu_disable_instant"
|
<item android:id="@+id/detail_menu_disable_instant" android:title="@string/detail_menu_disable_instant"
|
||||||
android:icon="@drawable/ic_bolt_white_24dp" app:showAsAction="ifRoom|withText"/>
|
android:icon="@drawable/ic_bolt_white_24dp" app:showAsAction="ifRoom|withText"/>
|
||||||
|
<item android:id="@+id/detail_menu_instant_info" android:title="@string/detail_menu_instant_info"
|
||||||
|
android:icon="@drawable/ic_bolt_white_24dp" app:showAsAction="ifRoom|withText"/>
|
||||||
<item android:id="@+id/detail_menu_test" android:title="@string/detail_menu_test"/>
|
<item android:id="@+id/detail_menu_test" android:title="@string/detail_menu_test"/>
|
||||||
<item android:id="@+id/detail_menu_copy_url" android:title="@string/detail_menu_copy_url"/>
|
<item android:id="@+id/detail_menu_copy_url" android:title="@string/detail_menu_copy_url"/>
|
||||||
<item android:id="@+id/detail_menu_unsubscribe" android:title="@string/detail_menu_unsubscribe"/>
|
<item android:id="@+id/detail_menu_unsubscribe" android:title="@string/detail_menu_unsubscribe"/>
|
||||||
|
|
|
@ -6,8 +6,10 @@
|
||||||
<!-- Notification channels -->
|
<!-- Notification channels -->
|
||||||
<string name="channel_notifications_name">Notifications</string>
|
<string name="channel_notifications_name">Notifications</string>
|
||||||
<string name="channel_subscriber_service_name">Subscription Service</string>
|
<string name="channel_subscriber_service_name">Subscription Service</string>
|
||||||
<string name="channel_subscriber_notification_title">Subscribed topics</string>
|
<string name="channel_subscriber_notification_title">Listening for incoming notifications</string>
|
||||||
<string name="channel_subscriber_notification_text">Listening for incoming notifications</string>
|
<string name="channel_subscriber_notification_text">You are subscribed to instant delivery topics</string>
|
||||||
|
<string name="channel_subscriber_notification_text_one">You are subscribed to one instant delivery topic</string>
|
||||||
|
<string name="channel_subscriber_notification_text_more">You are subscribed to %1$d instant delivery topics</string>
|
||||||
|
|
||||||
<!-- Common refresh toasts -->
|
<!-- Common refresh toasts -->
|
||||||
<string name="refresh_message_result">%1$d notification(s) received</string>
|
<string name="refresh_message_result">%1$d notification(s) received</string>
|
||||||
|
@ -16,7 +18,7 @@
|
||||||
|
|
||||||
<!-- Main activity: Action bar -->
|
<!-- Main activity: Action bar -->
|
||||||
<string name="main_action_bar_title">Subscribed topics</string>
|
<string name="main_action_bar_title">Subscribed topics</string>
|
||||||
<string name="main_menu_source_title">View source & report bugs</string>
|
<string name="main_menu_source_title">Report a bug</string>
|
||||||
<string name="main_menu_source_url">https://heckel.io/ntfy-android</string>
|
<string name="main_menu_source_url">https://heckel.io/ntfy-android</string>
|
||||||
<string name="main_menu_website_title">Visit ntfy.sh</string>
|
<string name="main_menu_website_title">Visit ntfy.sh</string>
|
||||||
|
|
||||||
|
@ -42,12 +44,12 @@
|
||||||
<string name="add_dialog_use_another_server">Use another server</string>
|
<string name="add_dialog_use_another_server">Use another server</string>
|
||||||
<string name="add_dialog_use_another_server_description">
|
<string name="add_dialog_use_another_server_description">
|
||||||
You can subscribe to topics from your own server. Due to platform limitations, this option requires a foreground
|
You can subscribe to topics from your own server. Due to platform limitations, this option requires a foreground
|
||||||
service and consumes more battery, but delivers notifications faster.
|
service and consumes more power, but also delivers notifications faster (even in doze mode).
|
||||||
</string>
|
</string>
|
||||||
<string name="add_dialog_instant_delivery">Instant delivery even in doze mode</string>
|
<string name="add_dialog_instant_delivery">Instant delivery in doze mode</string>
|
||||||
<string name="add_dialog_instant_delivery_description">
|
<string name="add_dialog_instant_delivery_description">
|
||||||
Android doze mode may delay message delivery. With this open, notifications are immediately delivered even in doze mode.
|
Doze mode sometimes causes delayed message delivery to conserve power. With instant delivery, notifications are
|
||||||
Requires foreground service and consumes more battery.
|
always immediately delivered. This requires a foreground service and consumes a little more power.
|
||||||
</string>
|
</string>
|
||||||
<string name="add_dialog_button_cancel">Cancel</string>
|
<string name="add_dialog_button_cancel">Cancel</string>
|
||||||
<string name="add_dialog_button_subscribe">Subscribe</string>
|
<string name="add_dialog_button_subscribe">Subscribe</string>
|
||||||
|
@ -65,12 +67,14 @@
|
||||||
<string name="detail_copied_to_clipboard_message">Copied to clipboard</string>
|
<string name="detail_copied_to_clipboard_message">Copied to clipboard</string>
|
||||||
<string name="detail_instant_delivery_enabled">Instant delivery enabled</string>
|
<string name="detail_instant_delivery_enabled">Instant delivery enabled</string>
|
||||||
<string name="detail_instant_delivery_disabled">Instant delivery disabled</string>
|
<string name="detail_instant_delivery_disabled">Instant delivery disabled</string>
|
||||||
|
<string name="detail_instant_info">Instant delivery is always enabled for subscriptions with other servers</string>
|
||||||
|
|
||||||
<!-- Detail activity: Action bar -->
|
<!-- Detail activity: Action bar -->
|
||||||
<string name="detail_menu_test">Send test notification</string>
|
<string name="detail_menu_test">Send test notification</string>
|
||||||
<string name="detail_menu_copy_url">Copy topic address</string>
|
<string name="detail_menu_copy_url">Copy topic address</string>
|
||||||
<string name="detail_menu_enable_instant">Enable instant delivery</string>
|
<string name="detail_menu_enable_instant">Enable instant delivery</string>
|
||||||
<string name="detail_menu_disable_instant">Disable instant delivery</string>
|
<string name="detail_menu_disable_instant">Disable instant delivery</string>
|
||||||
|
<string name="detail_menu_instant_info">Instant delivery enabled</string>
|
||||||
<string name="detail_menu_unsubscribe">Unsubscribe</string>
|
<string name="detail_menu_unsubscribe">Unsubscribe</string>
|
||||||
|
|
||||||
<!-- Detail activity: Action mode -->
|
<!-- Detail activity: Action mode -->
|
||||||
|
|
Loading…
Reference in a new issue