Improve dashboard

This commit is contained in:
世界 2024-03-12 13:59:24 +08:00
parent f0acb0999b
commit 096d5ef43d
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
45 changed files with 507 additions and 272 deletions

View file

@ -103,7 +103,7 @@ dependencies {
implementation "androidx.preference:preference-ktx:1.2.1"
ksp "androidx.room:room-compiler:2.6.1"
implementation "androidx.work:work-runtime-ktx:2.9.0"
implementation "androidx.browser:browser:1.7.0"
implementation "androidx.browser:browser:1.8.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0"
// DO NOT UPDATE (minSdkVersion updated)

View file

@ -26,7 +26,7 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:theme="@style/Theme.Material3.DayNight"
tools:targetApi="31">
<meta-data
@ -37,6 +37,7 @@
android:name=".ui.MainActivity"
android:exported="true"
android:icon="@mipmap/ic_launcher"
android:theme="@style/Theme.Material3.DayNight.NoActionBar"
android:launchMode="singleTask">
<meta-data

View file

@ -14,12 +14,17 @@ import androidx.activity.result.contract.ActivityResultContract
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
import androidx.navigation.NavDestination
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import io.nekohasekai.libbox.Libbox
import io.nekohasekai.libbox.ProfileContent
@ -38,6 +43,7 @@ import io.nekohasekai.sfa.databinding.ActivityMainBinding
import io.nekohasekai.sfa.ktx.errorDialogBuilder
import io.nekohasekai.sfa.ktx.hasPermission
import io.nekohasekai.sfa.ui.profile.NewProfileActivity
import io.nekohasekai.sfa.ui.settings.CoreFragment
import io.nekohasekai.sfa.ui.shared.AbstractActivity
import io.nekohasekai.sfa.vendor.Vendor
import kotlinx.coroutines.Dispatchers
@ -47,13 +53,15 @@ import java.io.File
import java.util.Date
import java.util.LinkedList
class MainActivity : AbstractActivity(), ServiceConnection.Callback {
class MainActivity : AbstractActivity(),
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback,
ServiceConnection.Callback {
companion object {
private const val TAG = "MainActivity"
}
private lateinit var binding: ActivityMainBinding
internal lateinit var binding: ActivityMainBinding
private val connection = ServiceConnection(this, this)
val logList = LinkedList<String>()
@ -65,9 +73,12 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback {
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
val navController = findNavController(R.id.nav_host_fragment_activity_my)
navController.setGraph(R.navigation.mobile_navigation)
navController.navigate(R.id.navigation_dashboard)
navController.addOnDestinationChangedListener(::onDestinationChanged)
val appBarConfiguration =
AppBarConfiguration(
setOf(
@ -86,6 +97,31 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback {
onNewIntent(intent)
}
private fun onDestinationChanged(
navController: NavController,
navDestination: NavDestination,
bundle: Bundle?
) {
val destinationId = navDestination.id
binding.dashboardTabContainer.isVisible = destinationId == R.id.navigation_dashboard
}
override fun onPreferenceStartFragment(
caller: PreferenceFragmentCompat,
pref: Preference
): Boolean {
val navController = findNavController(R.id.nav_host_fragment_activity_my)
when (pref.fragment) {
CoreFragment::class.java.name -> {
navController.navigate(R.id.navigation_settings_core)
return true
}
else -> return false
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
val uri = intent.data ?: return
@ -445,4 +481,5 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback {
super.onDestroy()
}
}

View file

@ -12,7 +12,6 @@ import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SimpleItemAnimator
@ -133,6 +132,8 @@ class GroupsFragment : Fragment(), CommandClient.Handler {
lateinit var group: OutboundGroup
lateinit var items: MutableList<OutboundGroupItem>
lateinit var adapter: ItemAdapter
@SuppressLint("NotifyDataSetChanged")
fun bind(group: OutboundGroup) {
this.group = group
binding.groupName.text = group.tag
@ -153,10 +154,23 @@ class GroupsFragment : Fragment(), CommandClient.Handler {
while (itemIterator.hasNext()) {
items.add(itemIterator.next())
}
adapter = ItemAdapter(this, group, items)
binding.itemList.adapter = adapter
(binding.itemList.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
binding.itemList.layoutManager = GridLayoutManager(binding.root.context, 2)
if (!::adapter.isInitialized) {
adapter = ItemAdapter(this, group, items)
binding.itemList.adapter = adapter
/* val divider =
MaterialDividerItemDecoration(
binding.root.context,
LinearLayoutManager.VERTICAL
)
divider.isLastItemDecorated = false
binding.itemList.addItemDecoration(divider)*/
(binding.itemList.itemAnimator as SimpleItemAnimator).supportsChangeAnimations =
false
binding.itemList.layoutManager = LinearLayoutManager(binding.root.context)
} else {
adapter.items = items
adapter.notifyDataSetChanged()
}
updateExpand()
}
@ -220,7 +234,7 @@ class GroupsFragment : Fragment(), CommandClient.Handler {
private class ItemAdapter(
val groupView: GroupView,
val group: OutboundGroup,
val items: List<OutboundGroupItem>
var items: List<OutboundGroupItem> = emptyList()
) :
RecyclerView.Adapter<ItemGroupView>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemGroupView {

View file

@ -70,42 +70,20 @@ class OverviewFragment : Fragment() {
Status.Stopped -> {
binding.clashModeCard.isVisible = false
binding.systemProxyCard.isVisible = false
binding.fab.setImageResource(R.drawable.ic_play_arrow_24)
binding.fab.show()
}
Status.Starting -> {
binding.fab.hide()
}
Status.Started -> {
statusClient.connect()
clashModeClient.connect()
reloadSystemProxyStatus()
binding.fab.setImageResource(R.drawable.ic_stop_24)
binding.fab.show()
}
Status.Stopping -> {
binding.fab.hide()
}
else -> {}
}
}
binding.fab.setOnClickListener {
when (activity.serviceStatus.value) {
Status.Stopped -> {
activity.startService()
}
Status.Started -> {
BoxService.stop()
}
else -> {}
}
}
ProfileManager.registerCallback(this::updateProfiles)
}

View file

@ -10,6 +10,7 @@ import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.google.android.material.tabs.TabLayoutMediator
import io.nekohasekai.sfa.R
import io.nekohasekai.sfa.bg.BoxService
import io.nekohasekai.sfa.constant.Status
import io.nekohasekai.sfa.databinding.FragmentDashboardBinding
import io.nekohasekai.sfa.ui.MainActivity
@ -20,6 +21,7 @@ class DashboardFragment : Fragment(R.layout.fragment_dashboard) {
private val activity: MainActivity? get() = super.getActivity() as MainActivity?
private var binding: FragmentDashboardBinding? = null
private var mediator: TabLayoutMediator? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
@ -34,21 +36,46 @@ class DashboardFragment : Fragment(R.layout.fragment_dashboard) {
val binding = binding ?: return
binding.dashboardPager.adapter = Adapter(this)
binding.dashboardPager.offscreenPageLimit = Page.values().size
TabLayoutMediator(binding.dashboardTabLayout, binding.dashboardPager) { tab, position ->
mediator = TabLayoutMediator(
activity.binding.dashboardTabLayout,
binding.dashboardPager
) { tab, position ->
tab.setText(Page.values()[position].titleRes)
}.attach()
}.apply { attach() }
activity.serviceStatus.observe(viewLifecycleOwner) {
when (it) {
Status.Stopped -> {
disablePager()
binding.fab.setImageResource(R.drawable.ic_play_arrow_24)
binding.fab.show()
}
Status.Starting -> {
binding.fab.hide()
}
Status.Started -> {
enablePager()
binding.fab.setImageResource(R.drawable.ic_stop_24)
binding.fab.show()
}
Status.Stopping -> {
disablePager()
binding.fab.hide()
}
else -> {}
}
}
binding.fab.setOnClickListener {
when (activity.serviceStatus.value) {
Status.Stopped -> {
activity.startService()
}
Status.Started -> {
BoxService.stop()
}
else -> {}
@ -58,18 +85,21 @@ class DashboardFragment : Fragment(R.layout.fragment_dashboard) {
override fun onDestroyView() {
super.onDestroyView()
mediator?.detach()
binding = null
}
private fun enablePager() {
val activity = activity ?: return
val binding = binding ?: return
binding.dashboardTabLayout.isVisible = true
activity.binding.dashboardTabLayout.isVisible = true
binding.dashboardPager.isUserInputEnabled = true
}
private fun disablePager() {
val activity = activity ?: return
val binding = binding ?: return
binding.dashboardTabLayout.isVisible = false
activity.binding.dashboardTabLayout.isVisible = false
binding.dashboardPager.isUserInputEnabled = false
binding.dashboardPager.setCurrentItem(0, false)
}

View file

@ -0,0 +1,9 @@
package io.nekohasekai.sfa.ui.main
import io.nekohasekai.sfa.R
import io.nekohasekai.sfa.ui.settings.AbstractSettingsFragment
class SettingsFragment0 : AbstractSettingsFragment(R.xml.preferences_settings) {
}

View file

@ -0,0 +1,27 @@
package io.nekohasekai.sfa.ui.settings
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.annotation.XmlRes
import androidx.preference.PreferenceFragmentCompat
import androidx.recyclerview.widget.RecyclerView
import io.nekohasekai.sfa.R
open class AbstractSettingsFragment(@XmlRes val resId: Int) : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(resId, rootKey)
}
override fun onCreateRecyclerView(
inflater: LayoutInflater,
parent: ViewGroup,
savedInstanceState: Bundle?
): RecyclerView {
val recyclerView = inflater
.inflate(R.layout.view_prefenence_screen, parent, false) as RecyclerView
recyclerView.layoutManager = onCreateLayoutManager()
return recyclerView
}
}

View file

@ -0,0 +1,6 @@
package io.nekohasekai.sfa.ui.settings
import androidx.fragment.app.Fragment
class CoreFragment : Fragment() {
}

View file

@ -0,0 +1,45 @@
package io.nekohasekai.sfa.ui.settings
import android.content.Context
import android.util.AttributeSet
import android.util.TypedValue
import androidx.preference.Preference
import io.nekohasekai.sfa.ktx.getAttrColor
class Preference : Preference {
constructor(
context: Context,
attrs: AttributeSet?,
defStyleAttr: Int,
defStyleRes: Int
) : super(context, attrs, defStyleAttr, defStyleRes) {
icon?.setTint(context.getAttrColor(com.google.android.material.R.attr.colorOnSurface))
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : this(
context,
attrs,
defStyleAttr,
0
)
constructor(context: Context, attrs: AttributeSet?) : this(
context, attrs, getAttr(
context, androidx.preference.R.attr.preferenceStyle,
android.R.attr.preferenceStyle
)
)
companion object {
private fun getAttr(context: Context, attr: Int, fallbackAttr: Int): Int {
val value = TypedValue()
context.theme.resolveAttribute(attr, value, true)
if (value.resourceId != 0) {
return attr
}
return fallbackAttr
}
}
}

View file

@ -5,7 +5,6 @@ import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.content.res.AppCompatResources
import com.google.android.material.color.DynamicColors
import com.google.android.material.elevation.SurfaceColors
import io.nekohasekai.sfa.R
import io.nekohasekai.sfa.ktx.getAttrColor
@ -16,9 +15,10 @@ abstract class AbstractActivity : AppCompatActivity() {
DynamicColors.applyToActivityIfAvailable(this)
val color = SurfaceColors.SURFACE_2.getColor(this)
window.statusBarColor = color
window.navigationBarColor = color
val colorSurfaceContainer =
getAttrColor(com.google.android.material.R.attr.colorSurfaceContainer)
window.statusBarColor = colorSurfaceContainer
window.navigationBarColor = colorSurfaceContainer
supportActionBar?.setHomeAsUpIndicator(AppCompatResources.getDrawable(
this@AbstractActivity,

View file

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
<vector android:height="24dp"
android:tint="#000000"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="@android:color/white"
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z" />
</vector>

View file

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M14.69,2.21L4.33,11.49c-0.64,0.58 -0.28,1.65 0.58,1.73L13,14l-4.85,6.76c-0.22,0.31 -0.19,0.74 0.08,1.01h0c0.3,0.3 0.77,0.31 1.08,0.02l10.36,-9.28c0.64,-0.58 0.28,-1.65 -0.58,-1.73L11,10l4.85,-6.76c0.22,-0.31 0.19,-0.74 -0.08,-1.01l0,0C15.47,1.93 15,1.92 14.69,2.21z"/>
<vector android:height="24dp"
android:tint="#000000"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="@android:color/white"
android:pathData="M14.69,2.21L4.33,11.49c-0.64,0.58 -0.28,1.65 0.58,1.73L13,14l-4.85,6.76c-0.22,0.31 -0.19,0.74 0.08,1.01h0c0.3,0.3 0.77,0.31 1.08,0.02l10.36,-9.28c0.64,-0.58 0.28,-1.65 -0.58,-1.73L11,10l4.85,-6.76c0.22,-0.31 0.19,-0.74 -0.08,-1.01l0,0C15.47,1.93 15,1.92 14.69,2.21z" />
</vector>

View file

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,8l-6,6 1.41,1.41L12,10.83l4.59,4.58L18,14z"/>
<vector android:height="24dp"
android:tint="#000000"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="@android:color/white"
android:pathData="M12,8l-6,6 1.41,1.41L12,10.83l4.59,4.58L18,14z" />
</vector>

View file

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"/>
<vector android:height="24dp"
android:tint="#000000"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="@android:color/white"
android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z" />
</vector>

View file

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M20,19.59V8l-6,-6H6c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2 1.99,2H18c0.45,0 0.85,-0.15 1.19,-0.4l-4.43,-4.43c-0.8,0.52 -1.74,0.83 -2.76,0.83 -2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5c0,1.02 -0.31,1.96 -0.83,2.75L20,19.59zM9,13c0,1.66 1.34,3 3,3s3,-1.34 3,-3 -1.34,-3 -3,-3 -3,1.34 -3,3z"/>
<vector android:height="24dp"
android:tint="#000000"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="@android:color/white"
android:pathData="M20,19.59V8l-6,-6H6c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2 1.99,2H18c0.45,0 0.85,-0.15 1.19,-0.4l-4.43,-4.43c-0.8,0.52 -1.74,0.83 -2.76,0.83 -2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5c0,1.02 -0.31,1.96 -0.83,2.75L20,19.59zM9,13c0,1.66 1.34,3 3,3s3,-1.34 3,-3 -1.34,-3 -3,-3 -3,1.34 -3,3z" />
</vector>

View file

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M16,5l-1.42,1.42 -1.59,-1.59L12.99,16h-1.98L11.01,4.83L9.42,6.42 8,5l4,-4 4,4zM20,10v11c0,1.1 -0.9,2 -2,2L6,23c-1.11,0 -2,-0.9 -2,-2L4,10c0,-1.11 0.89,-2 2,-2h3v2L6,10v11h12L18,10h-3L15,8h3c1.1,0 2,0.89 2,2z"/>
<vector android:height="24dp"
android:tint="#000000"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="@android:color/white"
android:pathData="M16,5l-1.42,1.42 -1.59,-1.59L12.99,16h-1.98L11.01,4.83L9.42,6.42 8,5l4,-4 4,4zM20,10v11c0,1.1 -0.9,2 -2,2L6,23c-1.11,0 -2,-0.9 -2,-2L4,10c0,-1.11 0.89,-2 2,-2h3v2L6,10v11h12L18,10h-3L15,8h3c1.1,0 2,0.89 2,2z" />
</vector>

View file

@ -1,5 +1,11 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#000000" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM18,14L6,14v-2h12v2zM18,11L6,11L6,9h12v2zM18,8L6,8L6,6h12v2z"/>
<vector android:autoMirrored="true"
android:height="24dp"
android:tint="#000000"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="@android:color/white"
android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM18,14L6,14v-2h12v2zM18,11L6,11L6,9h12v2zM18,8L6,8L6,6h12v2z" />
</vector>

View file

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
<vector android:height="24dp"
android:tint="#000000"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="@android:color/white"
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" />
</vector>

View file

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z"/>
<vector android:height="24dp"
android:tint="#000000"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="@android:color/white"
android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z" />
</vector>

View file

@ -5,10 +5,53 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorSurfaceContainer"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
style="?attr/toolbarStyle"
android:layout_width="match_parent"
android:layout_height="?actionBarSize" />
<LinearLayout
android:id="@+id/dashboardTabContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.tabs.TabLayout
android:id="@+id/dashboardTabLayout"
style="@style/Widget.Material3.TabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
app:tabIndicatorFullWidth="false"
app:tabUnboundedRipple="true">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_overview" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_groups" />
</com.google.android.material.tabs.TabLayout>
</LinearLayout>
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<fragment
android:id="@+id/nav_host_fragment_activity_my"
@ -16,14 +59,12 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:defaultNavHost="true"
app:navGraph="@navigation/mobile_navigation" />
app:defaultNavHost="true" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
app:menu="@menu/bottom_nav_menu" />
</LinearLayout>

View file

@ -25,10 +25,9 @@
</RadioGroup>
<View
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/divider" />
android:layout_height="1dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_app_list"

View file

@ -5,18 +5,18 @@
android:orientation="vertical">
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/scanVPNProgress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true" />
android:id="@+id/scanVPNProgress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/scanVPNResult"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingBottom="16dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/scanVPNResult"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingBottom="16dp" />
</LinearLayout>

View file

@ -36,9 +36,6 @@
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:backgroundTint="@color/blue_grey_600"
android:text="@string/title_new_profile"
android:textColor="@android:color/white"
app:icon="@drawable/ic_note_add_24"
app:iconTint="@android:color/white" />

View file

@ -6,41 +6,18 @@
android:layout_height="match_parent"
tools:context=".ui.main.DashboardFragment">
<LinearLayout
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/dashboardPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center|top"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/dashboardTabLayout"
style="@style/Widget.Material3.TabLayout.Secondary"
android:background="?android:attr/windowBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabUnboundedRipple="true"
app:tabIndicatorFullWidth="true">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_overview" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_groups" />
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/dashboardPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:saveEnabled="false" />
</LinearLayout>
android:saveEnabled="false" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
app:srcCompat="@drawable/ic_play_arrow_24" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -16,7 +15,6 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp" />
android:layout_height="match_parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -1,6 +1,5 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -17,21 +16,18 @@
<androidx.core.widget.NestedScrollView
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:padding="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical"
android:padding="16dp">
android:orientation="vertical">
<LinearLayout
android:id="@+id/statusContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
@ -39,7 +35,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:layout_marginBottom="8dp"
android:orientation="horizontal">
<com.google.android.material.card.MaterialCardView
@ -65,7 +61,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:orientation="horizontal">
<TextView
@ -155,7 +151,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:orientation="horizontal">
<TextView
@ -225,8 +221,7 @@
android:id="@+id/trafficContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:clipChildren="false"
android:layout_marginBottom="16dp"
android:orientation="horizontal"
android:visibility="gone"
tools:visibility="visible">
@ -254,7 +249,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:orientation="horizontal">
<TextView
@ -344,7 +339,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:orientation="horizontal">
<TextView
@ -416,7 +411,7 @@
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:visibility="gone"
tools:visibility="visible">
@ -441,11 +436,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="false"
android:orientation="horizontal"
android:padding="8dp"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="3"
tools:itemCount="3"
tools:listitem="@layout/view_clash_mode_button" />
</LinearLayout>
@ -456,7 +448,7 @@
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:visibility="gone"
tools:visibility="visible">
@ -482,8 +474,7 @@
android:id="@+id/profileCard"
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
@ -518,14 +509,4 @@
</androidx.core.widget.NestedScrollView>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:backgroundTint="@color/blue_grey_600"
app:srcCompat="@drawable/ic_play_arrow_24"
app:tint="@android:color/white" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -36,9 +36,7 @@
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:backgroundTint="@color/blue_grey_600"
app:srcCompat="@drawable/ic_play_arrow_24"
app:tint="@android:color/white" />
app:srcCompat="@drawable/ic_play_arrow_24" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -11,19 +11,18 @@
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
android:id="@+id/drag_handle"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:paddingTop="16dp"
android:id="@+id/qr_code"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
android:id="@+id/drag_handle"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:paddingTop="16dp"
android:id="@+id/qr_code"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>

View file

@ -19,7 +19,7 @@
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
android:layout_marginBottom="16dp">
<LinearLayout
android:layout_width="match_parent"
@ -29,6 +29,7 @@
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -99,7 +100,7 @@
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
android:layout_marginBottom="16dp">
<LinearLayout
android:layout_width="match_parent"
@ -205,7 +206,7 @@
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:visibility="gone"
tools:visibility="visible">
@ -263,7 +264,7 @@
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
android:layout_marginBottom="16dp">
<LinearLayout
android:layout_width="match_parent"
@ -311,7 +312,7 @@
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
android:layout_marginBottom="16dp">
<LinearLayout
android:layout_width="match_parent"
@ -359,7 +360,7 @@
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
android:layout_marginBottom="16dp">
<LinearLayout
android:layout_width="match_parent"

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -4,70 +4,87 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:orientation="vertical"
android:padding="16dp">
<LinearLayout
<com.google.android.material.card.MaterialCardView
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
android:layout_height="wrap_content">
<TextView
android:id="@+id/groupName"
style="?attr/textAppearanceTitleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="Group Name" />
<TextView
android:id="@+id/groupType"
style="?attr/textAppearanceBodyLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
tools:text="Group Name" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:orientation="horizontal">
android:orientation="vertical"
android:padding="16dp">
<ImageButton
android:id="@+id/expandButton"
android:layout_width="wrap_content"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:backgroundTint="?colorSurface"
android:contentDescription="@string/expand"
android:src="@drawable/ic_expand_less_24"
app:tint="?colorControlNormal" />
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageButton
android:id="@+id/urlTestButton"
android:layout_width="wrap_content"
<TextView
android:id="@+id/groupName"
style="?attr/textAppearanceTitleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="Group Name" />
<TextView
android:id="@+id/groupType"
style="?attr/textAppearanceBodyLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
tools:text="Group Name" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:orientation="horizontal">
<ImageButton
android:id="@+id/expandButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:backgroundTint="?colorSurfaceContainerLow"
android:contentDescription="@string/expand"
android:src="@drawable/ic_expand_less_24"
app:tint="?colorControlNormal" />
<ImageButton
android:id="@+id/urlTestButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:backgroundTint="?colorSurfaceContainerLow"
android:contentDescription="@string/urltest"
android:src="@drawable/ic_electric_bolt_24"
app:tint="?colorControlNormal" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/itemText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:backgroundTint="?colorSurface"
android:contentDescription="@string/urltest"
android:src="@drawable/ic_electric_bolt_24"
app:tint="?colorControlNormal" />
android:paddingEnd="56dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/itemList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
tools:listitem="@layout/view_dashboard_group_item" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/itemText"
android:layout_width="match_parent"
android:paddingEnd="56dp"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/itemList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" />
</com.google.android.material.card.MaterialCardView>
</LinearLayout>

View file

@ -1,11 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/item_card"
style="?materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp">
app:cardBackgroundColor="?colorSurfaceContainer"
app:cardCornerRadius="0dp"
app:cardElevation="0dp">
<LinearLayout
android:layout_width="match_parent"

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recycler_view"
style="?attr/preferenceFragmentListStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingTop="0dp"
android:paddingBottom="0dp" />

View file

@ -29,9 +29,10 @@
android:label="@string/title_settings"
tools:layout="@layout/fragment_settings" />
<!--<fragment
android:id="@+id/navigation_settings"
android:name="io.nekohasekai.sfa.ui.main.SettingsFragment"
android:label="@string/title_settings" />-->
<fragment
android:id="@+id/navigation_settings_core"
android:name="io.nekohasekai.sfa.ui.settings.CoreFragment"
android:label="@string/settings_title_core"
tools:layout="@layout/fragment_settings_core" />
</navigation>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="divider">#565656</color>
</resources>

View file

@ -1,7 +0,0 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="AppTheme" parent="Theme.Material3.DayNight">
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
<item name="colorPrimaryContainer">@color/blue_grey_600</item>
</style>
</resources>

View file

@ -11,6 +11,4 @@
<color name="log_red_light">#e91e63</color>
<color name="log_blue_light">#00a6b2</color>
<color name="log_white">#ececec</color>
<color name="divider">#cfcfcf</color>
</resources>

View file

@ -150,4 +150,7 @@
<string name="location_permission_description"><![CDATA[Your profile contains <strong><tt>wifi_ssid</tt> or <tt>wifi_bssid</tt> routing rules</strong>. To make them work, sing-box uses the <strong>location</strong> permission <strong>in the background</strong> to get information about the connected Wi-Fi network. The information will be used <strong>for routing purposes only</strong>.]]></string>
<string name="location_permission_background_description"><![CDATA[On Android 10 and up, <strong>background location</strong> permission is required. Select <strong>Allow all the time</strong> to grant the permission.]]></string>
<string name="open_settings">Open Settings</string>
<string name="settings_title_core">Core</string>
</resources>

View file

@ -1,8 +1,4 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="AppTheme" parent="Theme.Material3.DayNight">
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
</style>
<resources>
<style name="AppTheme.Translucent" parent="Theme.Material3.DayNight.Dialog.Alert">
<item name="android:background">@android:color/transparent</item>

View file

@ -1,8 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<include domain="database" path="profiles.db" />
<include domain="database" path="settings.db" />
<include domain="file" path="configs" />
<include
domain="database"
path="profiles.db" />
<include
domain="database"
path="settings.db" />
<include
domain="file"
path="configs" />
</full-backup-content>

View file

@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<paths>
<cache-path name="cache" path="/"/>
<cache-path
name="cache"
path="/" />
</paths>

View file

@ -1,13 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
<cloud-backup>
<include domain="database" path="profiles.db" />
<include domain="database" path="settings.db" />
<include domain="file" path="configs" />
<include
domain="database"
path="profiles.db" />
<include
domain="database"
path="settings.db" />
<include
domain="file"
path="configs" />
</cloud-backup>
<device-transfer>
<include domain="database" path="profiles.db" />
<include domain="database" path="settings.db" />
<include domain="file" path="configs" />
<include
domain="database"
path="profiles.db" />
<include
domain="database"
path="settings.db" />
<include
domain="file"
path="configs" />
</device-transfer>
</data-extraction-rules>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
<io.nekohasekai.sfa.ui.settings.Preference
app:fragment="io.nekohasekai.sfa.ui.settings.CoreFragment"
app:icon="@drawable/ic_qr_code_2_24"
app:title="@string/settings_title_core" />
</androidx.preference.PreferenceScreen>

View file

@ -6,8 +6,8 @@ buildscript {
}
plugins {
id 'com.android.application' version '8.2.2' apply false
id 'com.android.library' version '8.2.2' apply false
id 'com.android.application' version '8.3.0' apply false
id 'com.android.library' version '8.3.0' apply false
id 'org.jetbrains.kotlin.android' version '1.9.0' apply false
id 'com.google.devtools.ksp' version '1.9.0-1.0.12' apply false
id 'com.github.triplet.play' version '3.8.4' apply false