Add notification history page to settings (#1054)

* Add notification history page to settings

* Attempt to fix lint minimal errors

* Attempt to fix minimal errors again

* Remove minimal files to revert back to original commit

* Remove unneeded stuff
This commit is contained in:
Daniel Shokouhi 2020-10-15 05:28:22 -07:00 committed by GitHub
parent 1f48c44f44
commit e0f2eab639
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 249 additions and 4 deletions

View file

@ -35,6 +35,8 @@ import io.homeassistant.companion.android.common.data.authentication.SessionStat
import io.homeassistant.companion.android.common.data.integration.DeviceRegistration
import io.homeassistant.companion.android.common.data.integration.IntegrationRepository
import io.homeassistant.companion.android.common.data.url.UrlRepository
import io.homeassistant.companion.android.database.AppDatabase
import io.homeassistant.companion.android.database.notification.NotificationItem
import io.homeassistant.companion.android.sensors.LocationSensorManager
import io.homeassistant.companion.android.util.UrlHandler
import io.homeassistant.companion.android.util.cancel
@ -114,6 +116,10 @@ class MessagingService : FirebaseMessagingService() {
// Check if message contains a data payload.
remoteMessage.data.let {
Log.d(TAG, "Message data payload: " + remoteMessage.data)
val notificationDao = AppDatabase.getInstance(applicationContext).notificationDao()
val now = System.currentTimeMillis()
val notificationRow = NotificationItem(0, now, it[MESSAGE].toString(), it.toString())
notificationDao.add(notificationRow)
when {
it[MESSAGE] == REQUEST_LOCATION_UPDATE -> {

View file

@ -19,6 +19,8 @@ import io.homeassistant.companion.android.R
import io.homeassistant.companion.android.common.data.integration.IntegrationRepository
import io.homeassistant.companion.android.database.authentication.Authentication
import io.homeassistant.companion.android.database.authentication.AuthenticationDao
import io.homeassistant.companion.android.database.notification.NotificationDao
import io.homeassistant.companion.android.database.notification.NotificationItem
import io.homeassistant.companion.android.database.sensor.Attribute
import io.homeassistant.companion.android.database.sensor.Sensor
import io.homeassistant.companion.android.database.sensor.SensorDao
@ -42,9 +44,10 @@ import kotlinx.coroutines.runBlocking
ButtonWidgetEntity::class,
MediaPlayerControlsWidgetEntity::class,
StaticWidgetEntity::class,
TemplateWidgetEntity::class
TemplateWidgetEntity::class,
NotificationItem::class
],
version = 12,
version = 13,
exportSchema = false
)
abstract class AppDatabase : RoomDatabase() {
@ -54,6 +57,7 @@ abstract class AppDatabase : RoomDatabase() {
abstract fun mediaPlayCtrlWidgetDao(): MediaPlayerControlsWidgetDao
abstract fun staticWidgetDao(): StaticWidgetDao
abstract fun templateWidgetDao(): TemplateWidgetDao
abstract fun notificationDao(): NotificationDao
companion object {
private const val DATABASE_NAME = "HomeAssistantDB"
@ -89,7 +93,8 @@ abstract class AppDatabase : RoomDatabase() {
MIGRATION_8_9,
MIGRATION_9_10,
MIGRATION_10_11,
MIGRATION_11_12
MIGRATION_11_12,
MIGRATION_12_13
)
.fallbackToDestructiveMigration()
.build()
@ -266,6 +271,12 @@ abstract class AppDatabase : RoomDatabase() {
}
}
private val MIGRATION_12_13 = object : Migration(12, 13) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `notification_history` (`id` INTEGER NOT NULL, `received` LONG NOT NULL, `message` TEXT NOT NULL, `data` TEXT NOT NULL, PRIMARY KEY(`id`))")
}
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationManager = appContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

View file

@ -0,0 +1,28 @@
package io.homeassistant.companion.android.database.notification
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
@Dao
interface NotificationDao {
@Query("SELECT * FROM notification_history WHERE id = :id")
fun get(id: Int): NotificationItem?
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun add(notification: NotificationItem)
@Query("SELECT * FROM notification_history ORDER BY received DESC")
fun getAll(): Array<NotificationItem>?
@Query("SELECT * FROM notification_history ORDER BY received DESC LIMIT 25")
fun getLast25(): Array<NotificationItem>?
@Query("DELETE FROM notification_history WHERE id = :id")
fun delete(id: Int)
@Query("DELETE FROM notification_history")
fun deleteAll()
}

View file

@ -0,0 +1,17 @@
package io.homeassistant.companion.android.database.notification
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "notification_history")
data class NotificationItem(
@PrimaryKey(autoGenerate = true)
val id: Int,
@ColumnInfo(name = "received")
val received: Long,
@ColumnInfo(name = "message")
val message: String,
@ColumnInfo(name = "data")
val data: String
)

View file

@ -14,6 +14,7 @@ import androidx.biometric.BiometricManager
import androidx.preference.EditTextPreference
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
import io.homeassistant.companion.android.BuildConfig
@ -24,6 +25,7 @@ import io.homeassistant.companion.android.authenticator.Authenticator
import io.homeassistant.companion.android.common.dagger.GraphComponentAccessor
import io.homeassistant.companion.android.nfc.NfcSetupActivity
import io.homeassistant.companion.android.sensors.SensorsSettingsFragment
import io.homeassistant.companion.android.settings.notification.NotificationHistoryFragment
import io.homeassistant.companion.android.settings.ssid.SsidDialogFragment
import io.homeassistant.companion.android.settings.ssid.SsidPreference
import javax.inject.Inject
@ -128,6 +130,21 @@ class SettingsFragment : PreferenceFragmentCompat(), SettingsView {
}
if (BuildConfig.FLAVOR == "full") {
findPreference<PreferenceCategory>("notifications")?.let {
it.isVisible = true
}
findPreference<Preference>("notification_history")?.let {
it.isVisible = true
it.setOnPreferenceClickListener {
parentFragmentManager
.beginTransaction()
.replace(R.id.content, NotificationHistoryFragment.newInstance())
.addToBackStack(getString(R.string.notifications))
.commit()
return@setOnPreferenceClickListener true
}
}
findPreference<Preference>("notification_rate_limit")?.let {
val rateLimits = presenter.getNotificationRateLimits()

View file

@ -0,0 +1,41 @@
package io.homeassistant.companion.android.settings.notification
import android.os.Bundle
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import io.homeassistant.companion.android.R
import io.homeassistant.companion.android.database.notification.NotificationItem
import java.util.Calendar
import java.util.GregorianCalendar
class NotificationDetailFragment(
private val notification: NotificationItem
) :
PreferenceFragmentCompat() {
companion object {
fun newInstance(
notification: NotificationItem
): NotificationDetailFragment {
return NotificationDetailFragment(notification)
}
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.notification_detail)
findPreference<Preference>("received_at")?.let {
val cal: Calendar = GregorianCalendar()
cal.timeInMillis = notification.received
it.summary = cal.time.toString()
}
findPreference<Preference>("message")?.let {
it.summary = notification.message
}
findPreference<Preference>("data")?.let {
it.summary = notification.data
}
}
}

View file

@ -0,0 +1,62 @@
package io.homeassistant.companion.android.settings.notification
import android.os.Bundle
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat
import io.homeassistant.companion.android.R
import io.homeassistant.companion.android.database.AppDatabase
import java.util.Calendar
import java.util.GregorianCalendar
class NotificationHistoryFragment : PreferenceFragmentCompat() {
companion object {
fun newInstance(): NotificationHistoryFragment {
return NotificationHistoryFragment()
}
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.notifications, rootKey)
val notificationDao = AppDatabase.getInstance(requireContext()).notificationDao()
val notificationList = notificationDao.getLast25()
val prefCategory = PreferenceCategory(preferenceScreen.context)
if (!notificationList.isNullOrEmpty()) {
prefCategory.title = requireContext().getString(R.string.last_25_notifications)
prefCategory.isIconSpaceReserved = false
preferenceScreen.addPreference(prefCategory)
for (item in notificationList) {
val pref = Preference(preferenceScreen.context)
val cal: Calendar = GregorianCalendar()
cal.timeInMillis = item.received
pref.key = item.id.toString()
pref.title = cal.time.toString()
pref.summary = item.message
pref.isIconSpaceReserved = false
pref.setOnPreferenceClickListener {
parentFragmentManager
.beginTransaction()
.replace(
R.id.content,
NotificationDetailFragment.newInstance(
item
)
)
.addToBackStack("Notification Detail")
.commit()
return@setOnPreferenceClickListener true
}
prefCategory.addPreference(pref)
}
} else {
findPreference<Preference>("no_notifications")?.let {
it.isVisible = true
}
}
}
}

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@color/colorAccent"
android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z"/>
</vector>

View file

@ -162,8 +162,17 @@ Home Assistant instance</string>
<string name="nfc_write_tag_success">Successfully wrote nfc tag</string>
<string name="nfc_write_tag_too_early">Please fill out the form first</string>
<string name="not_private">Your connection to this site is not private.</string>
<string name="notifications">Notifications</string>
<string name="notification_clear_failure">Failed to send event on notification cleared</string>
<string name="notification_dismiss_failure">Failed to send event on notification dismissed</string>
<string name="notification_data">Full Notification Data</string>
<string name="notification_history">Notification History</string>
<string name="notification_history_summary">History of Notifications (currently displays the last 25 notifications received)</string>
<string name="notification_message">Message</string>
<string name="notification_received_at">Notification Received At</string>
<string name="last_25_notifications">Last 25 Notifications</string>
<string name="no_notifications">No Notifications</string>
<string name="no_notifications_summary">You have not received any notifications yet</string>
<string name="other_settings">Other Settings</string>
<string name="password">Password</string>
<string name="permission_explanation">In order to use location tracking features or different connection urls based on WiFi SSID we need access to your location. If you want consistent background updates you will also need to allow background processing</string>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen
xmlns:app="http://schemas.android.com/apk/res-auto"
app:iconSpaceReserved="false">
<Preference
app:key="received_at"
app:title="@string/notification_received_at"
app:iconSpaceReserved="false"
app:enableCopying="true"/>
<Preference
app:key="message"
app:title="@string/notification_message"
app:iconSpaceReserved="false"
app:enableCopying="true" />
<Preference
app:key="data"
app:title="@string/notification_data"
app:iconSpaceReserved="false"
app:enableCopying="true" />
</androidx.preference.PreferenceScreen>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Preference
android:key="no_notifications"
android:title="@string/no_notifications"
android:summary="@string/no_notifications_summary"
android:selectable="false"
app:isPreferenceVisible="false" />
</androidx.preference.PreferenceScreen>

View file

@ -86,7 +86,15 @@
</Preference>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/app_version_info">
android:title="@string/notifications"
android:key="notifications"
app:isPreferenceVisible="false">
<Preference
android:key="notification_history"
app:isPreferenceVisible="false"
android:title="@string/notification_history"
android:icon="@drawable/ic_notification_history"
android:summary="@string/notification_history_summary" />
<Preference
android:key="notification_rate_limit"
android:title="@string/rate_limit_title"
@ -94,6 +102,9 @@
app:enableCopying="true"
android:icon="@drawable/ic_notifications"
android:summary="@string/rate_limit_summary"/>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/app_version_info">
<Preference
android:key="changelog"
android:icon="@drawable/ic_changelog"