Skip to content

Instantly share code, notes, and snippets.

@Andrew0000
Andrew0000 / DiskDataSource.kt
Created February 26, 2025 17:44
DiskDataSource - utility functions for working with files via Okio
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.withContext
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.encodeToString
import okio.Path
object DiskDataSource {
@Andrew0000
Andrew0000 / ThrottleFirst.kt
Created January 22, 2025 12:56
Flow throttleFirst
fun <T> Flow<T>.throttleFirst(
delayMillis: Long,
dispatcher: CoroutineDispatcher = Dispatchers.IO, // Unbounded dispatcher by default
): Flow<T> {
val delayScope = CoroutineScope(SupervisorJob() + dispatcher)
var isOpen = true
return this
.transform {
if (isOpen) {
@Andrew0000
Andrew0000 / DoOnceSavable.kt
Created December 6, 2024 11:16
doOnceSavable(): Invokes the given block once per Composable across configuration changes.
/**
* Invokes the given [block] once.
* Doesn't invoke again after config changes (screen rotation) on Android.
* Helpful for screen appearance logging.
*/
@Composable
fun doOnceSavable(block: () -> Unit) {
val done = rememberSaveable { mutableStateOf(false) }
LaunchedEffect(Unit) {
if (!done.value) {
@Andrew0000
Andrew0000 / Check gradle parallel test.txt
Created October 15, 2024 12:27
Check gradle parallel test: same process (memory) or different?
tasks.withType<Test>().configureEach {
maxParallelForks = 3
}
// Another File
object TestSharedObject {
@Volatile
@Andrew0000
Andrew0000 / SingleEventStateFlow.kt
Created October 15, 2024 11:46
SingleEventStateFlow. A flow that uses the 'Single Event' pattern without losing events.
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.update
@Andrew0000
Andrew0000 / convert_upload.bat
Created September 13, 2024 20:46
Convert jks to keystore and upload to Google Pay console (pepk.jar)
keytool -importkeystore
-srckeystore path\to\android\file.jks
-destkeystore path\to\keystore\file.keystore
-srcstorepass your_pass
-deststorepass your_pass
java -jar "path\to\Downloads\pepk.jar"
--keystore="path\to\keystore\file.keystore"
--alias=your_alias_here
@Andrew0000
Andrew0000 / Retrying.kt
Last active May 30, 2024 08:52
suspend fun <T> retrying
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.delay
suspend fun <T> retrying(
timesMax: Int = 3,
delayMillis: (Int) -> Long = { (it + 1) * 1000L },
needRetry: (Int, Throwable) -> Boolean = { _, _ -> true },
block: suspend () -> T,
onResult: suspend (T) -> Unit,
@Andrew0000
Andrew0000 / NavigationMediator.kt
Last active December 21, 2023 20:19
NavigationMediator + NavigationUpdater
import androidx.annotation.MainThread
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import timber.log.Timber
@Andrew0000
Andrew0000 / VideoUtils.kt
Last active October 17, 2023 10:20
VideoUtils, Scaling ExoPlayer, AspectRatioScaler
import android.annotation.SuppressLint
import android.view.View
import android.widget.FrameLayout
import androidx.core.view.updateLayoutParams
import com.google.android.exoplayer2.TracksInfo
import com.google.android.exoplayer2.util.MimeTypes
import com.google.android.exoplayer2.video.VideoSize
import timber.log.Timber
@Andrew0000
Andrew0000 / Destination.kt
Last active October 17, 2023 10:22
Destination
import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.os.Parcelable
import androidx.annotation.IdRes
import androidx.fragment.app.Fragment
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
import androidx.navigation.NavOptions