Skip to content

Instantly share code, notes, and snippets.

View Skyyo's full-sized avatar
🇺🇦

Denis Rudenko Skyyo

🇺🇦
View GitHub Profile
@Skyyo
Skyyo / perf_snippet_2.kt
Last active October 4, 2022 07:42
perf_snippet_2
restartable scheme("[androidx.compose.ui.UiComposable]") fun UserDetails(
unstable user: User
)
@Skyyo
Skyyo / peformance_snippet_1.kt
Created October 2, 2022 11:39
performance_snippet_1
data class User(val id: Long, val name: String, var isSelected: Boolean)
@Composable
fun UnstableClassUsageScreen(viewModel: TypicalViewModel = hiltViewModel()) {
val user by viewModel.user.collectAsStateWithLifecycle()
Box {
UserDetails(user)
}
}
@Skyyo
Skyyo / ImageCompressor.kt
Created October 28, 2021 07:11
#compression #image_compression #optimization
object ImageCompressor {
/**
* @param context the application environment
* @param imageUri the input image uri. usually "content://..."
* @param imageFile file where the image was saved. For "photo from camera" scenarios. If it's
* null - we're creating the File inside the createFileAndCompress()
* @param compressFormat the output image file format
* @param maxWidth the output image max width
* @param maxHeight the output image max height
@Skyyo
Skyyo / startup-loop.sh
Created October 20, 2021 19:45
startup time loop #startup #cold_boot
for i in `seq 1 100`
do
adb shell am force-stop com.smth.smth
sleep 1
adb shell am start-activity -W -n com.smth.smth/.application.MainActivity | grep "TotalTime" | cut -d ' ' -f 2
done
LaunchedEffect(isCurrentItemVisible.value) {
if (!isCurrentItemVisible.value && playingItemIndex != null) {
viewModel.onPlayVideoClick(exoPlayer.currentPosition, playingItemIndex!!)
}
}
private fun LazyListState.visibleAreaContainsItem(
currentlyPlayedIndex: Int?,
videos: List<VideoItem>
): Boolean {
return when {
currentlyPlayedIndex == null -> false
videos.isEmpty() -> false
else -> {
layoutInfo.visibleItemsInfo.map { videos[it.index] }.contains(videos[currentlyPlayedIndex])
}
@Composable
fun VideosScreen(viewModel: VideosViewModel = hiltViewModel()) {
val listState = rememberLazyListState()
val playingItemIndex by viewModel.currentlyPlayingIndex.observeAsState()
var isCurrentItemVisible by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
snapshotFlow {
listState.visibleAreaContainsItem(playingItemIndex, videos)
}.collect { isItemVisible ->
DisposableEffect(exoPlayer) {
val lifecycleObserver = LifecycleEventObserver { _, event ->
if (playingItemIndex == null) return@LifecycleEventObserver
when (event) {
Lifecycle.Event.ON_START -> exoPlayer.play()
Lifecycle.Event.ON_STOP -> exoPlayer.pause()
}
}
lifecycleOwner.lifecycle.addObserver(lifecycleObserver)
LaunchedEffect(playingItemIndex) {
if (playingItemIndex == null) {
exoPlayer.pause()
} else {
val video = videos[playingItemIndex]
exoPlayer.setMediaItem(MediaItem.fromUri(video.mediaUrl), video.lastPlayedPosition)
exoPlayer.prepare()
exoPlayer.playWhenReady = true
}
}
@Composable
fun VideoPlayer(
exoPlayer: ExoPlayer,
onControllerVisibilityChanged: (uiVisible: Boolean) -> Unit
) {
val context = LocalContext.current
val playerView = remember {
val layout = LayoutInflater.from(context).inflate(R.layout.video_player, null, false)
val playerView = layout.findViewById(R.id.playerView) as PlayerView
playerView.apply {