This commit is contained in:
machiav3lli 2022-10-08 01:50:07 +02:00
parent 9a5607c52d
commit 25a3c2691f
5 changed files with 266 additions and 299 deletions

View File

@ -1,30 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION" />
<application
android:name=".MainApplication"
android:allowBackup="false"
android:icon="${appIcon}"
android:label="@string/application_name"
android:roundIcon="${appIconRound}"
android:supportsRtl="true"
tools:ignore="GoogleAppIndexingWarning">
android:name=".MainApplication"
android:allowBackup="false"
android:icon="${appIcon}"
android:label="@string/application_name"
android:roundIcon="${appIconRound}"
android:supportsRtl="true"
android:theme="@style/Theme.Main.Amoled"
tools:ignore="GoogleAppIndexingWarning">
<receiver
android:name=".MainApplication$BootReceiver"
android:exported="true">
android:name=".MainApplication$BootReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
@ -33,10 +34,10 @@
</receiver>
<activity
android:name=".ui.activities.MainActivityX"
android:exported="true"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize">
android:name=".ui.activities.MainActivityX"
android:exported="true"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -59,8 +60,8 @@
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="details"
android:scheme="market" />
android:host="details"
android:scheme="market" />
</intent-filter>
<intent-filter>
@ -82,29 +83,29 @@
</activity>
<activity
android:name=".ui.activities.PrefsActivityX"
android:exported="true"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize" />
android:name=".ui.activities.PrefsActivityX"
android:exported="true"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize" />
<service android:name=".service.SyncService" />
<service
android:name=".service.SyncService$Job"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" />
android:name=".service.SyncService$Job"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" />
<service android:name=".service.DownloadService" />
<service
android:name=".installer.InstallerService"
android:exported="false" />
android:name=".installer.InstallerService"
android:exported="false" />
<provider
android:name=".content.Cache$Provider"
android:authorities="${applicationId}.provider.cache"
android:exported="false"
android:grantUriPermissions="true" />
android:name=".content.Cache$Provider"
android:authorities="${applicationId}.provider.cache"
android:exported="false"
android:grantUriPermissions="true" />
</application>

View File

