feat: auth screen with auto-redirect, sync favorites/history with backend

This commit is contained in:
nk
2026-06-02 19:12:07 +03:00
parent d4adb1e7be
commit a83672b455
2934 changed files with 97351 additions and 163 deletions

View File

@@ -14,14 +14,21 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import android.util.Log
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import coil.compose.AsyncImage
import com.composables.icons.lucide.Heart
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Pause
import com.composables.icons.lucide.Play
import com.composables.icons.lucide.SkipBack
import com.composables.icons.lucide.SkipForward
import com.composables.icons.lucide.Circle
import com.composables.icons.lucide.Square
import com.radiola.domain.model.DeeplinkService
import com.radiola.domain.model.Station
import com.radiola.deeplink.DeeplinkNavigator
@@ -33,6 +40,12 @@ fun PlayerBottomSheet(
track: Track?,
isPlaying: Boolean,
onPlayPause: () -> Unit,
onNext: () -> Unit,
onPrevious: () -> Unit,
isFavorite: Boolean,
onToggleFavorite: () -> Unit,
isRecording: Boolean,
onToggleRecording: () -> Unit,
modifier: Modifier = Modifier,
viewModel: PlayerViewModel = hiltViewModel()
) {
@@ -50,12 +63,39 @@ fun PlayerBottomSheet(
.padding(24.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
station?.let {
Text(
text = it.name,
style = MaterialTheme.typography.labelMedium,
color = Color(0xFF888888)
)
station?.let { s ->
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Text(
text = s.name,
style = MaterialTheme.typography.labelMedium,
color = Color(0xFF888888)
)
IconButton(
onClick = onToggleFavorite,
modifier = Modifier.size(24.dp)
) {
Icon(
imageVector = Lucide.Heart,
contentDescription = "Избранное",
tint = if (isFavorite) Color(0xFFFF4081) else Color.White,
modifier = Modifier.size(16.dp)
)
}
IconButton(
onClick = onToggleRecording,
modifier = Modifier.size(24.dp)
) {
Icon(
imageVector = if (isRecording) Lucide.Square else Lucide.Circle,
contentDescription = if (isRecording) "Остановить запись" else "Запись",
tint = if (isRecording) Color(0xFFFF5252) else Color(0xFFFF5252),
modifier = Modifier.size(16.dp)
)
}
}
}
Spacer(modifier = Modifier.height(24.dp))
Box(
@@ -96,8 +136,9 @@ fun PlayerBottomSheet(
service = service,
onClick = {
track?.let { t ->
Log.d("PlayerBottomSheet", "DeeplinkButton clicked, track=${t.artist} - ${t.song}")
DeeplinkNavigator.openSearch(context, t, service)
}
} ?: Log.d("PlayerBottomSheet", "DeeplinkButton clicked but track is null")
}
)
}
@@ -107,14 +148,22 @@ fun PlayerBottomSheet(
horizontalArrangement = Arrangement.spacedBy(24.dp),
verticalAlignment = Alignment.CenterVertically
) {
ControlButton(size = 56.dp, onClick = { })
ControlButton(
size = 56.dp,
icon = Lucide.SkipBack,
onClick = onPrevious
)
ControlButton(
size = 72.dp,
isPlay = true,
isPlaying = isPlaying,
onClick = onPlayPause
)
ControlButton(size = 56.dp, onClick = { })
ControlButton(
size = 56.dp,
icon = Lucide.SkipForward,
onClick = onNext
)
}
}
}
@@ -146,6 +195,7 @@ private fun ControlButton(
size: androidx.compose.ui.unit.Dp,
isPlay: Boolean = false,
isPlaying: Boolean = false,
icon: androidx.compose.ui.graphics.vector.ImageVector? = null,
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
@@ -164,6 +214,13 @@ private fun ControlButton(
tint = Color.Black,
modifier = Modifier.size(size * 0.4f)
)
} else if (icon != null) {
Icon(
imageVector = icon,
contentDescription = null,
tint = Color.White,
modifier = Modifier.size(size * 0.4f)
)
}
}
}