Skip to content

Commit

Permalink
- Feat: Implement source order screen
Browse files Browse the repository at this point in the history
This commit introduces a new screen for customizing the order of sources.

It includes:
- Adding SourceOrder entity
 to store source order.
- Implementing UI for the source order screen.
- Adding navigation to the source order screen from settings.
- Modifying source list to use the order from SourceOrder.
- Adding logic to persist the order to the database.
  • Loading branch information
jacobrein committed Oct 8, 2024
1 parent 725a82e commit eb7ba0f
Show file tree
Hide file tree
Showing 13 changed files with 318 additions and 20 deletions.
6 changes: 4 additions & 2 deletions UIViews/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,15 @@ dependencies {

implementation(libs.material.kolor)

implementation("com.vanniktech:blurhash:0.4.0-SNAPSHOT")
implementation(libs.blurhash)
ksp(libs.roomCompiler)

implementation("androidx.biometric:biometric:1.4.0-alpha02")
implementation(libs.biometric)

implementation(projects.gemini)

implementation(libs.reorderable)

//TODO: Use this to check recomposition count on every screen
//implementation("io.github.theapache64:rebugger:1.0.0-rc03")
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberPermissionState
import com.programmersbox.extensionloader.SourceRepository
import com.programmersbox.favoritesdatabase.ItemDatabase
import com.programmersbox.favoritesdatabase.SourceOrder
import com.programmersbox.gemini.GeminiRecommendationScreen
import com.programmersbox.helpfulutils.notificationManager
import com.programmersbox.sharedutils.AppLogo
Expand All @@ -152,6 +153,7 @@ import com.programmersbox.uiviews.settings.MoreSettingsScreen
import com.programmersbox.uiviews.settings.NotificationSettings
import com.programmersbox.uiviews.settings.PlaySettings
import com.programmersbox.uiviews.settings.SettingScreen
import com.programmersbox.uiviews.settings.SourceOrderScreen
import com.programmersbox.uiviews.utils.ChromeCustomTabsNavigator
import com.programmersbox.uiviews.utils.LocalNavHostPadding
import com.programmersbox.uiviews.utils.LocalWindowSizeClass
Expand Down Expand Up @@ -228,6 +230,21 @@ abstract class BaseMainActivity : AppCompatActivity() {
}
.launchIn(lifecycleScope)

sourceRepository.sources
.onEach {
val itemDao = itemDatabase.itemDao()
it.forEachIndexed { index, sourceInformation ->
itemDao.insertSourceOrder(
SourceOrder(
source = sourceInformation.packageName,
name = sourceInformation.apiService.serviceName,
order = index
)
)
}
}
.launchIn(lifecycleScope)

setContent {
navController = rememberNavController(
remember { ChromeCustomTabsNavigator(this) }
Expand Down Expand Up @@ -754,10 +771,16 @@ abstract class BaseMainActivity : AppCompatActivity() {
otherClick = { navController.navigate(Screen.OtherSettings) },
moreInfoClick = { navController.navigate(Screen.MoreInfoSettings) },
moreSettingsClick = { navController.navigate(Screen.MoreSettings) },
geminiClick = { navController.navigate(Screen.GeminiScreen) }
geminiClick = { navController.navigate(Screen.GeminiScreen) },
sourcesOrderClick = { navController.navigate(Screen.OrderScreen) }
)
}

composable<Screen.OrderScreen>(
enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start) },
exitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.End) },
) { SourceOrderScreen() }

composable<Screen.NotificationsSettings>(
enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start) },
exitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.End) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -495,10 +495,7 @@ fun DetailFloatingActionButtonMenu(
)

