Эх сурвалжийг харах

Theme Compose SwipeRefresh indicator like XML version

Also rename some screens/controllers to better represent that they're the list views.
arkon 2 жил өмнө
parent
commit
01e04e31bf

+ 2 - 3
app/src/main/java/eu/kanade/presentation/browse/ExtensionsScreen.kt

@@ -40,6 +40,7 @@ import com.google.accompanist.swiperefresh.SwipeRefresh
 import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
 import eu.kanade.presentation.browse.components.BaseBrowseItem
 import eu.kanade.presentation.browse.components.ExtensionIcon
+import eu.kanade.presentation.components.SwipeRefreshIndicator
 import eu.kanade.presentation.theme.header
 import eu.kanade.presentation.util.horizontalPadding
 import eu.kanade.presentation.util.plus
@@ -73,12 +74,12 @@ fun ExtensionScreen(
     SwipeRefresh(
         modifier = Modifier.nestedScroll(nestedScrollInterop),
         state = rememberSwipeRefreshState(isRefreshing),
+        indicator = { s, trigger -> SwipeRefreshIndicator(s, trigger) },
         onRefresh = onRefresh,
     ) {
         when (state) {
             is ExtensionState.Initialized -> {
                 ExtensionContent(
-                    nestedScrollInterop = nestedScrollInterop,
                     items = (state as ExtensionState.Initialized).list,
                     onLongClickItem = onLongClickItem,
                     onClickItemCancel = onClickItemCancel,
@@ -98,7 +99,6 @@ fun ExtensionScreen(
 
 @Composable
 fun ExtensionContent(
-    nestedScrollInterop: NestedScrollConnection,
     items: List<ExtensionUiModel>,
     onLongClickItem: (Extension) -> Unit,
     onClickItemCancel: (Extension) -> Unit,
@@ -112,7 +112,6 @@ fun ExtensionContent(
 ) {
     val (trustState, setTrustState) = remember { mutableStateOf<Extension.Untrusted?>(null) }
     LazyColumn(
-        modifier = Modifier.nestedScroll(nestedScrollInterop),
         contentPadding = WindowInsets.navigationBars.asPaddingValues() + topPaddingValues,
     ) {
         items(

+ 9 - 9
app/src/main/java/eu/kanade/presentation/browse/SourceFilterScreen.kt → app/src/main/java/eu/kanade/presentation/browse/SourcesFilterScreen.kt

@@ -22,14 +22,14 @@ import eu.kanade.presentation.components.LoadingScreen
 import eu.kanade.presentation.components.PreferenceRow
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.ui.browse.source.FilterUiModel
-import eu.kanade.tachiyomi.ui.browse.source.SourceFilterPresenter
 import eu.kanade.tachiyomi.ui.browse.source.SourceFilterState
+import eu.kanade.tachiyomi.ui.browse.source.SourcesFilterPresenter
 import eu.kanade.tachiyomi.util.system.LocaleHelper
 
 @Composable
-fun SourceFilterScreen(
+fun SourcesFilterScreen(
     nestedScrollInterop: NestedScrollConnection,
-    presenter: SourceFilterPresenter,
+    presenter: SourcesFilterPresenter,
     onClickLang: (String) -> Unit,
     onClickSource: (Source) -> Unit,
 ) {
@@ -39,7 +39,7 @@ fun SourceFilterScreen(
         is SourceFilterState.Loading -> LoadingScreen()
         is SourceFilterState.Error -> Text(text = (state as SourceFilterState.Error).error.message!!)
         is SourceFilterState.Success ->
-            SourceFilterContent(
+            SourcesFilterContent(
                 nestedScrollInterop = nestedScrollInterop,
                 items = (state as SourceFilterState.Success).models,
                 onClickLang = onClickLang,
@@ -49,7 +49,7 @@ fun SourceFilterScreen(
 }
 
 @Composable
-fun SourceFilterContent(
+fun SourcesFilterContent(
     nestedScrollInterop: NestedScrollConnection,
     items: List<FilterUiModel>,
     onClickLang: (String) -> Unit,
@@ -81,14 +81,14 @@ fun SourceFilterContent(
         ) { model ->
             when (model) {
                 is FilterUiModel.Header -> {
-                    SourceFilterHeader(
+                    SourcesFilterHeader(
                         modifier = Modifier.animateItemPlacement(),
                         language = model.language,
                         isEnabled = model.isEnabled,
                         onClickItem = onClickLang,
                     )
                 }
-                is FilterUiModel.Item -> SourceFilterItem(
+                is FilterUiModel.Item -> SourcesFilterItem(
                     modifier = Modifier.animateItemPlacement(),
                     source = model.source,
                     isEnabled = model.isEnabled,
@@ -100,7 +100,7 @@ fun SourceFilterContent(
 }
 
 @Composable
-fun SourceFilterHeader(
+fun SourcesFilterHeader(
     modifier: Modifier,
     language: String,
     isEnabled: Boolean,
@@ -117,7 +117,7 @@ fun SourceFilterHeader(
 }
 
 @Composable
-fun SourceFilterItem(
+fun SourcesFilterItem(
     modifier: Modifier,
     source: Source,
     isEnabled: Boolean,

+ 30 - 2
app/src/main/java/eu/kanade/presentation/browse/components/BrowseIcons.kt

@@ -6,22 +6,26 @@ import androidx.compose.foundation.layout.aspectRatio
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.State
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.produceState
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.ImageBitmap
+import androidx.compose.ui.graphics.asImageBitmap
 import androidx.compose.ui.graphics.painter.ColorPainter
+import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.imageResource
 import androidx.compose.ui.res.painterResource
 import androidx.compose.ui.unit.dp
+import androidx.core.graphics.drawable.toBitmap
 import coil.compose.AsyncImage
 import eu.kanade.domain.source.model.Source
 import eu.kanade.presentation.util.bitmapPainterResource
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.extension.model.Extension
-import eu.kanade.tachiyomi.ui.browse.extension.Result
-import eu.kanade.tachiyomi.ui.browse.extension.getIcon
+import eu.kanade.tachiyomi.util.lang.withIOContext
 
 private val defaultModifier = Modifier
     .height(40.dp)
@@ -89,3 +93,27 @@ fun ExtensionIcon(
         )
     }
 }
+
+@Composable
+private fun Extension.getIcon(): State<Result<ImageBitmap>> {
+    val context = LocalContext.current
+    return produceState<Result<ImageBitmap>>(initialValue = Result.Loading, this) {
+        withIOContext {
+            value = try {
+                Result.Success(
+                    context.packageManager.getApplicationIcon(pkgName)
+                        .toBitmap()
+                        .asImageBitmap(),
+                )
+            } catch (e: Exception) {
+                Result.Error
+            }
+        }
+    }
+}
+
+sealed class Result<out T> {
+    object Loading : Result<Nothing>()
+    object Error : Result<Nothing>()
+    data class Success<out T>(val value: T) : Result<T>()
+}

+ 17 - 0
app/src/main/java/eu/kanade/presentation/components/SwipeRefresh.kt

@@ -0,0 +1,17 @@
+package eu.kanade.presentation.components
+
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.unit.Dp
+import com.google.accompanist.swiperefresh.SwipeRefreshState
+import com.google.accompanist.swiperefresh.SwipeRefreshIndicator as AccompanistSwipeRefreshIndicator
+
+@Composable
+fun SwipeRefreshIndicator(state: SwipeRefreshState, refreshTrigger: Dp) {
+    AccompanistSwipeRefreshIndicator(
+        state = state,
+        refreshTriggerDistance = refreshTrigger,
+        backgroundColor = MaterialTheme.colorScheme.primary,
+        contentColor = MaterialTheme.colorScheme.onPrimary,
+    )
+}

+ 0 - 46
app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionViewUtils.kt

@@ -1,46 +0,0 @@
-package eu.kanade.tachiyomi.ui.browse.extension
-
-import android.content.Context
-import android.content.pm.PackageManager
-import android.graphics.drawable.Drawable
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.State
-import androidx.compose.runtime.produceState
-import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.graphics.asImageBitmap
-import androidx.compose.ui.platform.LocalContext
-import androidx.core.graphics.drawable.toBitmap
-import eu.kanade.tachiyomi.extension.model.Extension
-import eu.kanade.tachiyomi.util.lang.withIOContext
-
-fun Extension.getApplicationIcon(context: Context): Drawable? {
-    return try {
-        context.packageManager.getApplicationIcon(pkgName)
-    } catch (e: PackageManager.NameNotFoundException) {
-        null
-    }
-}
-
-@Composable
-fun Extension.getIcon(): State<Result<ImageBitmap>> {
-    val context = LocalContext.current
-    return produceState<Result<ImageBitmap>>(initialValue = Result.Loading, this) {
-        withIOContext {
-            value = try {
-                Result.Success(
-                    context.packageManager.getApplicationIcon(pkgName)
-                        .toBitmap()
-                        .asImageBitmap(),
-                )
-            } catch (e: Exception) {
-                Result.Error
-            }
-        }
-    }
-}
-
-sealed class Result<out T> {
-    object Loading : Result<Nothing>()
-    object Error : Result<Nothing>()
-    data class Success<out T>(val value: T) : Result<T>()
-}

+ 4 - 4
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceFilterController.kt → app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesFilterController.kt

@@ -3,19 +3,19 @@ package eu.kanade.tachiyomi.ui.browse.source
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
 import eu.kanade.domain.source.model.Source
-import eu.kanade.presentation.browse.SourceFilterScreen
+import eu.kanade.presentation.browse.SourcesFilterScreen
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.ui.base.controller.ComposeController
 
-class SourceFilterController : ComposeController<SourceFilterPresenter>() {
+class SourceFilterController : ComposeController<SourcesFilterPresenter>() {
 
     override fun getTitle() = resources?.getString(R.string.label_sources)
 
-    override fun createPresenter(): SourceFilterPresenter = SourceFilterPresenter()
+    override fun createPresenter(): SourcesFilterPresenter = SourcesFilterPresenter()
 
     @Composable
     override fun ComposeContent(nestedScrollInterop: NestedScrollConnection) {
-        SourceFilterScreen(
+        SourcesFilterScreen(
             nestedScrollInterop = nestedScrollInterop,
             presenter = presenter,
             onClickLang = { language ->

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceFilterPresenter.kt → app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesFilterPresenter.kt

@@ -16,7 +16,7 @@ import kotlinx.coroutines.flow.collectLatest
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
 
-class SourceFilterPresenter(
+class SourcesFilterPresenter(
     private val getLanguagesWithSources: GetLanguagesWithSources = Injekt.get(),
     private val toggleSource: ToggleSource = Injekt.get(),
     private val toggleLanguage: ToggleLanguage = Injekt.get(),