Change the system theme + filter bottomsheet
This commit is contained in:
		
							parent
							
								
									785e181482
								
							
						
					
					
						commit
						7cc08cf300
					
				
					 19 changed files with 387 additions and 147 deletions
				
			
		| 
						 | 
				
			
			@ -9,7 +9,6 @@ import androidx.compose.material.Surface
 | 
			
		|||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
 | 
			
		||||
import androidx.core.view.WindowCompat
 | 
			
		||||
import com.pixelized.biblib.ui.composable.SystemThemeColor
 | 
			
		||||
import com.pixelized.biblib.ui.screen.launch.LauncherViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.theme.BibLibTheme
 | 
			
		||||
import dagger.hilt.android.AndroidEntryPoint
 | 
			
		||||
| 
						 | 
				
			
			@ -48,12 +47,10 @@ class MainActivity : ComponentActivity() {
 | 
			
		|||
        content: @Composable () -> Unit,
 | 
			
		||||
    ) {
 | 
			
		||||
        BibLibTheme {
 | 
			
		||||
            SystemThemeColor {
 | 
			
		||||
                Surface(
 | 
			
		||||
                    color = MaterialTheme.colors.surface,
 | 
			
		||||
                    content = content,
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
            Surface(
 | 
			
		||||
                color = MaterialTheme.colors.surface,
 | 
			
		||||
                content = content,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
package com.pixelized.biblib.ui.composable
 | 
			
		||||
 | 
			
		||||
import androidx.compose.foundation.background
 | 
			
		||||
import androidx.compose.foundation.layout.Box
 | 
			
		||||
import androidx.compose.foundation.layout.size
 | 
			
		||||
import androidx.compose.foundation.shape.CircleShape
 | 
			
		||||
import androidx.compose.material.MaterialTheme
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.ui.Modifier
 | 
			
		||||
import androidx.compose.ui.graphics.Color
 | 
			
		||||
import androidx.compose.ui.graphics.Shape
 | 
			
		||||
import androidx.compose.ui.unit.Dp
 | 
			
		||||
import com.pixelized.biblib.utils.extention.bibLib
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
fun Handle(
 | 
			
		||||
    modifier: Modifier = Modifier,
 | 
			
		||||
    width: Dp = MaterialTheme.bibLib.dimen.handle.width,
 | 
			
		||||
    thickness: Dp = MaterialTheme.bibLib.dimen.handle.thickness,
 | 
			
		||||
    color: Color = MaterialTheme.bibLib.colors.handle,
 | 
			
		||||
    shape: Shape = CircleShape
 | 
			
		||||
) = Box(
 | 
			
		||||
    modifier = modifier
 | 
			
		||||
        .size(width = width, height = thickness)
 | 
			
		||||
        .background(
 | 
			
		||||
            color = color,
 | 
			
		||||
            shape = shape,
 | 
			
		||||
        )
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,139 @@
 | 
			
		|||
package com.pixelized.biblib.ui.composable
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint
 | 
			
		||||
import androidx.compose.foundation.background
 | 
			
		||||
import androidx.compose.foundation.layout.Box
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxSize
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxWidth
 | 
			
		||||
import androidx.compose.foundation.layout.height
 | 
			
		||||
import androidx.compose.runtime.*
 | 
			
		||||
import androidx.compose.ui.Alignment
 | 
			
		||||
import androidx.compose.ui.Modifier
 | 
			
		||||
import androidx.compose.ui.graphics.Brush
 | 
			
		||||
import androidx.compose.ui.graphics.Color
 | 
			
		||||
import androidx.compose.ui.unit.Dp
 | 
			
		||||
import com.google.accompanist.systemuicontroller.SystemUiController
 | 
			
		||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
 | 
			
		||||
import com.pixelized.biblib.utils.extention.navigationBarsHeight
 | 
			
		||||
import com.pixelized.biblib.utils.extention.statusBarsHeight
 | 
			
		||||
 | 
			
		||||
val LocalStatusTheme = staticCompositionLocalOf<StatusThemeController> {
 | 
			
		||||
    error("LocalStatusTheme is not ready yet.")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class StatusThemeController(
 | 
			
		||||
    private val systemController: SystemUiController,
 | 
			
		||||
    private val statusBackground: MutableState<Brush>,
 | 
			
		||||
    private var statusDarkIcons: Boolean,
 | 
			
		||||
    private val navigationBackground: MutableState<Brush>,
 | 
			
		||||
    private var navigationDarkIcons: Boolean,
 | 
			
		||||
) {
 | 
			
		||||
    init {
 | 
			
		||||
        systemController.setStatusBarColor(
 | 
			
		||||
            color = Color.Transparent,
 | 
			
		||||
            darkIcons = statusDarkIcons,
 | 
			
		||||
        )
 | 
			
		||||
        systemController.setNavigationBarColor(
 | 
			
		||||
            color = Color.Transparent,
 | 
			
		||||
            darkIcons = navigationDarkIcons,
 | 
			
		||||
            navigationBarContrastEnforced = false,
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun updateStatusTheme(
 | 
			
		||||
        statusBackground: Brush = this.statusBackground.value,
 | 
			
		||||
        statusDarkIcons: Boolean = this.statusDarkIcons,
 | 
			
		||||
        navigationBackground: Brush = this.navigationBackground.value,
 | 
			
		||||
        navigationDarkIcons: Boolean = this.navigationDarkIcons,
 | 
			
		||||
    ) {
 | 
			
		||||
        if (this.statusDarkIcons != statusDarkIcons) {
 | 
			
		||||
            this.statusDarkIcons = statusDarkIcons
 | 
			
		||||
            systemController.setStatusBarColor(
 | 
			
		||||
                color = Color.Transparent,
 | 
			
		||||
                darkIcons = statusDarkIcons,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        if (this.statusBackground.value != statusBackground) {
 | 
			
		||||
            this.statusBackground.value = statusBackground
 | 
			
		||||
        }
 | 
			
		||||
        if (navigationDarkIcons != this.navigationDarkIcons) {
 | 
			
		||||
            this.navigationDarkIcons = navigationDarkIcons
 | 
			
		||||
            systemController.setNavigationBarColor(
 | 
			
		||||
                color = Color.Transparent,
 | 
			
		||||
                darkIcons = navigationDarkIcons,
 | 
			
		||||
                navigationBarContrastEnforced = false,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        if (this.navigationBackground.value != navigationBackground) {
 | 
			
		||||
            this.statusBackground.value = navigationBackground
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
fun SystemTheme(
 | 
			
		||||
    systemController: SystemUiController = rememberSystemUiController(),
 | 
			
		||||
    statusBackground: Color,
 | 
			
		||||
    statusDarkIcons: Boolean,
 | 
			
		||||
    navigationBackground: Color,
 | 
			
		||||
    navigationDarkIcons: Boolean,
 | 
			
		||||
    content: @Composable () -> Unit,
 | 
			
		||||
) {
 | 
			
		||||
    val statusBackgroundState = remember {
 | 
			
		||||
        mutableStateOf(
 | 
			
		||||
            Brush.verticalGradient(
 | 
			
		||||
                colors = listOf(statusBackground, Color.Transparent)
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
    val navigationBackgroundState = remember {
 | 
			
		||||
        mutableStateOf(
 | 
			
		||||
            Brush.verticalGradient(
 | 
			
		||||
                colors = listOf(Color.Transparent, navigationBackground)
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
    val statusController = remember(systemController) {
 | 
			
		||||
        StatusThemeController(
 | 
			
		||||
            systemController = systemController,
 | 
			
		||||
            statusBackground = statusBackgroundState,
 | 
			
		||||
            statusDarkIcons = statusDarkIcons,
 | 
			
		||||
            navigationBackground = navigationBackgroundState,
 | 
			
		||||
            navigationDarkIcons = navigationDarkIcons,
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
    CompositionLocalProvider(
 | 
			
		||||
        LocalStatusTheme provides statusController,
 | 
			
		||||
    ) {
 | 
			
		||||
        Box(
 | 
			
		||||
            modifier = Modifier.fillMaxSize(),
 | 
			
		||||
        ) {
 | 
			
		||||
            content()
 | 
			
		||||
 | 
			
		||||
            Overlay(
 | 
			
		||||
                height = statusBarsHeight(),
 | 
			
		||||
                brush = statusBackgroundState,
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            Overlay(
 | 
			
		||||
                modifier = Modifier.align(Alignment.BottomStart),
 | 
			
		||||
                height = navigationBarsHeight(),
 | 
			
		||||
                brush = navigationBackgroundState,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
private fun Overlay(
 | 
			
		||||
    modifier: Modifier = Modifier,
 | 
			
		||||
    height: Dp,
 | 
			
		||||
    brush: State<Brush>,
 | 
			
		||||
) {
 | 
			
		||||
    Box(
 | 
			
		||||
        modifier = modifier
 | 
			
		||||
            .height(height = height)
 | 
			
		||||
            .fillMaxWidth()
 | 
			
		||||
            .background(brush = brush.value)
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,36 +0,0 @@
 | 
			
		|||
package com.pixelized.biblib.ui.composable
 | 
			
		||||
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.runtime.CompositionLocalProvider
 | 
			
		||||
import androidx.compose.runtime.SideEffect
 | 
			
		||||
import androidx.compose.runtime.compositionLocalOf
 | 
			
		||||
import androidx.compose.ui.graphics.Color
 | 
			
		||||
import com.google.accompanist.systemuicontroller.SystemUiController
 | 
			
		||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
 | 
			
		||||
import com.pixelized.biblib.ui.theme.color.ShadowPalette
 | 
			
		||||
 | 
			
		||||
val LocalSystemUiController = compositionLocalOf<SystemUiController> { error("") }
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
fun SystemThemeColor(
 | 
			
		||||
    systemUiController: SystemUiController = rememberSystemUiController(),
 | 
			
		||||
    color: Color = ShadowPalette.system,
 | 
			
		||||
    statusDarkIcons: Boolean = false,
 | 
			
		||||
    navigationDarkIcons: Boolean = false,
 | 
			
		||||
    content: @Composable () -> Unit,
 | 
			
		||||
) {
 | 
			
		||||
    CompositionLocalProvider(LocalSystemUiController provides systemUiController) {
 | 
			
		||||
        SideEffect {
 | 
			
		||||
            systemUiController.setStatusBarColor(
 | 
			
		||||
                color = color,
 | 
			
		||||
                darkIcons = statusDarkIcons,
 | 
			
		||||
            )
 | 
			
		||||
            systemUiController.setNavigationBarColor(
 | 
			
		||||
                color = color,
 | 
			
		||||
                darkIcons = navigationDarkIcons,
 | 
			
		||||
                navigationBarContrastEnforced = false,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        content()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
package com.pixelized.biblib.ui.composable
 | 
			
		||||
 | 
			
		||||
import androidx.compose.material.LocalAbsoluteElevation
 | 
			
		||||
import androidx.compose.material.LocalElevationOverlay
 | 
			
		||||
import androidx.compose.material.MaterialTheme
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.ui.graphics.Color
 | 
			
		||||
import androidx.compose.ui.unit.Dp
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
fun colorElevation(
 | 
			
		||||
    base: Color = MaterialTheme.colors.surface,
 | 
			
		||||
    elevation: Dp,
 | 
			
		||||
): Color {
 | 
			
		||||
    val localElevation = LocalElevationOverlay.current
 | 
			
		||||
    val absoluteElevation = LocalAbsoluteElevation.current
 | 
			
		||||
    return localElevation?.apply(color = base, elevation = absoluteElevation + elevation) ?: base
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,18 +2,18 @@ package com.pixelized.biblib.ui.composable.scaffold
 | 
			
		|||
 | 
			
		||||
import androidx.activity.compose.BackHandler
 | 
			
		||||
import androidx.compose.foundation.layout.Box
 | 
			
		||||
import androidx.compose.foundation.layout.BoxWithConstraints
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxWidth
 | 
			
		||||
import androidx.compose.foundation.layout.height
 | 
			
		||||
import androidx.compose.material.ExperimentalMaterialApi
 | 
			
		||||
import androidx.compose.material.ModalBottomSheetLayout
 | 
			
		||||
import androidx.compose.material.ModalBottomSheetState
 | 
			
		||||
import androidx.compose.material.*
 | 
			
		||||
import androidx.compose.material.ModalBottomSheetValue.Hidden
 | 
			
		||||
import androidx.compose.material.rememberModalBottomSheetState
 | 
			
		||||
import androidx.compose.runtime.*
 | 
			
		||||
import androidx.compose.ui.ExperimentalComposeUiApi
 | 
			
		||||
import androidx.compose.ui.Modifier
 | 
			
		||||
import androidx.compose.ui.focus.FocusManager
 | 
			
		||||
import androidx.compose.ui.focus.FocusRequester
 | 
			
		||||
import androidx.compose.ui.graphics.Color
 | 
			
		||||
import androidx.compose.ui.graphics.Shape
 | 
			
		||||
import androidx.compose.ui.platform.LocalFocusManager
 | 
			
		||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
 | 
			
		||||
import androidx.compose.ui.unit.dp
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +26,8 @@ import com.pixelized.biblib.ui.screen.home.filter.viewModel.AuthorFilterViewMode
 | 
			
		|||
import com.pixelized.biblib.ui.screen.home.filter.viewModel.GenreFilterViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.screen.home.filter.viewModel.LanguageFilterViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.screen.home.filter.viewModel.SeriesFilterViewModel
 | 
			
		||||
import com.pixelized.biblib.utils.extention.bibLib
 | 
			
		||||
import com.pixelized.biblib.utils.extention.statusBarsHeight
 | 
			
		||||
import kotlinx.coroutines.CancellableContinuation
 | 
			
		||||
import kotlinx.coroutines.suspendCancellableCoroutine
 | 
			
		||||
import kotlinx.coroutines.sync.Mutex
 | 
			
		||||
| 
						 | 
				
			
			@ -102,6 +104,7 @@ fun FilterBottomSheet(
 | 
			
		|||
        skipHalfExpanded = true,
 | 
			
		||||
    ),
 | 
			
		||||
    sheetState: FilterBottomSheetState = rememberFilterBottomSheetState(),
 | 
			
		||||
    sheetShape: Shape = MaterialTheme.bibLib.shapes.filterSheet,
 | 
			
		||||
    content: @Composable () -> Unit,
 | 
			
		||||
) {
 | 
			
		||||
    CompositionLocalProvider(
 | 
			
		||||
| 
						 | 
				
			
			@ -134,47 +137,53 @@ fun FilterBottomSheet(
 | 
			
		|||
            onBack = { currentBottomSheetData?.dismiss() },
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        ModalBottomSheetLayout(
 | 
			
		||||
            sheetState = bottomSheetState,
 | 
			
		||||
            content = content,
 | 
			
		||||
            scrimColor = Color.Transparent,
 | 
			
		||||
            sheetContent = {
 | 
			
		||||
                val viewModel: IFilterViewModel? = when (sheetState.type) {
 | 
			
		||||
                    FilterType.Author -> hiltViewModel<AuthorFilterViewModel>()
 | 
			
		||||
                    FilterType.Series -> hiltViewModel<SeriesFilterViewModel>()
 | 
			
		||||
                    FilterType.Genre -> hiltViewModel<GenreFilterViewModel>()
 | 
			
		||||
                    FilterType.Language -> hiltViewModel<LanguageFilterViewModel>()
 | 
			
		||||
                    else -> null
 | 
			
		||||
                }
 | 
			
		||||
        BoxWithConstraints {
 | 
			
		||||
            val statusBarHeight = statusBarsHeight()
 | 
			
		||||
            val bottomSheetHeight = remember(statusBarHeight) {
 | 
			
		||||
                maxHeight - statusBarHeight - 16.dp
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
                if (viewModel != null) {
 | 
			
		||||
                    val focusRequester = remember { FocusRequester() }
 | 
			
		||||
 | 
			
		||||
                    FilterPage(
 | 
			
		||||
                        viewModel = viewModel,
 | 
			
		||||
                        focusRequester = focusRequester,
 | 
			
		||||
                        onFilter = {
 | 
			
		||||
                            currentBottomSheetData?.performAction(filter = it)
 | 
			
		||||
                        },
 | 
			
		||||
                        onClose = {
 | 
			
		||||
                            currentBottomSheetData?.dismiss()
 | 
			
		||||
                        },
 | 
			
		||||
                        onIMEDone = {
 | 
			
		||||
                            currentBottomSheetData?.dismiss()
 | 
			
		||||
                        }
 | 
			
		||||
                    )
 | 
			
		||||
 | 
			
		||||
                    LaunchedEffect(key1 = "FilterPageFocusRequest-${sheetState.type}") {
 | 
			
		||||
                        if (currentBottomSheetData != null) {
 | 
			
		||||
                            focusRequester.requestFocus()
 | 
			
		||||
                            keyboard?.show()
 | 
			
		||||
                        }
 | 
			
		||||
            ModalBottomSheetLayout(
 | 
			
		||||
                sheetState = bottomSheetState,
 | 
			
		||||
                sheetShape = sheetShape,
 | 
			
		||||
                content = content,
 | 
			
		||||
                scrimColor = Color.Transparent,
 | 
			
		||||
                sheetContent = {
 | 
			
		||||
                    val viewModel: IFilterViewModel? = when (sheetState.type) {
 | 
			
		||||
                        FilterType.Author -> hiltViewModel<AuthorFilterViewModel>()
 | 
			
		||||
                        FilterType.Series -> hiltViewModel<SeriesFilterViewModel>()
 | 
			
		||||
                        FilterType.Genre -> hiltViewModel<GenreFilterViewModel>()
 | 
			
		||||
                        FilterType.Language -> hiltViewModel<LanguageFilterViewModel>()
 | 
			
		||||
                        else -> null
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    Box(modifier = Modifier.height(1.dp))
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
                    if (viewModel != null) {
 | 
			
		||||
                        val focusRequester = remember { FocusRequester() }
 | 
			
		||||
 | 
			
		||||
                        FilterPage(
 | 
			
		||||
                            modifier = Modifier
 | 
			
		||||
                                .fillMaxWidth()
 | 
			
		||||
                                .height(bottomSheetHeight),
 | 
			
		||||
                            viewModel = viewModel,
 | 
			
		||||
                            focusRequester = focusRequester,
 | 
			
		||||
                            onFilter = {
 | 
			
		||||
                                currentBottomSheetData?.performAction(filter = it)
 | 
			
		||||
                            },
 | 
			
		||||
                            onIMEDone = {
 | 
			
		||||
                                currentBottomSheetData?.dismiss()
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                        LaunchedEffect(key1 = "FilterPageFocusRequest-${sheetState.type}") {
 | 
			
		||||
                            if (currentBottomSheetData != null) {
 | 
			
		||||
                                focusRequester.requestFocus()
 | 
			
		||||
                                keyboard?.show()
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        Box(modifier = Modifier.height(1.dp))
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,6 +42,7 @@ import com.pixelized.biblib.model.search.FilterType
 | 
			
		|||
import com.pixelized.biblib.model.search.SortType
 | 
			
		||||
import com.pixelized.biblib.model.search.SortValue
 | 
			
		||||
import com.pixelized.biblib.ui.LocalSnackHostState
 | 
			
		||||
import com.pixelized.biblib.ui.composable.colorElevation
 | 
			
		||||
import com.pixelized.biblib.ui.composable.scaffold.*
 | 
			
		||||
import com.pixelized.biblib.ui.navigation.LocalScreenNavHostController
 | 
			
		||||
import com.pixelized.biblib.ui.navigation.navigateToProfile
 | 
			
		||||
| 
						 | 
				
			
			@ -444,14 +445,10 @@ private fun HomeToolbar(
 | 
			
		|||
    onAvatarTap: () -> Unit,
 | 
			
		||||
) {
 | 
			
		||||
    val direction = LocalLayoutDirection.current
 | 
			
		||||
    val elevation = LocalElevationOverlay.current
 | 
			
		||||
    Surface(
 | 
			
		||||
        modifier = modifier,
 | 
			
		||||
        shape = CircleShape,
 | 
			
		||||
        color = elevation?.apply(
 | 
			
		||||
            MaterialTheme.colors.surface,
 | 
			
		||||
            LocalAbsoluteElevation.current + 1.dp
 | 
			
		||||
        ) ?: MaterialTheme.colors.surface,
 | 
			
		||||
        color = colorElevation(elevation = 1.dp),
 | 
			
		||||
    ) {
 | 
			
		||||
        Row(
 | 
			
		||||
            modifier = Modifier.padding(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,6 +36,7 @@ import com.bumptech.glide.load.engine.GlideException
 | 
			
		|||
import com.bumptech.glide.request.RequestListener
 | 
			
		||||
import com.bumptech.glide.request.target.Target
 | 
			
		||||
import com.pixelized.biblib.R
 | 
			
		||||
import com.pixelized.biblib.ui.composable.Handle
 | 
			
		||||
import com.pixelized.biblib.ui.composable.SpannedText
 | 
			
		||||
import com.pixelized.biblib.ui.composable.animation.AnimatedDelayer
 | 
			
		||||
import com.pixelized.biblib.ui.composable.animation.AnimatedOffset
 | 
			
		||||
| 
						 | 
				
			
			@ -117,6 +118,7 @@ fun DetailScreenContent(
 | 
			
		|||
                    .verticalScroll(rememberScrollState())
 | 
			
		||||
                    .padding(all = 16.dp)
 | 
			
		||||
                    .systemBarsPadding(),
 | 
			
		||||
                horizontalAlignment = Alignment.CenterHorizontally,
 | 
			
		||||
                verticalArrangement = Arrangement.spacedBy(16.dp)
 | 
			
		||||
            ) {
 | 
			
		||||
                Column(
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +150,6 @@ fun DetailScreenContent(
 | 
			
		|||
 | 
			
		||||
                AnimatedOffset {
 | 
			
		||||
                    Column(
 | 
			
		||||
                        modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
                        horizontalAlignment = Alignment.CenterHorizontally,
 | 
			
		||||
                    ) {
 | 
			
		||||
                        Text(
 | 
			
		||||
| 
						 | 
				
			
			@ -161,7 +162,7 @@ fun DetailScreenContent(
 | 
			
		|||
                            Text(
 | 
			
		||||
                                modifier = Modifier.clickable(onClick = { onSeries(series) }),
 | 
			
		||||
                                style = MaterialTheme.typography.body1,
 | 
			
		||||
                                color = MaterialTheme.colors.onSurface,
 | 
			
		||||
                                color = MaterialTheme.bibLib.colors.typography.emphasis,
 | 
			
		||||
                                textAlign = TextAlign.Center,
 | 
			
		||||
                                text = series.label,
 | 
			
		||||
                            )
 | 
			
		||||
| 
						 | 
				
			
			@ -171,15 +172,14 @@ fun DetailScreenContent(
 | 
			
		|||
 | 
			
		||||
                AnimatedOffset {
 | 
			
		||||
                    Column(
 | 
			
		||||
                        modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
                        horizontalAlignment = Alignment.CenterHorizontally,
 | 
			
		||||
                    ) {
 | 
			
		||||
                        book.authors.forEach { author ->
 | 
			
		||||
                            Text(
 | 
			
		||||
                                modifier = Modifier.clickable(onClick = { onAuthor(author) }),
 | 
			
		||||
                                fontWeight = FontWeight.Bold,
 | 
			
		||||
                                fontWeight = FontWeight.Normal,
 | 
			
		||||
                                style = MaterialTheme.typography.h6,
 | 
			
		||||
                                color = MaterialTheme.colors.onSurface,
 | 
			
		||||
                                color = MaterialTheme.bibLib.colors.typography.emphasis,
 | 
			
		||||
                                textAlign = TextAlign.Center,
 | 
			
		||||
                                text = author.name,
 | 
			
		||||
                            )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,10 @@
 | 
			
		|||
package com.pixelized.biblib.ui.screen.home.filter
 | 
			
		||||
 | 
			
		||||
import android.content.res.Configuration.UI_MODE_NIGHT_NO
 | 
			
		||||
import android.content.res.Configuration.UI_MODE_NIGHT_YES
 | 
			
		||||
import androidx.compose.animation.AnimatedVisibility
 | 
			
		||||
import androidx.compose.animation.fadeIn
 | 
			
		||||
import androidx.compose.animation.fadeOut
 | 
			
		||||
import androidx.compose.foundation.clickable
 | 
			
		||||
import androidx.compose.foundation.layout.*
 | 
			
		||||
import androidx.compose.foundation.lazy.LazyColumn
 | 
			
		||||
| 
						 | 
				
			
			@ -8,24 +13,27 @@ import androidx.compose.foundation.text.KeyboardActions
 | 
			
		|||
import androidx.compose.foundation.text.KeyboardOptions
 | 
			
		||||
import androidx.compose.material.*
 | 
			
		||||
import androidx.compose.material.icons.Icons
 | 
			
		||||
import androidx.compose.material.icons.filled.Close
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.runtime.Immutable
 | 
			
		||||
import androidx.compose.runtime.Stable
 | 
			
		||||
import androidx.compose.runtime.State
 | 
			
		||||
import androidx.compose.material.icons.filled.Clear
 | 
			
		||||
import androidx.compose.runtime.*
 | 
			
		||||
import androidx.compose.ui.Alignment
 | 
			
		||||
import androidx.compose.ui.Modifier
 | 
			
		||||
import androidx.compose.ui.focus.FocusRequester
 | 
			
		||||
import androidx.compose.ui.focus.focusRequester
 | 
			
		||||
import androidx.compose.ui.graphics.Color
 | 
			
		||||
import androidx.compose.ui.res.stringResource
 | 
			
		||||
import androidx.compose.ui.text.input.ImeAction
 | 
			
		||||
import androidx.compose.ui.tooling.preview.Preview
 | 
			
		||||
import androidx.compose.ui.unit.dp
 | 
			
		||||
import androidx.compose.ui.unit.max
 | 
			
		||||
import androidx.paging.PagingData
 | 
			
		||||
import androidx.paging.compose.LazyPagingItems
 | 
			
		||||
import androidx.paging.compose.collectAsLazyPagingItems
 | 
			
		||||
import androidx.paging.compose.items
 | 
			
		||||
import com.pixelized.biblib.R
 | 
			
		||||
import com.pixelized.biblib.model.search.FilterType
 | 
			
		||||
import com.pixelized.biblib.ui.composable.Handle
 | 
			
		||||
import com.pixelized.biblib.ui.theme.BibLibTheme
 | 
			
		||||
import com.pixelized.biblib.utils.extention.bibLib
 | 
			
		||||
import com.pixelized.biblib.utils.extention.imeHeight
 | 
			
		||||
import com.pixelized.biblib.utils.extention.navigationBarsHeight
 | 
			
		||||
import kotlinx.coroutines.flow.emptyFlow
 | 
			
		||||
 | 
			
		||||
@Stable
 | 
			
		||||
@Immutable
 | 
			
		||||
| 
						 | 
				
			
			@ -37,26 +45,23 @@ data class FilterItemUio(
 | 
			
		|||
 | 
			
		||||
@Composable
 | 
			
		||||
fun FilterPage(
 | 
			
		||||
    modifier: Modifier,
 | 
			
		||||
    viewModel: IFilterViewModel,
 | 
			
		||||
    focusRequester: FocusRequester,
 | 
			
		||||
    onFilter: (FilterItemUio) -> Unit,
 | 
			
		||||
    onClose: () -> Unit,
 | 
			
		||||
    onIMEDone: KeyboardActionScope.() -> Unit,
 | 
			
		||||
) {
 | 
			
		||||
    val filters = viewModel.paging.collectAsLazyPagingItems()
 | 
			
		||||
 | 
			
		||||
    FilterPageContent(
 | 
			
		||||
        modifier = Modifier
 | 
			
		||||
            .fillMaxSize()
 | 
			
		||||
            .imePadding()
 | 
			
		||||
            .systemBarsPadding(),
 | 
			
		||||
        modifier = modifier,
 | 
			
		||||
        focusRequester = focusRequester,
 | 
			
		||||
        title = viewModel.title,
 | 
			
		||||
        search = viewModel.search,
 | 
			
		||||
        onSearchUpdate = { viewModel.updateSearch(it) },
 | 
			
		||||
        onClear = { viewModel.updateSearch("") },
 | 
			
		||||
        filters = filters,
 | 
			
		||||
        onFilter = onFilter,
 | 
			
		||||
        onClose = onClose,
 | 
			
		||||
        onIMEDone = onIMEDone,
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -68,56 +73,64 @@ private fun FilterPageContent(
 | 
			
		|||
    title: String,
 | 
			
		||||
    search: State<String>,
 | 
			
		||||
    onSearchUpdate: (String) -> Unit,
 | 
			
		||||
    onClear: () -> Unit,
 | 
			
		||||
    filters: LazyPagingItems<FilterItemUio>,
 | 
			
		||||
    onFilter: (FilterItemUio) -> Unit,
 | 
			
		||||
    onClose: () -> Unit,
 | 
			
		||||
    onIMEDone: KeyboardActionScope.() -> Unit,
 | 
			
		||||
) {
 | 
			
		||||
    val navigationBarsHeight = navigationBarsHeight()
 | 
			
		||||
    val imeHeight = imeHeight()
 | 
			
		||||
    val paddingValues = remember(navigationBarsHeight, imeHeight) {
 | 
			
		||||
        PaddingValues(
 | 
			
		||||
            bottom = max(navigationBarsHeight, imeHeight)
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Column(
 | 
			
		||||
        modifier = modifier,
 | 
			
		||||
    ) {
 | 
			
		||||
        TopAppBar(
 | 
			
		||||
            backgroundColor = MaterialTheme.colors.surface,
 | 
			
		||||
            elevation = 0.dp,
 | 
			
		||||
            title = {
 | 
			
		||||
                Text(
 | 
			
		||||
                    style = MaterialTheme.typography.h6,
 | 
			
		||||
                    color = MaterialTheme.colors.onSurface,
 | 
			
		||||
                    text = title,
 | 
			
		||||
                )
 | 
			
		||||
            },
 | 
			
		||||
            navigationIcon = {
 | 
			
		||||
                IconButton(onClick = onClose) {
 | 
			
		||||
                    Icon(
 | 
			
		||||
                        imageVector = Icons.Default.Close,
 | 
			
		||||
                        contentDescription = null,
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        Handle(
 | 
			
		||||
            modifier = Modifier
 | 
			
		||||
                .align(alignment = Alignment.CenterHorizontally)
 | 
			
		||||
                .padding(vertical = 16.dp),
 | 
			
		||||
        )
 | 
			
		||||
        Text(
 | 
			
		||||
            modifier = Modifier.padding(horizontal = 16.dp),
 | 
			
		||||
            style = MaterialTheme.bibLib.typography.base.caption,
 | 
			
		||||
            color = MaterialTheme.bibLib.colors.typography.light,
 | 
			
		||||
            text = title,
 | 
			
		||||
        )
 | 
			
		||||
        TextField(
 | 
			
		||||
            modifier = Modifier
 | 
			
		||||
                .focusRequester(focusRequester = focusRequester)
 | 
			
		||||
                .fillMaxWidth(),
 | 
			
		||||
            label = {
 | 
			
		||||
                Text(
 | 
			
		||||
                    color = MaterialTheme.colors.onSurface,
 | 
			
		||||
                    text = stringResource(id = R.string.search_filter_title)
 | 
			
		||||
                )
 | 
			
		||||
            trailingIcon = {
 | 
			
		||||
                AnimatedVisibility(
 | 
			
		||||
                    visible = search.value.isNotBlank(),
 | 
			
		||||
                    enter = fadeIn(),
 | 
			
		||||
                    exit = fadeOut(),
 | 
			
		||||
                ) {
 | 
			
		||||
                    IconButton(
 | 
			
		||||
                        onClick = onClear,
 | 
			
		||||
                    ) {
 | 
			
		||||
                        Icon(
 | 
			
		||||
                            imageVector = Icons.Default.Clear,
 | 
			
		||||
                            tint = MaterialTheme.bibLib.colors.typography.emphasis,
 | 
			
		||||
                            contentDescription = null,
 | 
			
		||||
                        )
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            value = search.value,
 | 
			
		||||
            singleLine = true,
 | 
			
		||||
            colors = TextFieldDefaults.outlinedTextFieldColors(
 | 
			
		||||
                focusedBorderColor = Color.Transparent,
 | 
			
		||||
                unfocusedBorderColor = Color.Transparent,
 | 
			
		||||
                disabledBorderColor = Color.Transparent,
 | 
			
		||||
            ),
 | 
			
		||||
            colors = TextFieldDefaults.outlinedTextFieldColors(),
 | 
			
		||||
            keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
 | 
			
		||||
            keyboardActions = KeyboardActions(onDone = onIMEDone),
 | 
			
		||||
            onValueChange = onSearchUpdate
 | 
			
		||||
        )
 | 
			
		||||
        LazyColumn(
 | 
			
		||||
            modifier = Modifier.fillMaxSize()
 | 
			
		||||
            modifier = Modifier.fillMaxSize(),
 | 
			
		||||
            contentPadding = paddingValues,
 | 
			
		||||
        ) {
 | 
			
		||||
            items(items = filters, key = { it.filterId }) {
 | 
			
		||||
                Text(
 | 
			
		||||
| 
						 | 
				
			
			@ -132,4 +145,22 @@ private fun FilterPageContent(
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
@Preview(showBackground = true, uiMode = UI_MODE_NIGHT_NO)
 | 
			
		||||
@Preview(showBackground = true, uiMode = UI_MODE_NIGHT_YES)
 | 
			
		||||
private fun FilterPageContentPreview() {
 | 
			
		||||
    BibLibTheme {
 | 
			
		||||
        FilterPageContent(
 | 
			
		||||
            focusRequester = remember { FocusRequester() },
 | 
			
		||||
            title = "Search by Author",
 | 
			
		||||
            search = remember { mutableStateOf("") },
 | 
			
		||||
            onSearchUpdate = { },
 | 
			
		||||
            onClear = { },
 | 
			
		||||
            filters = remember { emptyFlow<PagingData<FilterItemUio>>() }.collectAsLazyPagingItems(),
 | 
			
		||||
            onFilter = { },
 | 
			
		||||
            onIMEDone = { },
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +26,10 @@ class AuthorFilterViewModel @Inject constructor(
 | 
			
		|||
    private val searchRepository: ISearchRepository,
 | 
			
		||||
) : ViewModel(), IFilterViewModel {
 | 
			
		||||
 | 
			
		||||
    override val title: String = application.getString(R.string.search_filter_author)
 | 
			
		||||
    override val title: String = application.getString(
 | 
			
		||||
        R.string.search_filter_title,
 | 
			
		||||
        application.getString(R.string.search_filter_author),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    private var source: AuthorSearchSource? = null
 | 
			
		||||
    override val paging: Flow<PagingData<FilterItemUio>>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,10 @@ class GenreFilterViewModel @Inject constructor(
 | 
			
		|||
    private val searchRepository: ISearchRepository,
 | 
			
		||||
) : ViewModel(), IFilterViewModel {
 | 
			
		||||
 | 
			
		||||
    override val title: String = application.getString(R.string.search_filter_genre)
 | 
			
		||||
    override val title: String = application.getString(
 | 
			
		||||
        R.string.search_filter_title,
 | 
			
		||||
        application.getString(R.string.search_filter_genre),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    private var source: GenreSearchSource? = null
 | 
			
		||||
    override val paging: Flow<PagingData<FilterItemUio>>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,10 @@ class LanguageFilterViewModel @Inject constructor(
 | 
			
		|||
    private val searchRepository: ISearchRepository,
 | 
			
		||||
) : ViewModel(), IFilterViewModel {
 | 
			
		||||
 | 
			
		||||
    override val title: String = application.getString(R.string.search_filter_language)
 | 
			
		||||
    override val title: String = application.getString(
 | 
			
		||||
        R.string.search_filter_title,
 | 
			
		||||
        application.getString(R.string.search_filter_language),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    private var source: LanguageSearchSource? = null
 | 
			
		||||
    override val paging: Flow<PagingData<FilterItemUio>>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,10 @@ class SeriesFilterViewModel @Inject constructor(
 | 
			
		|||
    private val searchRepository: ISearchRepository,
 | 
			
		||||
) : ViewModel(), IFilterViewModel {
 | 
			
		||||
 | 
			
		||||
    override val title: String = application.getString(R.string.search_filter_series)
 | 
			
		||||
    override val title: String = application.getString(
 | 
			
		||||
        R.string.search_filter_title,
 | 
			
		||||
        application.getString(R.string.search_filter_series),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    private var source: SeriesSearchSource? = null
 | 
			
		||||
    override val paging: Flow<PagingData<FilterItemUio>>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,11 +4,13 @@ import androidx.compose.foundation.isSystemInDarkTheme
 | 
			
		|||
import androidx.compose.material.MaterialTheme
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.runtime.CompositionLocalProvider
 | 
			
		||||
import com.pixelized.biblib.ui.composable.SystemTheme
 | 
			
		||||
import com.pixelized.biblib.ui.theme.color.bibLibDarkColors
 | 
			
		||||
import com.pixelized.biblib.ui.theme.color.bibLibLightColors
 | 
			
		||||
import com.pixelized.biblib.ui.theme.dimen.BibLibDimen
 | 
			
		||||
import com.pixelized.biblib.ui.theme.shape.BibLibShape
 | 
			
		||||
import com.pixelized.biblib.ui.theme.typography.BibLibTypography
 | 
			
		||||
import com.pixelized.biblib.utils.extention.bibLib
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
fun BibLibTheme(
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +28,15 @@ fun BibLibTheme(
 | 
			
		|||
            colors = theme.colors.base,
 | 
			
		||||
            typography = theme.typography.base,
 | 
			
		||||
            shapes = theme.shapes.base,
 | 
			
		||||
            content = content
 | 
			
		||||
            content = {
 | 
			
		||||
                SystemTheme(
 | 
			
		||||
                    statusBackground = MaterialTheme.bibLib.colors.system.status,
 | 
			
		||||
                    statusDarkIcons = darkTheme.not(),
 | 
			
		||||
                    navigationBackground = MaterialTheme.bibLib.colors.system.navigation,
 | 
			
		||||
                    navigationDarkIcons = darkTheme.not(),
 | 
			
		||||
                    content = content,
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +1,12 @@
 | 
			
		|||
package com.pixelized.biblib.ui.theme.color
 | 
			
		||||
 | 
			
		||||
import androidx.compose.material.Colors
 | 
			
		||||
import androidx.compose.material.MaterialTheme
 | 
			
		||||
import androidx.compose.material.darkColors
 | 
			
		||||
import androidx.compose.material.lightColors
 | 
			
		||||
import androidx.compose.runtime.Stable
 | 
			
		||||
import androidx.compose.ui.graphics.Color
 | 
			
		||||
import com.pixelized.biblib.utils.extention.bibLib
 | 
			
		||||
import javax.annotation.concurrent.Immutable
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -12,9 +14,18 @@ import javax.annotation.concurrent.Immutable
 | 
			
		|||
@Immutable
 | 
			
		||||
data class BibLibColor(
 | 
			
		||||
    val base: Colors,
 | 
			
		||||
    val system: System,
 | 
			
		||||
    val handle: Color,
 | 
			
		||||
    val typography: Typography,
 | 
			
		||||
    val placeHolder: PlaceHolder,
 | 
			
		||||
) {
 | 
			
		||||
    @Stable
 | 
			
		||||
    @Immutable
 | 
			
		||||
    data class System(
 | 
			
		||||
        val status: Color,
 | 
			
		||||
        val navigation: Color,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    @Stable
 | 
			
		||||
    @Immutable
 | 
			
		||||
    data class Typography(
 | 
			
		||||
| 
						 | 
				
			
			@ -40,6 +51,11 @@ fun bibLibDarkColors(
 | 
			
		|||
        error = BibLibColorPalette.Red,
 | 
			
		||||
        onError = Color.White,
 | 
			
		||||
    ),
 | 
			
		||||
    system: BibLibColor.System = BibLibColor.System(
 | 
			
		||||
        status = base.surface.copy(alpha = 0.5f),
 | 
			
		||||
        navigation = base.surface.copy(alpha = 0.5f),
 | 
			
		||||
    ),
 | 
			
		||||
    handle: Color = base.onSurface.copy(alpha = 0.2f),
 | 
			
		||||
    typography: BibLibColor.Typography = BibLibColor.Typography(
 | 
			
		||||
        light = base.onSurface.copy(alpha = 0.67f),
 | 
			
		||||
        medium = base.onSurface,
 | 
			
		||||
| 
						 | 
				
			
			@ -51,6 +67,8 @@ fun bibLibDarkColors(
 | 
			
		|||
    ),
 | 
			
		||||
) = BibLibColor(
 | 
			
		||||
    base = base,
 | 
			
		||||
    system = system,
 | 
			
		||||
    handle = handle,
 | 
			
		||||
    typography = typography,
 | 
			
		||||
    placeHolder = placeHolder,
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -68,6 +86,11 @@ fun bibLibLightColors(
 | 
			
		|||
        surface = Color.White,
 | 
			
		||||
        onSurface = BibLibColorPalette.VeryDarkGrey,
 | 
			
		||||
    ),
 | 
			
		||||
    system: BibLibColor.System = BibLibColor.System(
 | 
			
		||||
        status = base.surface.copy(alpha = 0.5f),
 | 
			
		||||
        navigation = base.surface.copy(alpha = 0.5f),
 | 
			
		||||
    ),
 | 
			
		||||
    handle: Color = base.onSurface.copy(alpha = 0.1f),
 | 
			
		||||
    typography: BibLibColor.Typography = BibLibColor.Typography(
 | 
			
		||||
        light = base.onSurface.copy(alpha = 0.67f),
 | 
			
		||||
        medium = base.onSurface,
 | 
			
		||||
| 
						 | 
				
			
			@ -79,6 +102,8 @@ fun bibLibLightColors(
 | 
			
		|||
    ),
 | 
			
		||||
) = BibLibColor(
 | 
			
		||||
    base = base,
 | 
			
		||||
    system = system,
 | 
			
		||||
    handle = handle,
 | 
			
		||||
    typography = typography,
 | 
			
		||||
    placeHolder = placeHolder,
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -11,6 +11,7 @@ import androidx.compose.ui.unit.dp
 | 
			
		|||
data class BibLibDimen(
 | 
			
		||||
    val avatar: Avatar = Avatar(),
 | 
			
		||||
    val progress: Progress = Progress(),
 | 
			
		||||
    val handle: Handle = Handle(),
 | 
			
		||||
    val detail: BookDetail = BookDetail(),
 | 
			
		||||
    val thumbnail: BookThumbnail = BookThumbnail(),
 | 
			
		||||
) {
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +27,13 @@ data class BibLibDimen(
 | 
			
		|||
        val iconSize: Dp = 52.dp,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    @Stable
 | 
			
		||||
    @Immutable
 | 
			
		||||
    data class Handle(
 | 
			
		||||
        val width: Dp = 32.dp,
 | 
			
		||||
        val thickness: Dp = 4.dp,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    @Stable
 | 
			
		||||
    @Immutable
 | 
			
		||||
    data class BookDetail(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,4 +17,5 @@ data class BibLibShape(
 | 
			
		|||
    ),
 | 
			
		||||
    val bookThumbnailCoverSmall: Shape = RoundedCornerShape(4.dp),
 | 
			
		||||
    val bookThumbnailCoverLarge: Shape = RoundedCornerShape(4.dp),
 | 
			
		||||
    val filterSheet: Shape = RoundedCornerShape(topEnd = 16.dp, topStart = 16.dp),
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +61,7 @@
 | 
			
		|||
    <string name="detail_send_success">eBook envoyé avec succès</string>
 | 
			
		||||
 | 
			
		||||
    <string name="search_title">Rechercher sur Biblib</string>
 | 
			
		||||
    <string name="search_filter_title">Rechercher</string>
 | 
			
		||||
    <string name="search_filter_title">Rechercher par %1$s</string>
 | 
			
		||||
    <string name="search_filter_param">%1$s : %2$s</string>
 | 
			
		||||
    <string name="search_filter_new">Nouveauté</string>
 | 
			
		||||
    <string name="search_filter_author">Auteur</string>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,7 +77,7 @@
 | 
			
		|||
    <string name="detail_send_success">eBook sent with success</string>
 | 
			
		||||
 | 
			
		||||
    <string name="search_title">Search on Biblib</string>
 | 
			
		||||
    <string name="search_filter_title">Search</string>
 | 
			
		||||
    <string name="search_filter_title">Search by %1$s</string>
 | 
			
		||||
    <string name="search_filter_param">%1$s: %2$s</string>
 | 
			
		||||
    <string name="search_filter_new">New</string>
 | 
			
		||||
    <string name="search_filter_author">Authors</string>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue