diff --git a/app/src/main/java/io/heckel/ntfy/msg/SubscriberConnection.kt b/app/src/main/java/io/heckel/ntfy/msg/SubscriberConnection.kt
index 9785aed..6e4e98f 100644
--- a/app/src/main/java/io/heckel/ntfy/msg/SubscriberConnection.kt
+++ b/app/src/main/java/io/heckel/ntfy/msg/SubscriberConnection.kt
@@ -43,7 +43,9 @@ class SubscriberConnection(
val failed = AtomicBoolean(false)
val fail = { e: Exception ->
failed.set(true)
- stateChangeListener(subscriptions.values, ConnectionState.CONNECTING)
+ if (isActive && serviceActive()) { // Avoid UI update races if we're restarting a connection
+ stateChangeListener(subscriptions.values, ConnectionState.CONNECTING)
+ }
}
// Call /json subscribe endpoint and loop until the call fails, is canceled,
@@ -57,8 +59,7 @@ class SubscriberConnection(
}
} catch (e: Exception) {
Log.e(TAG, "[$url] Connection failed: ${e.message}", e)
- if (isActive && serviceActive()) {
- // Only update if we're not canceled, otherwise this may lead to races
+ if (isActive && serviceActive()) { // Avoid UI update races if we're restarting a connection
stateChangeListener(subscriptions.values, ConnectionState.CONNECTING)
}
}
diff --git a/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt b/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt
index 83d7d40..7b4d635 100644
--- a/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt
+++ b/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt
@@ -125,4 +125,10 @@ class AddFragment(private val viewModel: SubscriptionsViewModel, private val onS
getString(R.string.app_base_url)
}
}
+
+ companion object {
+ fun newInstance() {
+ // ... make it not crash
+ }
+ }
}
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 0ff3624..df8fa66 100644
--- a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt
+++ b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt
@@ -232,12 +232,14 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback {
val url = topicUrl(subscriptionBaseUrl, subscriptionTopic)
Log.d(TAG, "Copying topic URL $url to clipboard ")
- val clipboard: ClipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
- val clip = ClipData.newPlainText("topic address", url)
- clipboard.setPrimaryClip(clip)
- Toast
- .makeText(this, getString(R.string.detail_copied_to_clipboard_message), Toast.LENGTH_LONG)
- .show()
+ runOnUiThread {
+ val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
+ val clip = ClipData.newPlainText("topic address", url)
+ clipboard.setPrimaryClip(clip)
+ Toast
+ .makeText(this, getString(R.string.detail_copied_to_clipboard_message), Toast.LENGTH_LONG)
+ .show()
+ }
}
private fun refresh() {
@@ -345,13 +347,15 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback {
}
private fun copyToClipboard(notification: Notification) {
- val message = notification.message + "\n\n" + Date(notification.timestamp * 1000).toString()
- val clipboard: ClipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
- val clip = ClipData.newPlainText("notification message", message)
- clipboard.setPrimaryClip(clip)
- Toast
- .makeText(this, getString(R.string.detail_copied_to_clipboard_message), Toast.LENGTH_LONG)
- .show()
+ runOnUiThread {
+ val message = notification.message + "\n\n" + Date(notification.timestamp * 1000).toString()
+ val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
+ val clip = ClipData.newPlainText("notification message", message)
+ clipboard.setPrimaryClip(clip)
+ Toast
+ .makeText(this, getString(R.string.detail_copied_to_clipboard_message), Toast.LENGTH_LONG)
+ .show()
+ }
}
private fun onNotificationLongClick(notification: Notification) {
@@ -407,10 +411,10 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback {
it.message + "\n" + Date(it.timestamp * 1000).toString()
}.orEmpty()
}
- val clipboard: ClipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
- val clip = ClipData.newPlainText("notifications", content)
- clipboard.setPrimaryClip(clip)
runOnUiThread {
+ val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
+ val clip = ClipData.newPlainText("notifications", content)
+ clipboard.setPrimaryClip(clip)
Toast
.makeText(this@DetailActivity, getString(R.string.detail_copied_to_clipboard_message), Toast.LENGTH_LONG)
.show()
diff --git a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt
index 31fe6d7..ef70fb3 100644
--- a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt
+++ b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt
@@ -152,8 +152,9 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback {
}
private fun onSubscribeButtonClick() {
- val newFragment = AddFragment(viewModel) { topic, baseUrl, instant -> onSubscribe(topic, baseUrl, instant) }
- newFragment.show(supportFragmentManager, "AddFragment")
+ val newFragment = AddFragment(viewModel, ::onSubscribe)
+ newFragment
+ .show(supportFragmentManager, "AddFragment")
}
private fun onSubscribe(topic: String, baseUrl: String, instant: Boolean) {
diff --git a/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt b/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt
index ade97dd..2086997 100644
--- a/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt
+++ b/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt
@@ -12,7 +12,7 @@ import io.heckel.ntfy.R
import io.heckel.ntfy.data.ConnectionState
import io.heckel.ntfy.data.Subscription
import io.heckel.ntfy.data.topicShortUrl
-import java.text.SimpleDateFormat
+import java.text.DateFormat
import java.util.*
@@ -62,12 +62,18 @@ class MainAdapter(private val onClick: (Subscription) -> Unit, private val onLon
if (subscription.instant && subscription.state == ConnectionState.CONNECTING) {
statusMessage += ", " + context.getString(R.string.main_item_status_reconnecting)
}
+ val date = Date(subscription.lastActive * 1000)
+ val dateStr = DateFormat.getDateInstance(DateFormat.SHORT).format(date)
+ val moreThanOneDay = System.currentTimeMillis()/1000 - subscription.lastActive > 24 * 60 * 60
+ val sameDay = dateStr == DateFormat.getDateInstance(DateFormat.SHORT).format(Date()) // Omg this is horrible
val dateText = if (subscription.lastActive == 0L) {
""
- } else if (System.currentTimeMillis()/1000 - subscription.lastActive < 24 * 60 * 60) {
- SimpleDateFormat("HH:mm").format(Date(subscription.lastActive*1000))
+ } else if (sameDay) {
+ DateFormat.getTimeInstance(DateFormat.SHORT).format(date)
+ } else if (!moreThanOneDay) {
+ context.getString(R.string.main_item_date_yesterday)
} else {
- SimpleDateFormat("M/d/yy").format(Date(subscription.lastActive*1000))
+ dateStr
}
nameView.text = topicShortUrl(subscription.baseUrl, subscription.topic)
statusView.text = statusMessage
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index f48db4d..0bc89ed 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -35,6 +35,7 @@
%1$d notification
%1$d notifications
reconnecting …
+ Yesterday
Add subscription
It looks like you don\'t have any subscriptions yet.
Click the button below to create or subscribe to a topic. After that, you can send messages via PUT or POST and you\'ll receive notifications on your phone.