diff --git a/build.gradle b/build.gradle
index 6fa46301..1b222161 100644
--- a/build.gradle
+++ b/build.gradle
@@ -17,8 +17,8 @@ android {
applicationId = 'com.looker.droidify'
minSdk = 23
targetSdk = 32
- versionCode = 43
- versionName = "0.4.3"
+ versionCode = 903
+ versionName = "0.9.0"
vectorDrawables.useSupportLibrary = true
javaCompileOptions {
@@ -58,7 +58,7 @@ android {
minifyEnabled = false
shrinkResources = false
applicationIdSuffix = ".debug"
- versionNameSuffix = "-alpha2"
+ versionNameSuffix = "-alpha3"
resValue "string", "application_name", "Neo Store-Debug"
manifestPlaceholders = [
appIcon : "@mipmap/ic_launcher_debug",
@@ -69,7 +69,7 @@ android {
minifyEnabled = false
shrinkResources = false
applicationIdSuffix = ".neo"
- versionNameSuffix = "-alpha2"
+ versionNameSuffix = "-alpha3"
resValue "string", "application_name", "Neo Store-alpha"
manifestPlaceholders = [
appIcon : "@mipmap/ic_launcher_debug",
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 0df76b76..e860c8a1 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -9,6 +9,7 @@
tools:ignore="QueryAllPackagesPermission" />
diff --git a/src/main/kotlin/com/looker/droidify/Common.kt b/src/main/kotlin/com/looker/droidify/Common.kt
index 4a9d217c..bb45fba8 100644
--- a/src/main/kotlin/com/looker/droidify/Common.kt
+++ b/src/main/kotlin/com/looker/droidify/Common.kt
@@ -15,8 +15,8 @@ const val TABLE_CATEGORY_NAME = "category"
const val TABLE_CATEGORY_TEMP_NAME = "temporary_category"
const val TABLE_INSTALLED = "installed"
const val TABLE_INSTALLED_NAME = "memory_installed"
-const val TABLE_LOCK = "lock"
-const val TABLE_LOCK_NAME = "memory_lock"
+const val TABLE_IGNORED = "lock"
+const val TABLE_IGNORED_NAME = "memory_lock"
const val TABLE_PRODUCT = "product"
const val TABLE_PRODUCT_NAME = "product"
const val TABLE_PRODUCT_TEMP_NAME = "temporary_product"
@@ -43,7 +43,6 @@ const val ROW_ANTIFEATURES = "antiFeatures"
const val ROW_LICENSES = "licenses"
const val ROW_DONATES = "donates"
const val ROW_SCREENSHOTS = "screenshots"
-const val ROW_VERSION = "version"
const val ROW_SIGNATURE = "signature"
const val ROW_ID = "_id"
const val ROW_ENABLED = "enabled"
diff --git a/src/main/kotlin/com/looker/droidify/content/Preferences.kt b/src/main/kotlin/com/looker/droidify/content/Preferences.kt
index e1f37c3b..1b283d38 100644
--- a/src/main/kotlin/com/looker/droidify/content/Preferences.kt
+++ b/src/main/kotlin/com/looker/droidify/content/Preferences.kt
@@ -37,7 +37,8 @@ object Preferences {
Key.Theme,
Key.DefaultTab,
Key.UpdateNotify,
- Key.UpdateUnstable
+ Key.UpdateUnstable,
+ Key.IgnoreIgnoreBatteryOptimization
).map { Pair(it.name, it) }.toMap()
fun init(context: Context) {
@@ -178,6 +179,9 @@ object Preferences {
object UpdateNotify : Key("update_notify", Value.BooleanValue(true))
object UpdateUnstable : Key("update_unstable", Value.BooleanValue(false))
+
+ object IgnoreIgnoreBatteryOptimization :
+ Key("ignore_ignore_battery_optimization", Value.BooleanValue(false))
}
sealed class AutoSync(override val valueString: String) : Enumeration {
diff --git a/src/main/kotlin/com/looker/droidify/content/ProductPreferences.kt b/src/main/kotlin/com/looker/droidify/content/ProductPreferences.kt
index 6fe14a07..7787d1ce 100644
--- a/src/main/kotlin/com/looker/droidify/content/ProductPreferences.kt
+++ b/src/main/kotlin/com/looker/droidify/content/ProductPreferences.kt
@@ -3,7 +3,7 @@ package com.looker.droidify.content
import android.content.Context
import android.content.SharedPreferences
import com.looker.droidify.database.DatabaseX
-import com.looker.droidify.database.entity.Lock
+import com.looker.droidify.database.entity.Ignored
import com.looker.droidify.entity.ProductPreference
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -27,13 +27,13 @@ object ProductPreferences {
db.lockDao.insert(*preferences.all.keys
.mapNotNull { pName ->
this@ProductPreferences[pName].databaseVersionCode?.let {
- Lock(pName, it)
+ Ignored(pName, it)
}
}
.toTypedArray()
)
subject.collect { (packageName, versionCode) ->
- if (versionCode != null) db.lockDao.insert(Lock(packageName, versionCode))
+ if (versionCode != null) db.lockDao.insert(Ignored(packageName, versionCode))
else db.lockDao.delete(packageName)
}
}
diff --git a/src/main/kotlin/com/looker/droidify/database/DAOs.kt b/src/main/kotlin/com/looker/droidify/database/DAOs.kt
index 3ef01739..135dcc5a 100644
--- a/src/main/kotlin/com/looker/droidify/database/DAOs.kt
+++ b/src/main/kotlin/com/looker/droidify/database/DAOs.kt
@@ -144,7 +144,7 @@ interface ProductDao : BaseDao {
builder += """SELECT $TABLE_PRODUCT.rowid AS $ROW_ID, $TABLE_PRODUCT.$ROW_REPOSITORY_ID,
$TABLE_PRODUCT.$ROW_PACKAGE_NAME, $TABLE_PRODUCT.$ROW_LABEL,
$TABLE_PRODUCT.$ROW_SUMMARY, $TABLE_PRODUCT.$ROW_DESCRIPTION,
- (COALESCE($TABLE_LOCK.$ROW_VERSION_CODE, -1) NOT IN (0, $TABLE_PRODUCT.$ROW_VERSION_CODE) AND
+ (COALESCE($TABLE_IGNORED.$ROW_VERSION_CODE, -1) NOT IN (0, $TABLE_PRODUCT.$ROW_VERSION_CODE) AND
$TABLE_PRODUCT.$ROW_COMPATIBLE != 0 AND
$TABLE_PRODUCT.$ROW_VERSION_CODE > COALESCE($TABLE_INSTALLED.$ROW_VERSION_CODE, 0xffffffff) AND
$signatureMatches) AS $ROW_CAN_UPDATE, $TABLE_PRODUCT.$ROW_ICON,
@@ -173,8 +173,8 @@ interface ProductDao : BaseDao {
ON $TABLE_PRODUCT.$ROW_REPOSITORY_ID = $TABLE_REPOSITORY.$ROW_ID"""
// Merge the matching locks
- builder += """LEFT JOIN $TABLE_LOCK_NAME AS $TABLE_LOCK
- ON $TABLE_PRODUCT.$ROW_PACKAGE_NAME = $TABLE_LOCK.$ROW_PACKAGE_NAME"""
+ builder += """LEFT JOIN $TABLE_IGNORED_NAME AS $TABLE_IGNORED
+ ON $TABLE_PRODUCT.$ROW_PACKAGE_NAME = $TABLE_IGNORED.$ROW_PACKAGE_NAME"""
// Merge the matching installed
if (!installed && !updates) builder += "LEFT"
@@ -291,7 +291,7 @@ interface InstalledDao : BaseDao {
}
@Dao
-interface LockDao : BaseDao {
+interface LockDao : BaseDao {
@Query("DELETE FROM memory_lock WHERE packageName = :packageName")
fun delete(packageName: String)
}
diff --git a/src/main/kotlin/com/looker/droidify/database/DatabaseX.kt b/src/main/kotlin/com/looker/droidify/database/DatabaseX.kt
index 2bf22262..17cc408f 100644
--- a/src/main/kotlin/com/looker/droidify/database/DatabaseX.kt
+++ b/src/main/kotlin/com/looker/droidify/database/DatabaseX.kt
@@ -20,7 +20,7 @@ import kotlinx.coroutines.launch
Category::class,
CategoryTemp::class,
Installed::class,
- Lock::class
+ Ignored::class
], version = 6
)
@TypeConverters(Converters::class)
diff --git a/src/main/kotlin/com/looker/droidify/database/entity/Lock.kt b/src/main/kotlin/com/looker/droidify/database/entity/Ignored.kt
similarity index 56%
rename from src/main/kotlin/com/looker/droidify/database/entity/Lock.kt
rename to src/main/kotlin/com/looker/droidify/database/entity/Ignored.kt
index 5f27889a..559827e3 100644
--- a/src/main/kotlin/com/looker/droidify/database/entity/Lock.kt
+++ b/src/main/kotlin/com/looker/droidify/database/entity/Ignored.kt
@@ -2,10 +2,11 @@ package com.looker.droidify.database.entity
import androidx.room.Entity
import androidx.room.PrimaryKey
-import com.looker.droidify.TABLE_LOCK_NAME
+import com.looker.droidify.TABLE_IGNORED_NAME
-@Entity(tableName = TABLE_LOCK_NAME)
-data class Lock(
+// TODO complete renaming to Ignored
+@Entity(tableName = TABLE_IGNORED_NAME)
+data class Ignored(
@PrimaryKey
var packageName: String = "",
var versionCode: Long = 0L
diff --git a/src/main/kotlin/com/looker/droidify/service/DownloadService.kt b/src/main/kotlin/com/looker/droidify/service/DownloadService.kt
index 0d878e02..97a9ec2d 100644
--- a/src/main/kotlin/com/looker/droidify/service/DownloadService.kt
+++ b/src/main/kotlin/com/looker/droidify/service/DownloadService.kt
@@ -37,6 +37,7 @@ import java.io.File
import java.security.MessageDigest
import kotlin.math.roundToInt
+// TODO maybe replace by using WorkManager instead?
class DownloadService : ConnectionService() {
companion object {
private const val ACTION_CANCEL = "${BuildConfig.APPLICATION_ID}.intent.action.CANCEL"
diff --git a/src/main/kotlin/com/looker/droidify/ui/activities/MainActivityX.kt b/src/main/kotlin/com/looker/droidify/ui/activities/MainActivityX.kt
index 2bbf06eb..2b9cb2d4 100644
--- a/src/main/kotlin/com/looker/droidify/ui/activities/MainActivityX.kt
+++ b/src/main/kotlin/com/looker/droidify/ui/activities/MainActivityX.kt
@@ -3,6 +3,7 @@ package com.looker.droidify.ui.activities
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.os.PowerManager
import android.view.Menu
import android.view.MenuItem
import android.view.inputmethod.InputMethodManager
@@ -31,6 +32,7 @@ import com.looker.droidify.ui.fragments.Source
import com.looker.droidify.ui.viewmodels.MainActivityViewModelX
import com.looker.droidify.utility.extension.android.Android
import com.looker.droidify.utility.extension.text.nullIfEmpty
+import com.looker.droidify.utility.showBatteryOptimizationDialog
import kotlinx.coroutines.launch
import kotlin.properties.Delegates
@@ -52,6 +54,7 @@ class MainActivityX : AppCompatActivity() {
lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var navController: NavController
private val viewModel: MainActivityViewModelX by viewModels()
+ private lateinit var powerManager: PowerManager
val menuSetup = MutableLiveData()
val syncConnection = Connection(SyncService::class.java, onBind = { _, _ ->
@@ -95,6 +98,7 @@ class MainActivityX : AppCompatActivity() {
setupActionBarWithNavController(navController, appBarConfiguration)
binding.bottomNavigation.selectedItemId = currentTab
+ powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
if (savedInstanceState == null && (intent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) {
handleIntent(intent)
}
@@ -117,6 +121,8 @@ class MainActivityX : AppCompatActivity() {
super.onResume()
if (currentTheme != Preferences[Preferences.Key.Theme].getResId(resources.configuration))
recreate()
+ if (!powerManager.isIgnoringBatteryOptimizations(this.packageName) && !Preferences[Preferences.Key.IgnoreIgnoreBatteryOptimization])
+ showBatteryOptimizationDialog()
}
override fun onSupportNavigateUp(): Boolean {
diff --git a/src/main/kotlin/com/looker/droidify/ui/compose/ItemRecyclers.kt b/src/main/kotlin/com/looker/droidify/ui/compose/ItemRecyclers.kt
index 4f409055..392e6871 100644
--- a/src/main/kotlin/com/looker/droidify/ui/compose/ItemRecyclers.kt
+++ b/src/main/kotlin/com/looker/droidify/ui/compose/ItemRecyclers.kt
@@ -30,11 +30,12 @@ import com.looker.droidify.ui.compose.components.RepositoryItem
fun ProductsVerticalRecycler(
productsList: List?,
repositories: Map,
+ modifier: Modifier = Modifier.fillMaxSize(),
onUserClick: (ProductItem) -> Unit = {},
onFavouriteClick: (ProductItem) -> Unit = {},
onInstallClick: (ProductItem) -> Unit = {}
) {
- VerticalItemList(list = productsList) {
+ VerticalItemList(list = productsList, modifier = modifier) {
it.toItem().let { item ->
ProductsListItem(
item,
@@ -84,7 +85,7 @@ fun RepositoriesRecycler(
@Composable
fun VerticalItemList(
- modifier: Modifier = Modifier,
+ modifier: Modifier = Modifier.fillMaxSize(),
backgroundColor: Color = MaterialTheme.colorScheme.background,
list: List?,
itemKey: ((T) -> Any)? = null,
@@ -92,7 +93,6 @@ fun VerticalItemList(
) {
Box(
modifier = modifier
- .fillMaxSize()
.background(backgroundColor),
contentAlignment = if (list.isNullOrEmpty()) Alignment.Center else Alignment.TopStart
) {
diff --git a/src/main/kotlin/com/looker/droidify/ui/compose/components/ProductCard.kt b/src/main/kotlin/com/looker/droidify/ui/compose/components/ProductCard.kt
index 2c5e957c..367944e4 100644
--- a/src/main/kotlin/com/looker/droidify/ui/compose/components/ProductCard.kt
+++ b/src/main/kotlin/com/looker/droidify/ui/compose/components/ProductCard.kt
@@ -28,12 +28,13 @@ fun ProductCard(
onUserClick: (ProductItem) -> Unit = {}
) {
- val imageData by remember(item, repo) {
+ val product by remember(item) { mutableStateOf(item) }
+ val imageData by remember(product, repo) {
mutableStateOf(
CoilDownloader.createIconUri(
- item.packageName,
- item.icon,
- item.metadataIcon,
+ product.packageName,
+ product.icon,
+ product.metadataIcon,
repo?.address,
repo?.authentication
).toString()
@@ -46,7 +47,7 @@ fun ProductCard(
.requiredSize(80.dp, 116.dp)
.clip(shape = RoundedCornerShape(8.dp))
.background(color = MaterialTheme.colorScheme.surface)
- .clickable(onClick = { onUserClick(item) }),
+ .clickable(onClick = { onUserClick(product) }),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
@@ -57,7 +58,7 @@ fun ProductCard(
Text(
modifier = Modifier.padding(4.dp, 2.dp),
- text = item.name,
+ text = product.name,
style = MaterialTheme.typography.bodySmall,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
@@ -65,7 +66,7 @@ fun ProductCard(
)
Text(
modifier = Modifier.padding(4.dp, 1.dp),
- text = item.version,
+ text = product.version,
style = MaterialTheme.typography.labelSmall,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
diff --git a/src/main/kotlin/com/looker/droidify/ui/compose/components/ProductsListItem.kt b/src/main/kotlin/com/looker/droidify/ui/compose/components/ProductsListItem.kt
index 8ab827e9..25f49576 100644
--- a/src/main/kotlin/com/looker/droidify/ui/compose/components/ProductsListItem.kt
+++ b/src/main/kotlin/com/looker/droidify/ui/compose/components/ProductsListItem.kt
@@ -32,12 +32,13 @@ fun ProductsListItem(
onFavouriteClick: (ProductItem) -> Unit = {},
onInstallClick: (ProductItem) -> Unit = {}
) {
- val imageData by remember(item, repo) {
+ val product by remember(item) { mutableStateOf(item) }
+ val imageData by remember(product, repo) {
mutableStateOf(
CoilDownloader.createIconUri(
- item.packageName,
- item.icon,
- item.metadataIcon,
+ product.packageName,
+ product.icon,
+ product.metadataIcon,
repo?.address,
repo?.authentication
).toString()
@@ -46,10 +47,10 @@ fun ProductsListItem(
ExpandableCard(
modifier = Modifier.padding(horizontal = 8.dp, vertical = 8.dp),
- onClick = { onUserClick(item) },
+ onClick = { onUserClick(product) },
expandedContent = {
ExpandedItemContent(
- item = item,
+ item = product,
onFavourite = onFavouriteClick,
onInstallClicked = onInstallClick
)
@@ -74,7 +75,7 @@ fun ProductsListItem(
.fillMaxHeight(0.4f),
) {
Text(
- text = item.name,
+ text = product.name,
modifier = Modifier
.align(Alignment.CenterVertically)
.weight(1f),
@@ -84,8 +85,8 @@ fun ProductsListItem(
style = MaterialTheme.typography.titleMedium
)
Text(
- text = item.version,
modifier = Modifier.align(Alignment.CenterVertically),
+ text = product.version,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = MaterialTheme.typography.bodySmall,
@@ -95,7 +96,7 @@ fun ProductsListItem(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth(),
- text = item.summary,
+ text = product.summary,
style = MaterialTheme.typography.bodySmall,
overflow = TextOverflow.Ellipsis,
maxLines = 2,
diff --git a/src/main/kotlin/com/looker/droidify/ui/compose/utils/Chip.kt b/src/main/kotlin/com/looker/droidify/ui/compose/utils/Chip.kt
index bf2bd3ba..3de77dc4 100644
--- a/src/main/kotlin/com/looker/droidify/ui/compose/utils/Chip.kt
+++ b/src/main/kotlin/com/looker/droidify/ui/compose/utils/Chip.kt
@@ -1,16 +1,14 @@
package com.looker.droidify.ui.compose.utils
import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.Chip
-import androidx.compose.material.ChipColors
-import androidx.compose.material.ChipDefaults
-import androidx.compose.material.ExperimentalMaterialApi
+import androidx.compose.material.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
+import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.unit.dp
@@ -29,7 +27,8 @@ fun ChipRow(
) {
LazyRow(
modifier = modifier,
- horizontalArrangement = Arrangement.spacedBy(8.dp)
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ contentPadding = PaddingValues(horizontal = 8.dp)
) {
items(list) {
Chip(
@@ -40,7 +39,47 @@ fun ChipRow(
Text(
text = it,
style = MaterialTheme.typography.labelLarge,
- color = MaterialTheme.colorScheme.primary.copy(alpha = ChipDefaults.ContentOpacity)
+ color = chipColors.contentColor(enabled = true).value
+ )
+ }
+ }
+ }
+}
+
+@OptIn(ExperimentalMaterialApi::class)
+@Composable
+fun SelectableChipRow(
+ modifier: Modifier = Modifier,
+ list: List,
+ chipColors: SelectableChipColors = ChipDefaults.filterChipColors(
+ backgroundColor = MaterialTheme.colorScheme.surface,
+ contentColor = MaterialTheme.colorScheme.onSurface,
+ selectedBackgroundColor = MaterialTheme.colorScheme.primary,
+ selectedContentColor = MaterialTheme.colorScheme.onPrimary
+ ),
+ shapes: Shape = RoundedCornerShape(50),
+ onClick: (String) -> Unit
+) {
+ var selected by remember { mutableStateOf(list[0]) }
+
+ LazyRow(
+ modifier = modifier,
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ contentPadding = PaddingValues(horizontal = 8.dp)
+ ) {
+ items(list) {
+ FilterChip(
+ shape = shapes,
+ colors = chipColors,
+ selected = it == selected,
+ onClick = {
+ onClick(it)
+ selected = it
+ }
+ ) {
+ Text(
+ text = it,
+ color = chipColors.contentColor(enabled = true, selected = it == selected).value
)
}
}
diff --git a/src/main/kotlin/com/looker/droidify/ui/fragments/BaseNavFragment.kt b/src/main/kotlin/com/looker/droidify/ui/fragments/BaseNavFragment.kt
index f0edab8e..5c3cffb0 100644
--- a/src/main/kotlin/com/looker/droidify/ui/fragments/BaseNavFragment.kt
+++ b/src/main/kotlin/com/looker/droidify/ui/fragments/BaseNavFragment.kt
@@ -7,10 +7,8 @@ import androidx.fragment.app.Fragment
abstract class BaseNavFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- setupAdapters()
setupLayout()
}
- abstract fun setupAdapters()
abstract fun setupLayout()
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/looker/droidify/ui/fragments/ExploreFragment.kt b/src/main/kotlin/com/looker/droidify/ui/fragments/ExploreFragment.kt
index ee6ed117..b3ce7d39 100644
--- a/src/main/kotlin/com/looker/droidify/ui/fragments/ExploreFragment.kt
+++ b/src/main/kotlin/com/looker/droidify/ui/fragments/ExploreFragment.kt
@@ -5,18 +5,26 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.SearchView
+import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
-import androidx.compose.material.Scaffold
-import androidx.core.view.children
-import com.google.android.material.chip.Chip
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.material.ExperimentalMaterialApi
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
import com.looker.droidify.R
import com.looker.droidify.content.Preferences
-import com.looker.droidify.database.entity.Category
+import com.looker.droidify.database.entity.Product
import com.looker.droidify.database.entity.Repository
import com.looker.droidify.databinding.FragmentExploreXBinding
import com.looker.droidify.entity.Section
import com.looker.droidify.ui.compose.ProductsVerticalRecycler
import com.looker.droidify.ui.compose.theme.AppTheme
+import com.looker.droidify.ui.compose.utils.SelectableChipRow
import com.looker.droidify.utility.isDarkTheme
import com.looker.droidify.widget.FocusSearchView
@@ -40,67 +48,15 @@ class ExploreFragment : MainNavFragmentX() {
return binding.root
}
- override fun setupAdapters() {
- }
-
override fun setupLayout() {
viewModel.repositories.observe(viewLifecycleOwner) {
repositories = it.associateBy { repo -> repo.id }
}
viewModel.primaryProducts.observe(viewLifecycleOwner) {
- binding.primaryComposeRecycler.setContent {
- AppTheme(
- darkTheme = when (Preferences[Preferences.Key.Theme]) {
- is Preferences.Theme.System -> isSystemInDarkTheme()
- is Preferences.Theme.AmoledSystem -> isSystemInDarkTheme()
- else -> isDarkTheme
- }
- ) {
- Scaffold { _ ->
- ProductsVerticalRecycler(it, repositories,
- onUserClick = { item ->
- AppSheetX(item.packageName)
- .showNow(parentFragmentManager, "Product ${item.packageName}")
- },
- onFavouriteClick = {},
- onInstallClick = {
- mainActivityX.syncConnection.binder?.installApps(listOf(it))
- }
- )
- }
- }
- }
+ redrawPage(it, viewModel.categories.value ?: emptyList())
}
viewModel.categories.observe(viewLifecycleOwner) {
- binding.categories.apply {
- removeAllViews()
- addView(Chip(requireContext(), null, R.attr.categoryChipStyle).apply {
- setText(R.string.all_applications)
- id = R.id.SHOW_ALL
- })
- it.sorted().forEach {
- addView(Chip(requireContext(), null, R.attr.categoryChipStyle).apply {
- text = it
- })
- }
- val selectedSection = viewModel.sections.value
- check(
- children.filterNotNull()
- .find { child ->
- child is Chip && selectedSection is Category && child.text == selectedSection.label
- }?.id ?: R.id.SHOW_ALL
- )
- }
- }
- binding.categories.setOnCheckedStateChangeListener { group, checkedIds ->
- group.findViewById(checkedIds[0]).let {
- viewModel.setSection(
- if (it.text.equals(getString(R.string.all_applications)))
- Section.All
- else
- Section.Category(it.text.toString())
- )
- }
+ redrawPage(viewModel.primaryProducts.value, it)
}
mainActivityX.menuSetup.observe(viewLifecycleOwner) {
if (it != null) {
@@ -122,4 +78,53 @@ class ExploreFragment : MainNavFragmentX() {
}
}
}
+
+ @OptIn(ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class)
+ private fun redrawPage(products: List?, categories: List = emptyList()) {
+ binding.primaryComposeRecycler.setContent {
+ AppTheme(
+ darkTheme = when (Preferences[Preferences.Key.Theme]) {
+ is Preferences.Theme.System -> isSystemInDarkTheme()
+ is Preferences.Theme.AmoledSystem -> isSystemInDarkTheme()
+ else -> isDarkTheme
+ }
+ ) {
+ Scaffold { _ ->
+ Column(
+ Modifier
+ .background(MaterialTheme.colorScheme.background)
+ .fillMaxSize()
+ ) {
+ SelectableChipRow(
+ list = listOf(
+ stringResource(id = R.string.all_applications),
+ *categories.sorted().toTypedArray()
+ )
+ ) {
+ viewModel.setSection(
+ when (it) {
+ getString(R.string.all_applications) -> Section.All
+ else -> Section.Category(it)
+ }
+ )
+ }
+ ProductsVerticalRecycler(products,
+ repositories,
+ Modifier
+ .fillMaxWidth()
+ .weight(1f),
+ onUserClick = { item ->
+ AppSheetX(item.packageName)
+ .showNow(parentFragmentManager, "Product ${item.packageName}")
+ },
+ onFavouriteClick = {},
+ onInstallClick = {
+ mainActivityX.syncConnection.binder?.installApps(listOf(it))
+ }
+ )
+ }
+ }
+ }
+ }
+ }
}
diff --git a/src/main/kotlin/com/looker/droidify/ui/fragments/InstalledFragment.kt b/src/main/kotlin/com/looker/droidify/ui/fragments/InstalledFragment.kt
index f48366bf..5d2dca5a 100644
--- a/src/main/kotlin/com/looker/droidify/ui/fragments/InstalledFragment.kt
+++ b/src/main/kotlin/com/looker/droidify/ui/fragments/InstalledFragment.kt
@@ -39,9 +39,6 @@ class InstalledFragment : MainNavFragmentX() {
return binding.root
}
- override fun setupAdapters() {
- }
-
override fun setupLayout() {
viewModel.repositories.observe(viewLifecycleOwner) {
repositories = it.associateBy { repo -> repo.id }
diff --git a/src/main/kotlin/com/looker/droidify/ui/fragments/LatestFragment.kt b/src/main/kotlin/com/looker/droidify/ui/fragments/LatestFragment.kt
index 69dfd125..84025299 100644
--- a/src/main/kotlin/com/looker/droidify/ui/fragments/LatestFragment.kt
+++ b/src/main/kotlin/com/looker/droidify/ui/fragments/LatestFragment.kt
@@ -39,9 +39,6 @@ class LatestFragment : MainNavFragmentX() {
return binding.root
}
- override fun setupAdapters() {
- }
-
override fun setupLayout() {
viewModel.repositories.observe(viewLifecycleOwner) {
repositories = it.associateBy { repo -> repo.id }
diff --git a/src/main/kotlin/com/looker/droidify/ui/fragments/PrefsRepositoriesFragment.kt b/src/main/kotlin/com/looker/droidify/ui/fragments/PrefsRepositoriesFragment.kt
index cd224fa2..b9072545 100644
--- a/src/main/kotlin/com/looker/droidify/ui/fragments/PrefsRepositoriesFragment.kt
+++ b/src/main/kotlin/com/looker/droidify/ui/fragments/PrefsRepositoriesFragment.kt
@@ -43,12 +43,9 @@ class PrefsRepositoriesFragment : BaseNavFragment() {
return binding.root
}
- override fun setupAdapters() {
+ override fun setupLayout() {
syncConnection.bind(requireContext())
binding.addRepository.setOnClickListener { viewModel.addRepository() }
- }
-
- override fun setupLayout() {
viewModel.repositories.observe(requireActivity()) {
binding.reposRecycler.setContent {
AppTheme(
diff --git a/src/main/kotlin/com/looker/droidify/utility/Utils.kt b/src/main/kotlin/com/looker/droidify/utility/Utils.kt
index 03107957..fbd1bda4 100644
--- a/src/main/kotlin/com/looker/droidify/utility/Utils.kt
+++ b/src/main/kotlin/com/looker/droidify/utility/Utils.kt
@@ -3,11 +3,19 @@ package com.looker.droidify.utility
import android.app.ActivityManager
import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE
+import android.content.ActivityNotFoundException
import android.content.Context
+import android.content.DialogInterface
+import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.Signature
import android.content.res.Configuration
import android.graphics.drawable.Drawable
+import android.net.Uri
+import android.os.PowerManager
+import android.provider.Settings
+import android.widget.Toast
+import androidx.appcompat.app.AlertDialog
import com.looker.droidify.BuildConfig
import com.looker.droidify.PREFS_LANGUAGE_DEFAULT
import com.looker.droidify.R
@@ -193,4 +201,28 @@ val isBlackTheme: Boolean
is Preferences.Theme.Amoled -> true
is Preferences.Theme.AmoledSystem -> true
else -> false
- }
\ No newline at end of file
+ }
+
+fun Context.showBatteryOptimizationDialog() {
+ AlertDialog.Builder(this)
+ .setTitle(R.string.ignore_battery_optimization_title)
+ .setMessage(R.string.ignore_battery_optimization_message)
+ .setPositiveButton(R.string.dialog_approve) { dialog: DialogInterface?, _: Int ->
+ val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
+ intent.data = Uri.parse("package:" + this.packageName)
+ try {
+ startActivity(intent)
+ } catch (e: ActivityNotFoundException) {
+ Toast.makeText(
+ this,
+ R.string.ignore_battery_optimization_not_supported,
+ Toast.LENGTH_LONG
+ ).show()
+ Preferences[Preferences.Key.IgnoreIgnoreBatteryOptimization] = true
+ }
+ }
+ .setNeutralButton(R.string.dialog_refuse) { _: DialogInterface?, _: Int ->
+ Preferences[Preferences.Key.IgnoreIgnoreBatteryOptimization] = true
+ }
+ .show()
+}
\ No newline at end of file
diff --git a/src/main/res/layout/fragment_explore_x.xml b/src/main/res/layout/fragment_explore_x.xml
index c081e301..476406bb 100644
--- a/src/main/res/layout/fragment_explore_x.xml
+++ b/src/main/res/layout/fragment_explore_x.xml
@@ -15,8 +15,7 @@
~ You should have received a copy of the GNU Affero General Public License
~ along with this program. If not, see .
-->
-
+
@@ -26,33 +25,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
-
-
-
-
-
-
-
-
+ android:layout_height="match_parent" />
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 54484d9e..fbe796c2 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -189,4 +189,9 @@
Default Tab
Pending
Installing
+ Ignore Battery Optimization
+ Starting Android 12 there\'s restrictions on running foreground services causing the app to crash on downloads. To prevent this, you should turn off the battery optimization
+ The device doesn\'t support ignoring battery optimizations!
+ Don\'t need it
+ Let\'s do it!