diff --git a/app/src/main/kotlin/com/subtracks/ui/library/LibraryScreen.kt b/app/src/main/kotlin/com/subtracks/ui/library/LibraryScreen.kt
index f1cd8648..ba86d3db 100644
--- a/app/src/main/kotlin/com/subtracks/ui/library/LibraryScreen.kt
+++ b/app/src/main/kotlin/com/subtracks/ui/library/LibraryScreen.kt
@@ -17,7 +17,6 @@ import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@@ -46,6 +45,7 @@ import androidx.compose.material.icons.rounded.Search
import androidx.compose.material.icons.rounded.Settings
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.FilterChip
import androidx.compose.material3.FilterChipDefaults
import androidx.compose.material3.FloatingActionButton
@@ -90,7 +90,6 @@ import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.clipPath
import androidx.compose.ui.graphics.drawscope.clipRect
import androidx.compose.ui.graphics.graphicsLayer
-import androidx.compose.ui.graphics.lerp
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.boundsInParent
import androidx.compose.ui.layout.layout
@@ -100,7 +99,6 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
@@ -593,9 +591,6 @@ fun LibraryScreen(
.onSizeChanged { tabBarHeightPx = it.height.toFloat() }
.padding(bottom = bottomInset),
) {
- if (offline) {
- OfflineStrip(onGoOnline = onExitOffline, headerColor = headerColor)
- }
LibraryTabs(
pagerState = pagerState,
onTabSelected = { tab ->
@@ -623,6 +618,20 @@ fun LibraryScreen(
}
if (!searchActive) {
+ if (offline) {
+ FilledTonalIconButton(
+ onClick = onExitOffline,
+ modifier =
+ Modifier
+ .align(Alignment.BottomStart)
+ .padding(start = 16.dp, bottom = tabBarHeight + 16.dp),
+ ) {
+ Icon(
+ imageVector = Icons.Rounded.CloudOff,
+ contentDescription = stringResource(R.string.offline_mode_status),
+ )
+ }
+ }
val searchFab = selectedTab == LibraryTab.Home
FloatingActionButton(
onClick = { if (searchFab) onOpenSearch() else showOptions = true },
@@ -837,7 +846,6 @@ private val TAB_ICON_SIZE = 24.dp
private val TAB_VERTICAL_PADDING = 6.dp
private val TOUCH_TARGET = 48.dp
private const val LIST_OPTIONS_WEIGHT = 0.11f
-private const val OFFLINE_STRIP_TINT = 0.10f
private val LIST_OPTIONS_BAR_WIDTHS = listOf(1f, 0.62f, 0.34f)
@Composable
@@ -1015,44 +1023,6 @@ internal fun LibraryTabs(
}
}
-@Composable
-private fun OfflineStrip(
- onGoOnline: () -> Unit,
- headerColor: Color,
- modifier: Modifier = Modifier,
-) {
- Row(
- modifier =
- modifier
- .fillMaxWidth()
- .background(lerp(headerColor, MaterialTheme.colorScheme.primary, OFFLINE_STRIP_TINT))
- .heightIn(min = 48.dp)
- .clickable(role = Role.Button, onClick = onGoOnline)
- .padding(horizontal = 16.dp, vertical = 8.dp),
- verticalAlignment = Alignment.CenterVertically,
- horizontalArrangement = Arrangement.spacedBy(8.dp),
- ) {
- Icon(
- imageVector = Icons.Rounded.CloudOff,
- contentDescription = null,
- tint = MaterialTheme.colorScheme.primary,
- modifier = Modifier.size(18.dp),
- )
- Text(
- text = stringResource(R.string.offline_mode_banner),
- style = MaterialTheme.typography.bodyMedium,
- color = MaterialTheme.colorScheme.onBackground,
- maxLines = 2,
- modifier = Modifier.weight(1f),
- )
- Text(
- text = stringResource(R.string.offline_go_online),
- style = MaterialTheme.typography.labelLarge,
- color = MaterialTheme.colorScheme.primary,
- )
- }
-}
-
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun TabButton(
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ed5b5a0d..af58820e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -175,8 +175,7 @@
Filters
Downloaded
Close search
- Offline mode
- Go online
+ Offline mode; tap to go online
Shuffle artist
Playing
diff --git a/app/src/test/kotlin/com/subtracks/ui/LibraryScreenTest.kt b/app/src/test/kotlin/com/subtracks/ui/LibraryScreenTest.kt
index 646d748f..a31bef1a 100644
--- a/app/src/test/kotlin/com/subtracks/ui/LibraryScreenTest.kt
+++ b/app/src/test/kotlin/com/subtracks/ui/LibraryScreenTest.kt
@@ -510,7 +510,7 @@ class LibraryScreenTest {
@Test
@Config(qualifiers = "de-rDE-w320dp-h640dp-xhdpi")
- fun theOfflineStripExplainsTheModeAndGoesOnline() {
+ fun theOfflineIndicatorGoesOnline() {
var exited = false
composeRule.setContent {
SubtracksTheme {
@@ -533,11 +533,10 @@ class LibraryScreenTest {
}
composeRule.waitForIdle()
- composeRule.onNodeWithText(composeRule.activity.getString(R.string.offline_mode_banner)).performClick()
- assertTrue("the offline strip should leave offline mode", exited)
composeRule
- .onNodeWithContentDescription(composeRule.activity.getString(R.string.navigation_tabs_settings))
- .assertWidthIsEqualTo(40.dp)
+ .onNodeWithContentDescription(composeRule.activity.getString(R.string.offline_mode_status))
+ .performClick()
+ assertTrue("the offline indicator should leave offline mode", exited)
}
private fun tabBounds(tab: LibraryTab) =