@ -1,7 +1,6 @@
package com.machiav3lli.fdroid.ui.pages
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@ -35,10 +34,8 @@ import com.machiav3lli.fdroid.ui.compose.ProductsVerticalRecycler
import com.machiav3lli.fdroid.ui.compose.components.CategoryChip
import com.machiav3lli.fdroid.ui.compose.icons.Phosphor
import com.machiav3lli.fdroid.ui.compose.icons.phosphor.FunnelSimple
import com.machiav3lli.fdroid.ui.compose.theme.AppTheme
import com.machiav3lli.fdroid.ui.navigation.NavItem
import com.machiav3lli.fdroid.ui.viewmodels.MainNavFragmentViewModelX
import com.machiav3lli.fdroid.utility.isDarkTheme
import com.machiav3lli.fdroid.utility.onLaunchClick
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -78,83 +75,75 @@ fun ExplorePage(viewModel: MainNavFragmentViewModelX) {
}
}
AppTheme(
darkTheme = when (Preferences[Preferences.Key.Theme]) {
is Preferences.Theme.System -> isSystemInDarkTheme()
is Preferences.Theme.SystemBlack -> isSystemInDarkTheme()
else -> isDarkTheme
}
Column(
Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize()
) {
Column(
Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize()
Row(
modifier = Modifier.padding(horizontal = 6.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Row(
modifier = Modifier.padding(horizontal = 6.dp),
verticalAlignment = Alignment.CenterVertically,
) {
var favoriteFilter by remember {
mutableStateOf(false)
}
SuggestionChip(
shape = MaterialTheme.shapes.medium,
colors = SuggestionChipDefaults.suggestionChipColors(
containerColor = MaterialTheme.colorScheme.surface,
labelColor = MaterialTheme.colorScheme.onSurface,
),
onClick = {
mainActivityX.navigateSortFilter(NavItem.Explore.destination)
},
icon = {
Icon(
modifier = Modifier.size(18.dp),
imageVector = Phosphor.FunnelSimple,
contentDescription = stringResource(id = R.string.sort_filter)
)
},
label = {
Text(text = stringResource(id = R.string.sort_filter))
}
)
Spacer(modifier = Modifier.weight(1f))
CategoryChip(
category = stringResource(id = R.string.favorite_applications),
isSelected = favoriteFilter,
onSelected = {
favoriteFilter = !favoriteFilter
viewModel.sections.postValue(
if (it) Section.FAVORITE
else Section.All
)
}
)
var favoriteFilter by remember {
mutableStateOf(false)
}
ProductsVerticalRecycler(
productsList = products,
repositories = repositoriesMap,
favorites = favorites,
modifier = Modifier
.fillMaxWidth()
.weight(1f),
onUserClick = { item ->
mainActivityX.navigateProduct(item.packageName)
SuggestionChip(
shape = MaterialTheme.shapes.medium,
colors = SuggestionChipDefaults.suggestionChipColors(
containerColor = MaterialTheme.colorScheme.surface,
labelColor = MaterialTheme.colorScheme.onSurface,
),
onClick = {
mainActivityX.navigateSortFilter(NavItem.Explore.destination)
},
onFavouriteClick = { item ->
viewModel.setFavorite(
item.packageName,
!favorites.contains(item.packageName)
icon = {
Icon(
modifier = Modifier.size(18.dp),
imageVector = Phosphor.FunnelSimple,
contentDescription = stringResource(id = R.string.sort_filter)
)
},
getInstalled = { installedList?.get(it.packageName) }
) { item ->
val installed = installedList?.get(item.packageName)
if (installed != null && installed.launcherActivities.isNotEmpty())
context.onLaunchClick(installed, mainActivityX.supportFragmentManager)
else
mainActivityX.syncConnection.binder?.installApps(listOf(item))
}
label = {
Text(text = stringResource(id = R.string.sort_filter))
}
)
Spacer(modifier = Modifier.weight(1f))
CategoryChip(
category = stringResource(id = R.string.favorite_applications),
isSelected = favoriteFilter,
onSelected = {
favoriteFilter = !favoriteFilter
viewModel.sections.postValue(
if (it) Section.FAVORITE
else Section.All
)
}
)
}
ProductsVerticalRecycler(
productsList = products,
repositories = repositoriesMap,
favorites = favorites,
modifier = Modifier
.fillMaxWidth()
.weight(1f),
onUserClick = { item ->
mainActivityX.navigateProduct(item.packageName)
},
onFavouriteClick = { item ->
viewModel.setFavorite(
item.packageName,
!favorites.contains(item.packageName)
)
},
getInstalled = { installedList?.get(it.packageName) }
) { item ->
val installed = installedList?.get(item.packageName)
if (installed != null && installed.launcherActivities.isNotEmpty())
context.onLaunchClick(installed, mainActivityX.supportFragmentManager)
else
mainActivityX.syncConnection.binder?.installApps(listOf(item))
}
}
}

View File

@ -2,7 +2,6 @@ package com.machiav3lli.fdroid.ui.pages
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@ -43,10 +42,8 @@ import com.machiav3lli.fdroid.ui.compose.icons.phosphor.CaretDown
import com.machiav3lli.fdroid.ui.compose.icons.phosphor.CaretUp
import com.machiav3lli.fdroid.ui.compose.icons.phosphor.Download
import com.machiav3lli.fdroid.ui.compose.icons.phosphor.FunnelSimple
import com.machiav3lli.fdroid.ui.compose.theme.AppTheme
import com.machiav3lli.fdroid.ui.navigation.NavItem
import com.machiav3lli.fdroid.ui.viewmodels.MainNavFragmentViewModelX
import com.machiav3lli.fdroid.utility.isDarkTheme
import com.machiav3lli.fdroid.utility.onLaunchClick
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -87,133 +84,125 @@ fun InstalledPage(viewModel: MainNavFragmentViewModelX) {
}
}
AppTheme(
darkTheme = when (Preferences[Preferences.Key.Theme]) {
is Preferences.Theme.System -> isSystemInDarkTheme()
is Preferences.Theme.SystemBlack -> isSystemInDarkTheme()
else -> isDarkTheme
}
) {
var updatesVisible by remember(secondaryList) { mutableStateOf(true) }
var updatesVisible by remember(secondaryList) { mutableStateOf(true) }
Column(
Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize()
) {
AnimatedVisibility(visible = secondaryList.orEmpty().isNotEmpty()) {
Column {
Row(
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
verticalAlignment = Alignment.CenterVertically
Column(
Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize()
) {
AnimatedVisibility(visible = secondaryList.orEmpty().isNotEmpty()) {
Column {
Row(
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
verticalAlignment = Alignment.CenterVertically
) {
ElevatedButton(
colors = ButtonDefaults.elevatedButtonColors(
contentColor = MaterialTheme.colorScheme.primary
),
onClick = { updatesVisible = !updatesVisible }
) {
ElevatedButton(
colors = ButtonDefaults.elevatedButtonColors(
contentColor = MaterialTheme.colorScheme.primary
),
onClick = { updatesVisible = !updatesVisible }
) {
Text(
modifier = Modifier.padding(start = 4.dp),
text = stringResource(id = R.string.updates),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.titleSmall
)
Spacer(modifier = Modifier.width(8.dp))
Icon(
modifier = Modifier.size(18.dp),
imageVector = if (updatesVisible) Phosphor.CaretUp else Phosphor.CaretDown,
contentDescription = stringResource(id = R.string.updates)
)
}
Spacer(modifier = Modifier.weight(1f))
SuggestionChip(
shape = MaterialTheme.shapes.medium,
colors = SuggestionChipDefaults.suggestionChipColors(
containerColor = MaterialTheme.colorScheme.surface,
labelColor = MaterialTheme.colorScheme.onSurface,
),
onClick = {
secondaryList?.let {
mainActivityX.syncConnection.binder?.updateApps(
it.map(
Product::toItem
)
)
}
},
icon = {
Icon(
modifier = Modifier.size(18.dp),
imageVector = Phosphor.Download,
contentDescription = stringResource(id = R.string.update_all)
)
},
label = {
Text(text = stringResource(id = R.string.update_all))
}
Text(
modifier = Modifier.padding(start = 4.dp),
text = stringResource(id = R.string.updates),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.titleSmall
)
Spacer(modifier = Modifier.width(8.dp))
Icon(
modifier = Modifier.size(18.dp),
imageVector = if (updatesVisible) Phosphor.CaretUp else Phosphor.CaretDown,
contentDescription = stringResource(id = R.string.updates)
)
}
AnimatedVisibility(visible = updatesVisible) {
ProductsHorizontalRecycler(secondaryList, repositoriesMap) { item ->
mainActivityX.navigateProduct(item.packageName)
Spacer(modifier = Modifier.weight(1f))
SuggestionChip(
shape = MaterialTheme.shapes.medium,
colors = SuggestionChipDefaults.suggestionChipColors(
containerColor = MaterialTheme.colorScheme.surface,
labelColor = MaterialTheme.colorScheme.onSurface,
),
onClick = {
secondaryList?.let {
mainActivityX.syncConnection.binder?.updateApps(
it.map(
Product::toItem
)
)
}
},
icon = {
Icon(
modifier = Modifier.size(18.dp),
imageVector = Phosphor.Download,
contentDescription = stringResource(id = R.string.update_all)
)
},
label = {
Text(text = stringResource(id = R.string.update_all))
}
)
}
AnimatedVisibility(visible = updatesVisible) {
ProductsHorizontalRecycler(secondaryList, repositoriesMap) { item ->
mainActivityX.navigateProduct(item.packageName)
}
}
}
Row(
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = stringResource(id = R.string.installed_applications),
modifier = Modifier.weight(1f),
)
SuggestionChip(
shape = MaterialTheme.shapes.medium,
colors = SuggestionChipDefaults.suggestionChipColors(
containerColor = MaterialTheme.colorScheme.surface,
labelColor = MaterialTheme.colorScheme.onSurface,
),
onClick = {
mainActivityX.navigateSortFilter(NavItem.Installed.destination)
},
icon = {
Icon(
modifier = Modifier.size(18.dp),
imageVector = Phosphor.FunnelSimple,
contentDescription = stringResource(id = R.string.sort_filter)
)
},
label = {
Text(text = stringResource(id = R.string.sort_filter))
}
)
}
ProductsVerticalRecycler(
productsList = primaryList?.sortedBy { it.label.lowercase() },
repositories = repositoriesMap,
favorites = favorites,
modifier = Modifier
.fillMaxWidth()
.weight(1f),
onUserClick = { item ->
mainActivityX.navigateProduct(item.packageName)
}
Row(
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = stringResource(id = R.string.installed_applications),
modifier = Modifier.weight(1f),
)
SuggestionChip(
shape = MaterialTheme.shapes.medium,
colors = SuggestionChipDefaults.suggestionChipColors(
containerColor = MaterialTheme.colorScheme.surface,
labelColor = MaterialTheme.colorScheme.onSurface,
),
onClick = {
mainActivityX.navigateSortFilter(NavItem.Installed.destination)
},
onFavouriteClick = { item ->
viewModel.setFavorite(
item.packageName,
!favorites.contains(item.packageName)
icon = {
Icon(
modifier = Modifier.size(18.dp),
imageVector = Phosphor.FunnelSimple,
contentDescription = stringResource(id = R.string.sort_filter)
)
},
getInstalled = { installedList?.get(it.packageName) }
) { item ->
val installed = installedList?.get(item.packageName)
if (installed != null && installed.launcherActivities.isNotEmpty())
context.onLaunchClick(installed, mainActivityX.supportFragmentManager)
else
mainActivityX.syncConnection.binder?.installApps(listOf(item))
}
label = {
Text(text = stringResource(id = R.string.sort_filter))
}
)
}
ProductsVerticalRecycler(
productsList = primaryList?.sortedBy { it.label.lowercase() },
repositories = repositoriesMap,
favorites = favorites,
modifier = Modifier
.fillMaxWidth()
.weight(1f),
onUserClick = { item ->
mainActivityX.navigateProduct(item.packageName)
},
onFavouriteClick = { item ->
viewModel.setFavorite(
item.packageName,
!favorites.contains(item.packageName)
)
},
getInstalled = { installedList?.get(it.packageName) }
) { item ->
val installed = installedList?.get(item.packageName)
if (installed != null && installed.launcherActivities.isNotEmpty())
context.onLaunchClick(installed, mainActivityX.supportFragmentManager)
else
mainActivityX.syncConnection.binder?.installApps(listOf(item))
}
}
}

View File

@ -1,7 +1,6 @@
package com.machiav3lli.fdroid.ui.pages
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
@ -32,10 +31,8 @@ import com.machiav3lli.fdroid.ui.compose.ProductsHorizontalRecycler
import com.machiav3lli.fdroid.ui.compose.components.ProductsListItem
import com.machiav3lli.fdroid.ui.compose.icons.Phosphor
import com.machiav3lli.fdroid.ui.compose.icons.phosphor.FunnelSimple
import com.machiav3lli.fdroid.ui.compose.theme.AppTheme
import com.machiav3lli.fdroid.ui.navigation.NavItem
import com.machiav3lli.fdroid.ui.viewmodels.MainNavFragmentViewModelX
import com.machiav3lli.fdroid.utility.isDarkTheme
import com.machiav3lli.fdroid.utility.onLaunchClick
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -77,85 +74,77 @@ fun LatestPage(viewModel: MainNavFragmentViewModelX) {
}
}
AppTheme(
darkTheme = when (Preferences[Preferences.Key.Theme]) {
is Preferences.Theme.System -> isSystemInDarkTheme()
is Preferences.Theme.SystemBlack -> isSystemInDarkTheme()
else -> isDarkTheme
}
LazyColumn(
Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize(),
) {
LazyColumn(
Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize(),
) {
item {
item {
Text(
text = stringResource(id = R.string.new_applications),
modifier = Modifier.padding(8.dp)
)
ProductsHorizontalRecycler(secondaryList, repositoriesMap) { item ->
mainActivityX.navigateProduct(item.packageName)
}
}
item {
Row(
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = stringResource(id = R.string.new_applications),
modifier = Modifier.padding(8.dp)
text = stringResource(id = R.string.recently_updated),
modifier = Modifier.weight(1f),
)
ProductsHorizontalRecycler(secondaryList, repositoriesMap) { item ->
mainActivityX.navigateProduct(item.packageName)
}
}
item {
Row(
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = stringResource(id = R.string.recently_updated),
modifier = Modifier.weight(1f),
)
SuggestionChip(
shape = MaterialTheme.shapes.medium,
colors = SuggestionChipDefaults.suggestionChipColors(
containerColor = MaterialTheme.colorScheme.surface,
labelColor = MaterialTheme.colorScheme.onSurface,
),
onClick = {
mainActivityX.navigateSortFilter(NavItem.Latest.destination)
},
icon = {
Icon(
modifier = Modifier.size(18.dp),
imageVector = Phosphor.FunnelSimple,
contentDescription = stringResource(id = R.string.sort_filter)
)
},
label = {
Text(text = stringResource(id = R.string.sort_filter))
}
)
}
}
items(
items = primaryList?.map { it.toItem() } ?: emptyList(),
) { item ->
ProductsListItem(
item = item,
repo = repositoriesMap[item.repositoryId],
isFavorite = favorites.contains(item.packageName),
onUserClick = { mainActivityX.navigateProduct(it.packageName) },
onFavouriteClick = {
viewModel.setFavorite(
it.packageName,
!favorites.contains(it.packageName)
SuggestionChip(
shape = MaterialTheme.shapes.medium,
colors = SuggestionChipDefaults.suggestionChipColors(
containerColor = MaterialTheme.colorScheme.surface,
labelColor = MaterialTheme.colorScheme.onSurface,
),
onClick = {
mainActivityX.navigateSortFilter(NavItem.Latest.destination)
},
icon = {
Icon(
modifier = Modifier.size(18.dp),
imageVector = Phosphor.FunnelSimple,
contentDescription = stringResource(id = R.string.sort_filter)
)
},
installed = installedList?.get(item.packageName),
onActionClick = {
val installed = installedList?.get(it.packageName)
if (installed != null && installed.launcherActivities.isNotEmpty())
context.onLaunchClick(
installed,
mainActivityX.supportFragmentManager
)
else
mainActivityX.syncConnection.binder?.installApps(listOf(it))
label = {
Text(text = stringResource(id = R.string.sort_filter))
}
)
}
}
items(
items = primaryList?.map { it.toItem() } ?: emptyList(),
) { item ->
ProductsListItem(
item = item,
repo = repositoriesMap[item.repositoryId],
isFavorite = favorites.contains(item.packageName),
onUserClick = { mainActivityX.navigateProduct(it.packageName) },
onFavouriteClick = {
viewModel.setFavorite(
it.packageName,
!favorites.contains(it.packageName)
)
},
installed = installedList?.get(item.packageName),
onActionClick = {
val installed = installedList?.get(it.packageName)
if (installed != null && installed.launcherActivities.isNotEmpty())
context.onLaunchClick(
installed,
mainActivityX.supportFragmentManager
)
else
mainActivityX.syncConnection.binder?.installApps(listOf(it))
}
)
}
}
}

View File

@ -41,7 +41,6 @@ fun PrefsOtherPage() {
Preferences.Key.ProxyHost,
Preferences.Key.ProxyPort,
)
val infoPrefs = emptyList<Preferences.Key<*>>()
Scaffold(
modifier = Modifier.fillMaxSize()