Loading app/build.gradle +3 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,9 @@ dependencies { // RecyclerView implementation "androidx.recyclerview:recyclerview:$rootProject.recyclerViewVersion" // Swipe down to refresh implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' // Material design implementation "com.google.android.material:material:$rootProject.materialVersion" Loading app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt +0 −2 Original line number Diff line number Diff line Loading @@ -19,14 +19,12 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import androidx.work.WorkManager 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 io.heckel.ntfy.msg.ApiService import io.heckel.ntfy.msg.NotificationService import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.util.* Loading app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt +15 −12 Original line number Diff line number Diff line Loading @@ -6,7 +6,6 @@ import android.app.AlertDialog import android.content.Context import android.content.Intent import android.net.Uri import android.os.Build import android.os.Bundle import android.util.Log import android.view.ActionMode Loading @@ -19,6 +18,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.work.* import com.google.firebase.messaging.FirebaseMessaging import io.heckel.ntfy.R Loading @@ -27,10 +27,6 @@ import io.heckel.ntfy.data.Subscription import io.heckel.ntfy.data.topicShortUrl import io.heckel.ntfy.msg.ApiService import io.heckel.ntfy.msg.NotificationService import io.heckel.ntfy.msg.SubscriberService import io.heckel.ntfy.msg.SubscriberService.ServiceState import io.heckel.ntfy.msg.SubscriberService.Actions import io.heckel.ntfy.msg.SubscriberService.Companion.readServiceState import io.heckel.ntfy.work.PollWorker import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch Loading @@ -38,6 +34,7 @@ import java.util.* import java.util.concurrent.TimeUnit import kotlin.random.Random class MainActivity : AppCompatActivity(), ActionMode.Callback { private val viewModel by viewModels<SubscriptionsViewModel> { SubscriptionsViewModelFactory((application as Application).repository) Loading @@ -46,6 +43,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback { private val api = ApiService() private lateinit var mainList: RecyclerView private lateinit var mainListContainer: SwipeRefreshLayout private lateinit var adapter: MainAdapter private lateinit var fab: View private var actionMode: ActionMode? = null Loading Loading @@ -73,6 +71,11 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback { onSubscribeButtonClick() } // Swipewn to refresh mainListContainer = findViewById(R.id.main_subscriptions_list_swipe_container) mainListContainer.setOnRefreshListener { refreshAllSubscriptions() } mainListContainer.setColorSchemeResources(R.color.primaryColor) // Update main list based on viewModel (& its datasource/livedata) val noEntries: View = findViewById(R.id.main_no_subscriptions) val onSubscriptionClick = { s: Subscription -> onSubscriptionItemClick(s) } Loading @@ -86,10 +89,10 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback { it?.let { subscriptions -> adapter.submitList(subscriptions as MutableList<Subscription>) if (it.isEmpty()) { mainList.visibility = View.GONE mainListContainer.visibility = View.GONE noEntries.visibility = View.VISIBLE } else { mainList.visibility = View.VISIBLE mainListContainer.visibility = View.VISIBLE noEntries.visibility = View.GONE } } Loading Loading @@ -134,10 +137,6 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback { override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.main_menu_refresh -> { refreshAllSubscriptions() true } R.id.main_menu_source -> { startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.main_menu_source_url)))) true Loading Loading @@ -230,12 +229,16 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback { } else { getString(R.string.refresh_message_result, newNotificationsCount) } runOnUiThread { Toast.makeText(this@MainActivity, toastMessage, Toast.LENGTH_LONG).show() } runOnUiThread { Toast.makeText(this@MainActivity, toastMessage, Toast.LENGTH_LONG).show() mainListContainer.isRefreshing = false } Log.d(TAG, "Finished polling for new notifications") } catch (e: Exception) { Log.e(TAG, "Polling failed: ${e.message}", e) runOnUiThread { Toast.makeText(this@MainActivity, getString(R.string.refresh_message_error, e.message), Toast.LENGTH_LONG).show() mainListContainer.isRefreshing = false } } } Loading app/src/main/res/layout/main_activity.xml +12 −6 Original line number Diff line number Diff line Loading @@ -4,15 +4,21 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:id="@+id/main_subscriptions_list_swipe_container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="10dp" android:visibility="gone"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/main_subscriptions_list" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" android:focusable="true" android:layout_marginTop="10dp" android:background="?android:attr/selectableItemBackground" app:layoutManager="LinearLayoutManager" android:visibility="gone"/> app:layoutManager="LinearLayoutManager"/> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" Loading app/src/main/res/menu/main_action_bar_menu.xml +0 −1 Original line number Diff line number Diff line <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/main_menu_refresh" android:title="@string/main_menu_refresh"/> <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> Loading
app/build.gradle +3 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,9 @@ dependencies { // RecyclerView implementation "androidx.recyclerview:recyclerview:$rootProject.recyclerViewVersion" // Swipe down to refresh implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' // Material design implementation "com.google.android.material:material:$rootProject.materialVersion" Loading
app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt +0 −2 Original line number Diff line number Diff line Loading @@ -19,14 +19,12 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import androidx.work.WorkManager 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 io.heckel.ntfy.msg.ApiService import io.heckel.ntfy.msg.NotificationService import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.util.* Loading
app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt +15 −12 Original line number Diff line number Diff line Loading @@ -6,7 +6,6 @@ import android.app.AlertDialog import android.content.Context import android.content.Intent import android.net.Uri import android.os.Build import android.os.Bundle import android.util.Log import android.view.ActionMode Loading @@ -19,6 +18,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.work.* import com.google.firebase.messaging.FirebaseMessaging import io.heckel.ntfy.R Loading @@ -27,10 +27,6 @@ import io.heckel.ntfy.data.Subscription import io.heckel.ntfy.data.topicShortUrl import io.heckel.ntfy.msg.ApiService import io.heckel.ntfy.msg.NotificationService import io.heckel.ntfy.msg.SubscriberService import io.heckel.ntfy.msg.SubscriberService.ServiceState import io.heckel.ntfy.msg.SubscriberService.Actions import io.heckel.ntfy.msg.SubscriberService.Companion.readServiceState import io.heckel.ntfy.work.PollWorker import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch Loading @@ -38,6 +34,7 @@ import java.util.* import java.util.concurrent.TimeUnit import kotlin.random.Random class MainActivity : AppCompatActivity(), ActionMode.Callback { private val viewModel by viewModels<SubscriptionsViewModel> { SubscriptionsViewModelFactory((application as Application).repository) Loading @@ -46,6 +43,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback { private val api = ApiService() private lateinit var mainList: RecyclerView private lateinit var mainListContainer: SwipeRefreshLayout private lateinit var adapter: MainAdapter private lateinit var fab: View private var actionMode: ActionMode? = null Loading Loading @@ -73,6 +71,11 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback { onSubscribeButtonClick() } // Swipewn to refresh mainListContainer = findViewById(R.id.main_subscriptions_list_swipe_container) mainListContainer.setOnRefreshListener { refreshAllSubscriptions() } mainListContainer.setColorSchemeResources(R.color.primaryColor) // Update main list based on viewModel (& its datasource/livedata) val noEntries: View = findViewById(R.id.main_no_subscriptions) val onSubscriptionClick = { s: Subscription -> onSubscriptionItemClick(s) } Loading @@ -86,10 +89,10 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback { it?.let { subscriptions -> adapter.submitList(subscriptions as MutableList<Subscription>) if (it.isEmpty()) { mainList.visibility = View.GONE mainListContainer.visibility = View.GONE noEntries.visibility = View.VISIBLE } else { mainList.visibility = View.VISIBLE mainListContainer.visibility = View.VISIBLE noEntries.visibility = View.GONE } } Loading Loading @@ -134,10 +137,6 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback { override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.main_menu_refresh -> { refreshAllSubscriptions() true } R.id.main_menu_source -> { startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.main_menu_source_url)))) true Loading Loading @@ -230,12 +229,16 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback { } else { getString(R.string.refresh_message_result, newNotificationsCount) } runOnUiThread { Toast.makeText(this@MainActivity, toastMessage, Toast.LENGTH_LONG).show() } runOnUiThread { Toast.makeText(this@MainActivity, toastMessage, Toast.LENGTH_LONG).show() mainListContainer.isRefreshing = false } Log.d(TAG, "Finished polling for new notifications") } catch (e: Exception) { Log.e(TAG, "Polling failed: ${e.message}", e) runOnUiThread { Toast.makeText(this@MainActivity, getString(R.string.refresh_message_error, e.message), Toast.LENGTH_LONG).show() mainListContainer.isRefreshing = false } } } Loading
app/src/main/res/layout/main_activity.xml +12 −6 Original line number Diff line number Diff line Loading @@ -4,15 +4,21 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:id="@+id/main_subscriptions_list_swipe_container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="10dp" android:visibility="gone"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/main_subscriptions_list" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" android:focusable="true" android:layout_marginTop="10dp" android:background="?android:attr/selectableItemBackground" app:layoutManager="LinearLayoutManager" android:visibility="gone"/> app:layoutManager="LinearLayoutManager"/> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" Loading
app/src/main/res/menu/main_action_bar_menu.xml +0 −1 Original line number Diff line number Diff line <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/main_menu_refresh" android:title="@string/main_menu_refresh"/> <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>