FloatingActionButtonMenuItem(
onClick = {
fabMenuExpanded = false
onFavoriteClick(isFavorite)
},
onClick = { onFavoriteClick(isFavorite) },
icon = {
Icon(
if (isFavorite) Icons.Default.Favorite else Icons.Default.FavoriteBorder,
Expand All @@ -510,10 +507,7 @@ fun DetailFloatingActionButtonMenu(

if (isFavorite && LocalContext.current.shouldCheckFlow.collectAsStateWithLifecycle(initialValue = true).value) {
FloatingActionButtonMenuItem(
onClick = {
fabMenuExpanded = false
notifyAction()
},
onClick = notifyAction,
icon = {
Icon(
if (canNotify) Icons.Default.NotificationsActive else Icons.Default.NotificationsOff,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ import com.programmersbox.uiviews.utils.LocalSettingsHandling
import com.programmersbox.uiviews.utils.NotificationLogo
import com.programmersbox.uiviews.utils.components.OtakuScaffold
import com.programmersbox.uiviews.utils.components.ToolTipWrapper
import com.programmersbox.uiviews.utils.components.minus
import com.programmersbox.uiviews.utils.isScrollingUp
import dev.chrisbanes.haze.HazeState
import dev.chrisbanes.haze.haze
Expand Down Expand Up @@ -344,7 +343,7 @@ fun DetailsView(
.nestedScroll(collapsableBehavior.nestedScrollConnection)
.nestedScroll(scrollBehavior.nestedScrollConnection)
) { p ->
val modifiedPaddingValues = p - LocalNavHostPadding.current
val modifiedPaddingValues = p// - LocalNavHostPadding.current
var descriptionVisibility by remember { mutableStateOf(false) }
val listOfChapters = remember(reverseChapters) {
info.chapters.let { if (reverseChapters) it.reversed() else it }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.programmersbox.sharedutils.FirebaseDb
import com.programmersbox.uiviews.CurrentSourceRepository
import com.programmersbox.uiviews.utils.DefaultToastItems
import com.programmersbox.uiviews.utils.ToastItems
import com.programmersbox.uiviews.utils.combineSources
import com.programmersbox.uiviews.utils.dispatchIo
import com.programmersbox.uiviews.utils.recordFirebaseException
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -61,7 +62,7 @@ class RecentViewModel(
val sources = mutableStateListOf<SourceInformation>()

init {
sourceRepository.sources
combineSources(sourceRepository, dao)
.onEach {
sources.clear()
sources.addAll(it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import androidx.compose.material.icons.filled.Notifications
import androidx.compose.material.icons.filled.OpenInBrowser
import androidx.compose.material.icons.filled.PhoneAndroid
import androidx.compose.material.icons.filled.PlayCircleOutline
import androidx.compose.material.icons.filled.Reorder
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.Source
Expand Down Expand Up @@ -56,6 +57,7 @@ import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.SubcomposeAsyncImage
import coil.compose.SubcomposeAsyncImageContent
Expand Down Expand Up @@ -88,6 +90,7 @@ import com.programmersbox.uiviews.utils.components.OtakuScaffold
import com.programmersbox.uiviews.utils.currentService
import com.programmersbox.uiviews.utils.showSourceChooser
import com.programmersbox.uiviews.utils.showTranslationScreen
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
import org.koin.compose.koinInject
import java.util.Locale
Expand Down Expand Up @@ -128,6 +131,7 @@ fun SettingScreen(
moreInfoClick: () -> Unit = {},
moreSettingsClick: () -> Unit = {},
geminiClick: () -> Unit = {},
sourcesOrderClick: () -> Unit = {},
) {
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState())

Expand Down Expand Up @@ -165,7 +169,8 @@ fun SettingScreen(
otherClick = otherClick,
moreInfoClick = moreInfoClick,
moreSettingsClick = moreSettingsClick,
geminiClick = geminiClick
geminiClick = geminiClick,
sourcesOrderClick = sourcesOrderClick
)
}
}
Expand Down Expand Up @@ -302,6 +307,7 @@ private fun SettingsScreen(
moreInfoClick: () -> Unit,
moreSettingsClick: () -> Unit,
geminiClick: () -> Unit,
sourcesOrderClick: () -> Unit,
) {
val uriHandler = LocalUriHandler.current
val source by LocalCurrentSource.current.asFlow().collectAsState(initial = null)
Expand Down Expand Up @@ -391,6 +397,16 @@ private fun SettingsScreen(
) { showSourceChooser = true }
)

PreferenceSetting(
settingTitle = { Text("Sources Order") },
settingIcon = { Icon(Icons.Default.Reorder, null, modifier = Modifier.fillMaxSize()) },
modifier = Modifier.clickable(
indication = ripple(),
interactionSource = null,
onClick = sourcesOrderClick
)
)

PreferenceSetting(
settingTitle = { Text(stringResource(R.string.view_extensions)) },
settingIcon = { Icon(Icons.Default.Extension, null, modifier = Modifier.fillMaxSize()) },
Expand Down Expand Up @@ -506,7 +522,8 @@ private fun SettingsPreview() {
otherClick = {},
moreInfoClick = {},
moreSettingsClick = {},
geminiClick = {}
geminiClick = {},
sourcesOrderClick = {}
)
}
}
Expand Down Expand Up @@ -588,11 +605,23 @@ fun SourceChooserScreen(
val context = LocalContext.current
val sourceRepository = LocalSourcesRepository.current
val currentSourceRepository = LocalCurrentSource.current
val itemDao = LocalItemDao.current

ListBottomScreen(
includeInsetPadding = true,
title = stringResource(R.string.chooseASource),
list = sourceRepository.list.filterNot { it.apiService.notWorking },
list = remember {
combine(
sourceRepository.sources,
itemDao.getSourceOrder()
) { list, order ->
list
.filterNot { it.apiService.notWorking }
.sortedBy { order.find { o -> o.source == it.packageName }?.order ?: 0 }
}
}
.collectAsStateWithLifecycle(emptyList())
.value,
onClick = { service ->
onChosen()
scope.launch {
Expand Down
Loading

0 comments on commit eb7ba0f

Please sign in to comment.