Try another idea, add log fragment again

This commit is contained in:
frknkrc44 2025-08-23 05:30:15 +03:00
commit e435e5fb40
No known key found for this signature in database
GPG key ID: 784AE1CC0DCFD34F
19 changed files with 518 additions and 62 deletions

View file

@ -0,0 +1,82 @@
package icu.nullptr.hidemyapplist.ui.adapter
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import icu.nullptr.hidemyapplist.service.PrefManager
import icu.nullptr.hidemyapplist.ui.util.ThemeUtils.themeColor
import org.frknkrc44.hma_oss.R
import org.frknkrc44.hma_oss.databinding.LogItemViewBinding
import java.util.regex.Pattern
class LogAdapter(context: Context) : RecyclerView.Adapter<LogAdapter.ViewHolder>() {
class LogItem(
val level: String,
val date: String,
val tag: String,
val message: String
)
companion object {
private val pattern = Pattern.compile("\\[ ?(.*)] (.*) \\((.*)\\) (.*)", Pattern.DOTALL)
fun parseLog(text: String): LogItem? {
val matcher = pattern.matcher(text)
matcher.find()
val level = matcher.group(1) ?: return null
if (level == "DEBUG" && PrefManager.logFilter_level > 0 ||
level == "INFO" && PrefManager.logFilter_level > 1 ||
level == "WARN" && PrefManager.logFilter_level > 2
) return null
val date = matcher.group(2) ?: return null
val tag = matcher.group(3) ?: return null
val message = matcher.group(4) ?: return null
return LogItem(level, date, tag, message)
}
}
private val colorDebug = context.getColor(R.color.debug)
private val colorInfo = context.getColor(R.color.info)
private val colorWarn = context.getColor(R.color.warn)
private val colorError =
context.themeColor(android.R.attr.colorError)
var logs = listOf<LogItem>()
@SuppressLint("NotifyDataSetChanged")
set(value) {
field = value
notifyDataSetChanged()
}
inner class ViewHolder(private val binding: LogItemViewBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(logItem: LogItem) {
val color = when (logItem.level) {
"DEBUG" -> colorDebug
"INFO" -> colorInfo
"WARN" -> colorWarn
"ERROR" -> colorError
else -> throw IllegalArgumentException("Unknown level: ${logItem.level}")
}
binding.level.setBackgroundColor(color)
binding.level.text = logItem.level.substring(0, 1)
binding.date.text = logItem.date
binding.tag.text = logItem.tag
binding.message.text = logItem.message
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = LogItemViewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
override fun getItemCount() = logs.size
override fun getItemId(position: Int) = logs[position].hashCode().toLong()
override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.bind(logs[position])
}

View file

@ -0,0 +1,143 @@
package icu.nullptr.hidemyapplist.ui.fragment
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import by.kirich1409.viewbindingdelegate.viewBinding
import icu.nullptr.hidemyapplist.hmaApp
import icu.nullptr.hidemyapplist.service.PrefManager
import icu.nullptr.hidemyapplist.service.ServiceClient
import icu.nullptr.hidemyapplist.ui.adapter.LogAdapter
import icu.nullptr.hidemyapplist.ui.util.makeToast
import icu.nullptr.hidemyapplist.ui.util.navController
import icu.nullptr.hidemyapplist.ui.util.setupToolbar
import kotlinx.coroutines.launch
import org.frknkrc44.hma_oss.R
import org.frknkrc44.hma_oss.databinding.FragmentLogsBinding
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
class LogsFragment : Fragment(R.layout.fragment_logs) {
private val binding by viewBinding<FragmentLogsBinding>()
private val adapter by lazy { LogAdapter(requireContext()) }
private var logCache: String? = null
private val saveSAFLauncher =
registerForActivityResult(ActivityResultContracts.CreateDocument("text/x-log")) save@{ uri ->
if (uri == null) return@save
if (logCache.isNullOrEmpty()) {
makeToast(R.string.logs_empty)
return@save
}
hmaApp.contentResolver.openOutputStream(uri).use { output ->
if (output == null) makeToast(R.string.home_export_failed)
else output.write(logCache!!.toByteArray())
}
makeToast(R.string.logs_saved)
}
private fun updateLogs() {
lifecycleScope.launch {
logCache = ServiceClient.logs
val raw = logCache?.split("\n")
if (raw == null) {
binding.serviceOff.visibility = View.VISIBLE
} else {
binding.serviceOff.visibility = View.GONE
adapter.logs = buildList {
val cur = StringBuilder()
for (line in raw) {
if (line.startsWith('[')) {
if (cur.isNotEmpty()) {
val log = LogAdapter.parseLog(cur.toString())
if (log != null) add(log)
}
cur.clear()
}
cur.append(line)
}
if (cur.isNotEmpty()) {
val log = LogAdapter.parseLog(cur.toString())
if (log != null) add(log)
}
if (!PrefManager.logFilter_reverseOrder) reverse()
}
}
}
}
private fun onMenuOptionSelected(item: MenuItem) {
when (item.itemId) {
R.id.menu_refresh -> updateLogs()
R.id.menu_save -> {
val date = SimpleDateFormat("yyyy-MM-dd_HH.mm.ss", Locale.getDefault()).format(Date())
saveSAFLauncher.launch("hma_logs_$date.log")
}
R.id.menu_delete -> {
ServiceClient.clearLogs()
updateLogs()
}
R.id.menu_filter_debug -> {
item.isChecked = true
PrefManager.logFilter_level = 0
updateLogs()
}
R.id.menu_filter_info -> {
item.isChecked = true
PrefManager.logFilter_level = 1
updateLogs()
}
R.id.menu_filter_warn -> {
item.isChecked = true
PrefManager.logFilter_level = 2
updateLogs()
}
R.id.menu_filter_error -> {
item.isChecked = true
PrefManager.logFilter_level = 3
updateLogs()
}
R.id.menu_reverse_order -> {
item.isChecked = !item.isChecked
PrefManager.logFilter_reverseOrder = item.isChecked
updateLogs()
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
with(binding.toolbar) {
setupToolbar(
toolbar = this,
title = getString(R.string.title_logs),
menuRes = R.menu.menu_logs,
onMenuOptionSelected = this@LogsFragment::onMenuOptionSelected
)
setNavigationIcon(R.drawable.baseline_arrow_back_24)
setNavigationOnClickListener { navController.popBackStack() }
}
with(binding.toolbar.menu) {
when (PrefManager.logFilter_level) {
0 -> findItem(R.id.menu_filter_debug).isChecked = true
1 -> findItem(R.id.menu_filter_info).isChecked = true
2 -> findItem(R.id.menu_filter_warn).isChecked = true
3 -> findItem(R.id.menu_filter_error).isChecked = true
}
findItem(R.id.menu_reverse_order).isChecked = PrefManager.logFilter_reverseOrder
}
binding.list.layoutManager = LinearLayoutManager(context)
binding.list.adapter = adapter
binding.list.addItemDecoration(DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL))
updateLogs()
}
}

View file

@ -4,6 +4,7 @@ import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import android.view.WindowInsets
import androidx.appcompat.app.AppCompatDelegate
import androidx.fragment.app.Fragment
import androidx.preference.ListPreference
@ -20,6 +21,7 @@ import icu.nullptr.hidemyapplist.service.ConfigManager
import icu.nullptr.hidemyapplist.service.PrefManager
import icu.nullptr.hidemyapplist.service.ServiceClient
import icu.nullptr.hidemyapplist.ui.util.makeToast
import icu.nullptr.hidemyapplist.ui.util.navController
import icu.nullptr.hidemyapplist.ui.util.setupToolbar
import icu.nullptr.hidemyapplist.util.ConfigUtils.Companion.getLocale
import icu.nullptr.hidemyapplist.util.LangList
@ -33,13 +35,25 @@ class SettingsFragment : Fragment(R.layout.fragment_settings), PreferenceFragmen
private val binding by viewBinding<FragmentSettingsBinding>()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
setupToolbar(binding.toolbar, getString(R.string.title_settings))
with(binding.toolbar) {
setupToolbar(this, getString(R.string.title_settings))
setNavigationIcon(R.drawable.baseline_arrow_back_24)
setNavigationOnClickListener { navController.popBackStack() }
}
if (childFragmentManager.findFragmentById(R.id.settings_container) == null) {
childFragmentManager.beginTransaction()
.replace(R.id.settings_container, SettingsPreferenceFragment())
.commit()
}
val insets = binding.root.rootWindowInsets.getInsets(WindowInsets.Type.systemBars())
binding.settingsContainer.setPadding(
insets.left,
0,
insets.right,
insets.bottom,
)
}
override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, pref: Preference): Boolean {

View file

@ -1,18 +1,33 @@
package icu.nullptr.hidemyapplist.ui.util
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.annotation.DrawableRes
import androidx.annotation.IdRes
import androidx.annotation.MenuRes
import androidx.appcompat.widget.Toolbar
import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.navigation.NavOptions
import androidx.navigation.fragment.NavHostFragment
import org.frknkrc44.hma_oss.R
val Fragment.navController get() = NavHostFragment.findNavController(this)
fun Fragment.navigate(@IdRes resId: Int, args: Bundle? = null) {
val navOptions = NavOptions.Builder().apply {
setEnterAnim(R.anim.slide_in_right)
setExitAnim(R.anim.slide_out_left)
setPopEnterAnim(R.anim.slide_in_left)
setPopExitAnim(R.anim.slide_out_right)
}.build()
navController.navigate(resId, args, navOptions)
}
fun Fragment.setupToolbar(
toolbar: Toolbar,
title: String,

View file

@ -25,9 +25,6 @@ class MainActivity : AppCompatActivity() {
setContentView(binding.root)
DynamicColors.applyToActivityIfAvailable(this)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
setupWithNavController(binding.bottomNav, navController)
}
override fun onApplyThemeResource(theme: Resources.Theme, resid: Int, first: Boolean) {

View file

@ -6,6 +6,7 @@ import android.os.Bundle
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.NavHostFragment
import by.kirich1409.viewbindingdelegate.viewBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import icu.nullptr.hidemyapplist.hmaApp
@ -16,6 +17,8 @@ import icu.nullptr.hidemyapplist.ui.util.ThemeUtils.getColor
import icu.nullptr.hidemyapplist.ui.util.ThemeUtils.setCircleBackground
import icu.nullptr.hidemyapplist.ui.util.ThemeUtils.themeColor
import icu.nullptr.hidemyapplist.ui.util.makeToast
import icu.nullptr.hidemyapplist.ui.util.navController
import icu.nullptr.hidemyapplist.ui.util.navigate
import icu.nullptr.hidemyapplist.ui.util.setupToolbar
import org.frknkrc44.hma_oss.BuildConfig
import org.frknkrc44.hma_oss.R
@ -125,7 +128,7 @@ class HomeFragment : Fragment(R.layout.fragment_home) {
with(binding.howToUse) {
text1.text = getString(R.string.about_how_to_use_title)
itemIcon.setImageResource(R.drawable.outline_info_24)
itemIcon.setCircleBackground(getColor(R.color.info))
// itemIcon.setCircleBackground(getColor(R.color.info))
root.setOnClickListener {
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.about_how_to_use_title)
@ -141,13 +144,31 @@ class HomeFragment : Fragment(R.layout.fragment_home) {
with(binding.manageApps) {
text1.text = getString(R.string.title_app_manage)
itemIcon.setImageResource(R.drawable.outline_android_24)
itemIcon.setCircleBackground(getColor(R.color.warn))
// itemIcon.setCircleBackground(getColor(R.color.warn))
}
with(binding.manageTemplates) {
text1.text = getString(R.string.title_template_manage)
itemIcon.setImageResource(R.drawable.ic_outline_layers_24)
itemIcon.setCircleBackground(getColor(R.color.invalid))
// itemIcon.setCircleBackground(getColor(R.color.invalid))
}
with(binding.navLogs) {
text1.text = getString(R.string.title_logs)
itemIcon.setImageResource(R.drawable.outline_assignment_24)
// itemIcon.setCircleBackground(getColor(R.color.error))
root.setOnClickListener {
navigate(R.id.nav_logs)
}
}
with(binding.navSettings) {
text1.text = getString(R.string.title_settings)
itemIcon.setImageResource(R.drawable.outline_settings_24)
// itemIcon.setCircleBackground(getColor(R.color.gray))
root.setOnClickListener {
navigate(R.id.nav_settings)
}
}
binding.backupConfig.setOnClickListener {

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/res/anim/slide_in_left.xml
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-50%p" android:toXDelta="0"
android:duration="@android:integer/config_shortAnimTime" />
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_shortAnimTime" />
</set>

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/res/anim/slide_in_right.xml
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="50%p" android:toXDelta="0"
android:duration="@android:integer/config_shortAnimTime"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_shortAnimTime" />
</set>

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/res/anim/slide_out_left.xml
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="-50%p"
android:duration="@android:integer/config_shortAnimTime"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_shortAnimTime" />
</set>

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/res/anim/slide_out_right.xml
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="50%p"
android:duration="@android:integer/config_shortAnimTime"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_shortAnimTime" />
</set>

View file

@ -18,16 +18,8 @@
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/bottom_nav"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/main_nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:labelVisibilityMode="selected"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="@menu/menu_nav" />
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/home_nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -36,17 +36,41 @@
android:id="@+id/status_card"
layout="@layout/view_status_card" />
<include
android:id="@+id/how_to_use"
layout="@layout/view_home_item" />
<com.google.android.material.card.MaterialCardView
app:cardCornerRadius="24dp"
android:layout_marginHorizontal="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/manage_apps"
layout="@layout/view_home_item" />
<LinearLayout
android:orientation="vertical"
android:layout_marginVertical="16dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/manage_templates"
layout="@layout/view_home_item" />
<include
android:id="@+id/how_to_use"
layout="@layout/view_home_item" />
<include
android:id="@+id/manage_apps"
layout="@layout/view_home_item" />
<include
android:id="@+id/manage_templates"
layout="@layout/view_home_item" />
<include
android:id="@+id/nav_logs"
layout="@layout/view_home_item" />
<include
android:id="@+id/nav_settings"
layout="@layout/view_home_item" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<LinearLayout
android:layout_marginTop="16dp"

View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:elevation="0dp" />
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/service_off"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fontFamily="serif"
android:gravity="center"
android:text="@string/home_xposed_service_off"
android:textAppearance="?textAppearanceTitleLarge" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/level"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fontFamily="monospace"
android:gravity="center"
android:paddingHorizontal="4dp"
android:textAppearance="?textAppearanceTitleSmall"
android:textColor="@android:color/white"
tools:background="@color/info"
tools:text="I" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="6dp"
android:paddingVertical="4dp">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/tag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:textAppearance="?textAppearanceTitleSmall"
tools:text="HMA-Bridge" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="2dp"
android:fontFamily="monospace"
android:textAppearance="?textAppearanceBodySmall"
tools:text="HMA service initialized" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="serif"
android:textAppearance="?textAppearanceBodySmall"
tools:text="19-19 11:45:14" />
</LinearLayout>
</LinearLayout>

View file

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/home_nav_graph"
android:icon="@drawable/ic_home_checkable"
android:title="@string/title_home" />
<item
android:id="@+id/nav_logs"
android:icon="@drawable/ic_logs_checkable"
android:title="@string/title_logs" />
<item
android:id="@+id/nav_settings"
android:icon="@drawable/ic_settings_checkable"
android:title="@string/title_settings" />
</menu>

View file

@ -7,6 +7,17 @@
android:id="@+id/nav_home"
android:name="org.frknkrc44.hma_oss.ui.fragment.HomeFragment"
android:label="@string/title_home" />
<fragment
android:id="@+id/nav_logs"
android:name="icu.nullptr.hidemyapplist.ui.fragment.LogsFragment"
android:label="@string/title_logs" />
<fragment
android:id="@+id/nav_settings"
android:name="icu.nullptr.hidemyapplist.ui.fragment.SettingsFragment"
android:label="@string/title_settings" />
<!--
<fragment
android:id="@+id/nav_template_manage"

View file

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_nav_graph"
app:startDestination="@id/home_nav_graph">
<include app:graph="@navigation/home_nav_graph" />
<!--
<fragment
android:id="@+id/nav_logs"
android:name="icu.nullptr.hidemyapplist.ui.fragment.LogsFragment"
android:label="@string/title_logs" />
-->
<fragment
android:id="@+id/nav_settings"
android:name="icu.nullptr.hidemyapplist.ui.fragment.SettingsFragment"
android:label="@string/title_settings" />
</navigation>

View file

@ -5,4 +5,5 @@
<color name="debug">#000000</color>
<color name="info">#154A74</color>
<color name="warn">#375634</color>
<color name="error">#8F3232</color>
</resources>

View file

@ -186,7 +186,7 @@
<!-- Dark theme modes -->
<string name="dark_theme">Dark theme</string>
<string name="dark_theme_off">Off</string>
<string name="dark_theme_on">On</string>
<string name="dark_theme_off">Always off</string>
<string name="dark_theme_on">Always on</string>
<string name="dark_theme_follow_system">Follow system</string>
</resources>