Remove obsolete UI scaffolding

This commit is contained in:
ajp_anton
2026-09-03 00:49:14 +00:00
parent 99f999d4e0
commit 78bf4bde8c
9 changed files with 48 additions and 121 deletions
+2 -2
View File
@@ -41,8 +41,8 @@ android {
applicationId = "se.ajpanton.notificationsmaster"
minSdk = 34
targetSdk = 36
versionCode = project.findProperty("notificationLogVersionCode")?.toString()?.toIntOrNull() ?: 1
versionName = project.findProperty("notificationLogVersionName")?.toString() ?: "0.1"
versionCode = project.findProperty("notificationsMasterVersionCode")?.toString()?.toIntOrNull() ?: 1
versionName = project.findProperty("notificationsMasterVersionName")?.toString() ?: "0.1"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
+2 -2
View File
@@ -17,7 +17,7 @@
tools:ignore="QueryAllPackagesPermission" />
<application
android:name=".NotificationLogApplication"
android:name=".NotificationsMasterApplication"
android:allowBackup="false"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
@@ -25,7 +25,7 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/Theme.NotificationLog">
android:theme="@style/Theme.NotificationsMaster">
<activity
android:name=".MainActivity"
@@ -85,7 +85,6 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
refreshLogProtection(requestUnlock = hasWindowFocus())
syncDrawerSelection(currentItemId)
title = getString(page.titleRes)
binding.root.post(::applyPageTitleVisibility)
}
applyNavigationDrawerInsets()
syncDrawerToggle()
@@ -171,23 +170,21 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
supportFragmentManager.commit {
replace(
R.id.content_frame,
when {
page == Page.VIEW_LOGS -> ViewLogsFragment()
page == Page.SETTINGS -> SettingsFragment()
page == Page.ALERTS -> AlertsFragment()
page == Page.PROFILES -> ProfilesFragment()
page == Page.RULES -> RulesFragment()
page == Page.APPS -> AppsFragment()
page == Page.NOTIFICATION_VISIBILITY -> NotificationVisibilityFragment()
page == Page.CARDS_LAYOUT -> CardsLayoutFragment()
page == Page.MISCELLANEOUS -> MiscellaneousFragment()
page == Page.LOG_DISPLAY -> LogDisplayFragment()
page == Page.FILTER_LOGGING -> FilterLoggingFragment()
page == Page.FILTER_APPS -> FilterAppsFragment.newInstance()
else -> PageFragment.newInstance(page.titleRes)
when (page) {
Page.VIEW_LOGS -> ViewLogsFragment()
Page.SETTINGS -> SettingsFragment()
Page.ALERTS -> AlertsFragment()
Page.PROFILES -> ProfilesFragment()
Page.RULES -> RulesFragment()
Page.APPS -> AppsFragment()
Page.NOTIFICATION_VISIBILITY -> NotificationVisibilityFragment()
Page.CARDS_LAYOUT -> CardsLayoutFragment()
Page.MISCELLANEOUS -> MiscellaneousFragment()
Page.LOG_DISPLAY -> LogDisplayFragment()
Page.FILTER_LOGGING -> FilterLoggingFragment()
Page.FILTER_APPS -> FilterAppsFragment.newInstance()
},
)
runOnCommit(::applyPageTitleVisibility)
}
title = getString(page.titleRes)
invalidateOptionsMenu()
@@ -306,7 +303,6 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
}
updateNavigationHeaderHeight(binding.navViewDrawer)
updateNavigationHeaderHeight(binding.navViewPermanent)
applyPageTitleVisibility()
}
private fun updateNavigationHeaderHeight(navigationView: NavigationView) {
@@ -332,11 +328,6 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
return visible
}
private fun applyPageTitleVisibility() {
(supportFragmentManager.findFragmentById(R.id.content_frame) as? PageFragment)
?.setPageTitleVisible(permanentSidebar)
}
private fun syncDrawerToggle() {
drawerToggle.syncState()
drawerToggle.drawerArrowDrawable.color = getColor(R.color.on_primary)
@@ -9,12 +9,12 @@ import se.ajpanton.notificationsmaster.settings.NotificationListenerComponentCon
import se.ajpanton.notificationsmaster.settings.PerAppEventSettingsStore
import se.ajpanton.notificationsmaster.visibility.VisibilityPolicyStore
class NotificationLogApplication : Application() {
class NotificationsMasterApplication : Application() {
override fun onCreate() {
super.onCreate()
synchronizeListenerComponent()
VisibilityPolicySync.publishStored(this)
Thread(::removeStaleAppStorage, "notification-log-storage-cleanup").start()
Thread(::removeStaleAppStorage, "notifications-master-storage-cleanup").start()
}
/**
@@ -1,34 +0,0 @@
package se.ajpanton.notificationsmaster
import android.os.Bundle
import android.view.View
import androidx.annotation.StringRes
import androidx.fragment.app.Fragment
import se.ajpanton.notificationsmaster.databinding.FragmentPageBinding
class PageFragment : Fragment(R.layout.fragment_page) {
private var binding: FragmentPageBinding? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentPageBinding.bind(view)
binding?.pageTitle?.setText(requireArguments().getInt(ARG_TITLE))
}
override fun onDestroyView() {
binding = null
super.onDestroyView()
}
fun setPageTitleVisible(visible: Boolean) {
binding?.pageTitle?.visibility = if (visible) View.VISIBLE else View.GONE
}
companion object {
private const val ARG_TITLE = "title"
fun newInstance(@StringRes titleRes: Int) = PageFragment().apply {
arguments = Bundle().apply { putInt(ARG_TITLE, titleRes) }
}
}
}
@@ -45,7 +45,7 @@ import kotlinx.coroutines.withContext
class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
private var binding: FragmentViewLogsBinding? = null
private val expandedIds = mutableSetOf<String>()
private val rows = mutableListOf<LogRow>()
private val rows = mutableListOf<NotificationLogEntry>()
private var nextCursor: NewestLogCursor? = null
private var loading = false
private var noMoreRows = false
@@ -106,7 +106,7 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
nextCursor = page.nextCursor
noMoreRows = nextCursor == null
val visibleBefore = visibleRows(LogViewSettingsStore(requireContext()).load()).size
rows += page.entries.map(::LogRow)
rows += page.entries
binding?.let(::render)
val visibleAfter = visibleRows(LogViewSettingsStore(requireContext()).load()).size
val skipFilteredPage = appFilterStore.selectedPackages().isNotEmpty() &&
@@ -181,15 +181,15 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
loadLogs(reset = true)
}
private fun visibleRows(settings: LogViewSettings): List<LogRow> {
private fun visibleRows(settings: LogViewSettings): List<NotificationLogEntry> {
val selectedPackages = appFilterStore.selectedPackages()
return rows.filter { row ->
eventFor(row.entry.action) in settings.visibleEvents &&
(selectedPackages.isEmpty() || row.entry.packageName in selectedPackages)
return rows.filter { entry ->
eventFor(entry.action) in settings.visibleEvents &&
(selectedPackages.isEmpty() || entry.packageName in selectedPackages)
}
}
private fun logRowView(row: LogRow, settings: LogViewSettings, metadataColumnWidth: Int): View = LinearLayout(requireContext()).apply {
private fun logRowView(entry: NotificationLogEntry, settings: LogViewSettings, metadataColumnWidth: Int): View = LinearLayout(requireContext()).apply {
orientation = LinearLayout.HORIZONTAL
gravity = android.view.Gravity.TOP
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT).apply {
@@ -198,14 +198,14 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
fun renderExpanded(expanded: Boolean) {
removeAllViews()
val metadata = metadataValues(row.entry, settings)
val contents = fieldValue(LogField.CONTENTS, row.entry, settings)
val metadata = metadataValues(entry, settings)
val contents = entry.contents
val hasContents = LogField.CONTENTS in settings.visibleFields && !contents.isNullOrEmpty()
val toggleExpanded = {
val collapsing = expanded
val collapseAnchor = if (collapsing) captureCollapseAnchor(this@apply) else null
if (!expandedIds.add(row.entry.id)) expandedIds.remove(row.entry.id)
renderExpanded(row.entry.id in expandedIds)
if (!expandedIds.add(entry.id)) expandedIds.remove(entry.id)
renderExpanded(entry.id in expandedIds)
if (collapsing) {
val highlight = { highlightCollapsedRow(this@apply) }
if (collapseAnchor != null) {
@@ -216,7 +216,7 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
}
Unit
}
val metadataCell = metadataCell(metadata, expanded, toggleExpanded, row.entry.id).apply {
val metadataCell = metadataCell(metadata, expanded, toggleExpanded, entry.id).apply {
layoutParams = LinearLayout.LayoutParams(
if (hasContents) metadataColumnWidth else LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT,
@@ -226,7 +226,7 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
}
if (metadata.isNotEmpty()) addView(metadataCell)
if (hasContents) {
val contentsCell = contentsCell(row, contents!!, metadata.size.coerceAtLeast(1), expanded, toggleExpanded).apply {
val contentsCell = contentsCell(entry, contents!!, metadata.size.coerceAtLeast(1), expanded, toggleExpanded).apply {
layoutParams = LinearLayout.LayoutParams(
if (metadata.isNotEmpty()) 0 else LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT,
@@ -237,9 +237,9 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
}
}
renderExpanded(row.entry.id in expandedIds)
renderExpanded(entry.id in expandedIds)
setOnLongClickListener {
showDeleteDialog(row.entry.id)
showDeleteDialog(entry.id)
}
}
@@ -273,7 +273,7 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
}
private fun contentsCell(
row: LogRow,
entry: NotificationLogEntry,
contents: String,
collapsedLines: Int,
expanded: Boolean,
@@ -290,15 +290,15 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
setLineSpacing(0f, 1f)
}
addView(message)
if (expanded && row.entry.action == NotificationAction.EDITED && !row.entry.previousContents.isNullOrEmpty()) {
if (expanded && entry.action == NotificationAction.EDITED && !entry.previousContents.isNullOrEmpty()) {
addView(previousDivider())
addView(TextView(context).apply {
text = row.entry.previousContents
text = entry.previousContents
setLineSpacing(0f, 1f)
})
}
if (expanded && row.entry.imageId != null) {
val imageId = row.entry.imageId
if (expanded && entry.imageId != null) {
val imageId = entry.imageId
val appContext = requireContext().applicationContext
val contentsContainer = this
viewLifecycleOwner.lifecycleScope.launch {
@@ -324,7 +324,7 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
}
}
setOnClickListener { onToggleExpanded() }
setOnLongClickListener { showDeleteDialog(row.entry.id) }
setOnLongClickListener { showDeleteDialog(entry.id) }
}
private fun previousDivider(): LinearLayout = LinearLayout(requireContext()).apply {
@@ -352,14 +352,6 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
if (LogField.ACTION in settings.visibleFields) add(MetadataValue(actionLabel(entry.action), 14f, indented = true))
}
private fun fieldValue(field: LogField, entry: NotificationLogEntry, settings: LogViewSettings): String? = when (field) {
LogField.TIMESTAMP -> timestamp(entry.recordedAtEpochMillis, settings, entry.eventTimeZoneId)
LogField.APP_NAME -> entry.appName
LogField.PACKAGE_NAME -> entry.packageName
LogField.ACTION -> actionLabel(entry.action)
LogField.CONTENTS -> entry.contents
}
private fun actionLabel(action: NotificationAction): String = when (action) {
NotificationAction.APPEARED -> "Appeared"
NotificationAction.ALREADY_ACTIVE -> "Already active"
@@ -382,8 +374,8 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
.getSystemService(NotificationManager::class.java)
.isNotificationListenerAccessGranted(ComponentName(requireContext(), NotificationCaptureService::class.java))
private fun metadataColumnWidth(availableWidth: Int, rows: List<LogRow>, settings: LogViewSettings): Int {
val values = rows.flatMap { metadataValues(it.entry, settings) }
private fun metadataColumnWidth(availableWidth: Int, rows: List<NotificationLogEntry>, settings: LogViewSettings): Int {
val values = rows.flatMap { metadataValues(it, settings) }
val widestTimestamp = values.filter { it.isTimestamp }
.maxOfOrNull(::metadataTextWidth)
?: 0
@@ -418,11 +410,11 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
}
private inner class LogAdapter : RecyclerView.Adapter<LogAdapter.Holder>() {
private var rows: List<LogRow> = emptyList()
private var rows: List<NotificationLogEntry> = emptyList()
private var settings = LogViewSettings()
private var metadataWidth = 0
fun submit(rows: List<LogRow>, settings: LogViewSettings, metadataWidth: Int) {
fun submit(rows: List<NotificationLogEntry>, settings: LogViewSettings, metadataWidth: Int) {
val previous = this.rows
this.rows = rows
this.settings = settings
@@ -431,7 +423,7 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
override fun getOldListSize() = previous.size
override fun getNewListSize() = rows.size
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) =
previous[oldItemPosition].entry.id == rows[newItemPosition].entry.id
previous[oldItemPosition].id == rows[newItemPosition].id
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) =
previous[oldItemPosition] == rows[newItemPosition]
}).dispatchUpdatesTo(this)
@@ -547,7 +539,6 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
resources.displayMetrics,
)
private data class LogRow(val entry: NotificationLogEntry)
private data class LoggedApp(val name: String, val packageName: String)
private data class MetadataValue(
val text: String,
@@ -567,7 +558,6 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
private companion object {
const val SCROLL_TO_TOP_THRESHOLD_DP = 120
const val LOAD_MORE_THRESHOLD_DP = 480
const val PAGE_SIZE = 80
const val IMAGE_VIEWER_TAG = "image-viewer"
const val MINIMUM_METADATA_COLUMN_DP = 120
+1 -1
View File
@@ -39,7 +39,7 @@
android:layout_height="wrap_content"
android:background="@color/primary"
android:elevation="0dp"
android:theme="@style/ThemeOverlay.NotificationLog.Toolbar"
android:theme="@style/ThemeOverlay.NotificationsMaster.Toolbar"
android:layout_alignParentTop="true"
app:navigationIconTint="@color/on_primary"
app:titleTextColor="@color/on_primary" />
-20
View File
@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/page_padding">
<TextView
android:id="@+id/page_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?attr/textAppearanceHeadline5"
android:textColor="?attr/colorOnBackground" />
</LinearLayout>
</ScrollView>
+2 -2
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.NotificationLog" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<style name="Theme.NotificationsMaster" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="colorPrimary">@color/primary</item>
<item name="colorOnPrimary">@color/on_primary</item>
<item name="colorSurface">@color/surface</item>
@@ -12,5 +12,5 @@
<item name="android:windowLightNavigationBar">true</item>
</style>
<style name="ThemeOverlay.NotificationLog.Toolbar" parent="ThemeOverlay.MaterialComponents.Dark.ActionBar" />
<style name="ThemeOverlay.NotificationsMaster.Toolbar" parent="ThemeOverlay.MaterialComponents.Dark.ActionBar" />
</resources>